Modifications to support banked code. Interrupts and routines accessed through function pointers reside in independent files so they can be assigned to the HOME bank. Init code can be placed in any bank.

Also add adc init code and bank header files.
This commit is contained in:
anthony-a 2010-01-25 23:12:09 +00:00
parent cc3f609eaa
commit 9cfe29612a
15 changed files with 594 additions and 331 deletions

67
cpu/cc2430/dev/adc.c Normal file
View file

@ -0,0 +1,67 @@
/**
* \file
* ADC functions
* \author
* Anthony "Asterisk" Ambuehl
*
* ADC initialization routine, trigger and result conversion routines.
*
*/
#include <stdio.h>
#include "banked.h"
#include "contiki.h"
#include "sys/clock.h"
#include "cc2430_sfr.h"
#include "dev/adc.h"
#include "dev/dma.h"
xDMAHandle adc_dma=0xff;
unsigned int *adc_dma_dest;
/*---------------------------------------------------------------------------*/
void adc_init(void) __banked
{
unsigned char jj;
while (!SLEEP&(HFRC_STB)) {}
/* power both 32MHz crystal and 15MHz RC */
SLEEP &= ~(OSC_PD);
/* printf("SLEEP 1 %x\n",SLEEP); */
/* then wait for it to stabilize */
while (!SLEEP&(XOSC_STB)) {}
/* printf("SLEEP 2 %x\n",SLEEP); */
/* then wait 64uS more */
clock_delay(150);
/* switch to 32MHz clock */
/* printf("switch to 32MHz %x\n",CLKCON); */
CLKCON &= ~(OSC);
/* printf("switched to 32MHz %x\n",CLKCON); */
/* power down 15MHz RC clock */
SLEEP |= OSC_PD;
/* printf("pwr down hfrc\n",SLEEP); */
/* preconfigure adc_dma before calling adc_init if a different dma type is desired. */
if (adc_dma==0xff) {
dma_init();
/* config DMA channel to copy results to single location */
adc_dma=dma_config2(ADC_DMA_CONFIG_CHANNEL, &ADC_SHADOW, DMA_NOINC, adc_dma_dest, DMA_NOINC, 1, 1, DMA_VLEN_LEN, DMA_RPT, DMA_T_ADC_CHALL, 0);
}
}
/* single sample trigger */
void adc_single_shot(void) __banked
{
ADCCON1 |= 0x73;
}
/* convert adc results */
int16_t adc_convert_result(int16_t data) __banked {
data = (0xfffc&data)>>2;
return data;
}
/* read/convert last conversion result */
int16_t adc_get_last_conv() __banked {
int16_t result;
result = (ADCH<<8)|(ADCL);
result = (0xfffc&result)>>2;
return result;
}

40
cpu/cc2430/dev/banked.h Normal file
View file

@ -0,0 +1,40 @@
/**
* \file
*
* SDCC bank switching macro define file
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* SDCC (small device cross compiler) has built-in support for bank switching using predefined macros __banked.
* To avoid compilation issues on other compilers include this file which will replace __banked with the empty string on unsupported compilers.
*
* In addition, the file can add the codeseg pragma to place code into specific banks, if specific macro is set.
* However the same result can be achieved by using the segment.rules file.
*
*/
#ifndef __BANKED_H
#ifdef SDCC
#ifndef HAVE_SDCC_BANKING
#define __banked
#else
#ifdef BANKED_IN_HOME
#pragma codeseg HOME
#endif
#ifdef BANKED_IN_BANK1
#pragma codeseg BANK1
#endif
#ifdef BANKED_IN_BANK2
#pragma codeseg BANK2
#endif
#ifdef BANKED_IN_BANK3
#pragma codeseg BANK3
#endif
#endif
#else
#define __banked
#endif
#endif /*__BANKED_H*/

View file

@ -28,7 +28,7 @@
*
* This file is part of the Contiki operating system.
*
* $Id: bus.c,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
* $Id: bus.c,v 1.2 2010/01/25 23:12:09 anthony-a Exp $
*/
/**
@ -38,13 +38,14 @@
* Adam Dunkels <adam@sics.se>
*/
#include "banked.h"
#include "cc2430_sfr.h"
#include "dev/bus.h"
#include "sys/clock.h"
/*---------------------------------------------------------------------------*/
void
bus_init(void)
bus_init (void) __banked
{
CLKCON = (0x00 | OSC32K); /* 32k internal */
while(CLKCON != (0x00 | OSC32K));
@ -65,7 +66,7 @@ bus_init(void)
* \param size number of bytes to read
*/
void
flash_read(uint8_t *buf, uint32_t address, uint8_t size)
flash_read (uint8_t *buf, uint32_t address, uint8_t size) __banked
{
buf; /*dptr0*/
address; /*stack-6*/

View file

@ -28,7 +28,7 @@
*
* This file is part of the Contiki operating system.
*
* $Id: bus.h,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
* $Id: bus.h,v 1.2 2010/01/25 23:12:09 anthony-a Exp $
*/
/**
@ -46,9 +46,17 @@
#include "8051def.h"
#define inline
#ifdef SDCC
#ifdef HAVE_SDCC_BANKING
#else
#define __banked
#endif
#else
#define __banked
#endif
void bus_init(void);
void flash_read(uint8_t *buf, uint32_t address, uint8_t size);
void bus_init(void) __banked;
void flash_read(uint8_t *buf, uint32_t address, uint8_t size) __banked;
void cc2430_clock_ISR( void ) __interrupt (ST_VECTOR);
#endif /* __BUS_H__ */

View file

@ -3,6 +3,9 @@
* CC2430 RF driver
* \author
* Zach Shelby <zach@sensinode.com>
*
* bankable code for cc2430 rf driver. this code can be placed in any bank.
*
*/
#include <stdio.h>
@ -17,15 +20,7 @@
#include "net/rime/packetbuf.h"
#include "net/rime/rimestats.h"
static void (* receiver_callback)(const struct radio_driver *);
void cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *));
int cc2430_rf_on(void);
int cc2430_rf_off(void);
int cc2430_rf_read(void *buf, unsigned short bufsize);
int cc2430_rf_send(const void *data, unsigned short len);
void cc2430_rf_init(void);
void (* receiver_callback)(const struct radio_driver *);
#ifndef RF_DEFAULT_POWER
#define RF_DEFAULT_POWER 100
@ -110,7 +105,7 @@ PROCESS_THREAD(cc2430_rf_process, ev, data)
}
/*---------------------------------------------------------------------------*/
void
cc2430_rf_init(void)
cc2430_rf_init(void) __banked
{
if(rf_initialized) {
return;
@ -142,7 +137,6 @@ cc2430_rf_init(void)
rf_manfid = CHVER;
rf_manfid <<= 8;
rf_manfid += CHIPID;
cc2430_rf_channel_set(RF_DEFAULT_CHANNEL);
cc2430_rf_command(ISFLUSHTX);
cc2430_rf_command(ISFLUSHRX);
@ -159,18 +153,11 @@ cc2430_rf_init(void)
RF_TX_LED_OFF();
RF_RX_LED_OFF();
rf_initialized = 1;
process_start(&cc2430_rf_process, NULL);
}
/*---------------------------------------------------------------------------*/
void
cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *))
{
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_send(const void *payload, unsigned short payload_len)
cc2430_rf_send_b(void *payload, unsigned short payload_len) __banked
{
uint8_t i, counter;
@ -180,12 +167,11 @@ cc2430_rf_send(const void *payload, unsigned short payload_len)
if((rf_flags & RX_ACTIVE) == 0) {
cc2430_rf_rx_enable();
}
/* Check packet attributes */
/*printf("packetbuf_attr: txpower = %d\n", packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER));*/
/* Should set TX power according to this if > 0 */
PRINTF("cc2430_rf: sending %d byte payload\n", payload_len);
PRINTF("cc2430_rf: sending %ud byte payload\n", payload_len);
RIMESTATS_ADD(lltx);
@ -230,7 +216,7 @@ cc2430_rf_send(const void *payload, unsigned short payload_len)
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_read(void *buf, unsigned short bufsize)
cc2430_rf_read_banked(void *buf, unsigned short bufsize) __banked
{
uint8_t i, len;
#if CC2420_CONF_CHECKSUM
@ -294,27 +280,13 @@ cc2430_rf_read(void *buf, unsigned short bufsize)
return (len - CHECKSUM_LEN);
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_off(void)
{
return cc2430_rf_rx_disable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_on(void)
{
return cc2430_rf_rx_enable();
}
/*---------------------------------------------------------------------------*/
/**
* Execute a single CSP command.
*
* \param command command to execute
*
*/
void cc2430_rf_command(uint8_t command)
void cc2430_rf_command(uint8_t command) __banked
{
if(command >= 0xE0) { /*immediate strobe*/
uint8_t fifo_count;
@ -344,6 +316,8 @@ void cc2430_rf_command(uint8_t command)
}
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/**
* Select RF channel.
*
@ -428,7 +402,7 @@ cc2430_rf_power_set(uint8_t new_power)
* \return pdFALSE bus not free
*/
int8_t
cc2430_rf_rx_enable(void)
cc2430_rf_rx_enable(void) __banked
{
PRINTF("cc2430_rf_rx_enable called\n");
if(!(rf_flags & RX_ACTIVE)) {
@ -444,6 +418,7 @@ cc2430_rf_rx_enable(void)
cc2430_rf_command(ISRXON);
cc2430_rf_command(ISFLUSHRX);
}
PRINTF("cc2430_rf_rx_enable done\n");
return 1;
}
/*---------------------------------------------------------------------------*/
@ -454,7 +429,7 @@ cc2430_rf_rx_enable(void)
* \return pdTRUE
* \return pdFALSE bus not free
*/
int8_t cc2430_rf_rx_disable(void)
int8_t cc2430_rf_rx_disable(void) __banked
{
cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/
cc2430_rf_command(ISRFOFF);
@ -625,7 +600,7 @@ cc2430_rf_cca_check(uint8_t backoff_count, uint8_t slotted)
*\param pending set up pending flag if pending > 0.
*/
void
cc2430_rf_send_ack(uint8_t pending)
cc2430_rf_send_ack(uint8_t pending) __banked
{
if(pending) {
cc2430_rf_command(ISACKPEND);
@ -634,52 +609,3 @@ cc2430_rf_send_ack(uint8_t pending)
}
}
/*---------------------------------------------------------------------------*/
/**
* RF interrupt service routine.
*
*/
void
cc2430_rf_ISR( void ) __interrupt (RF_VECTOR)
{
EA = 0;
if(RFIF & IRQ_TXDONE) {
RF_TX_LED_OFF();
RFIF &= ~IRQ_TXDONE;
cc2430_rf_command(ISFLUSHTX);
}
if(RFIF & IRQ_FIFOP) {
if(RFSTATUS & FIFO) {
RF_RX_LED_ON();
/* Poll the RF process which calls cc2430_rf_read() */
process_poll(&cc2430_rf_process);
} else {
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
RFIF &= ~IRQ_FIFOP;
}
}
S1CON &= ~(RFIF_0 | RFIF_1);
EA = 1;
}
/*---------------------------------------------------------------------------*/
/**
* RF error interrupt service routine.
*
*/
void
cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR)
{
EA = 0;
TCON_RFERRIF = 0;
#ifdef HAVE_RF_ERROR
rf_error = 254;
#endif
cc2430_rf_command(ISRFOFF);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISRXON);
RF_RX_LED_OFF();
RF_TX_LED_OFF();
EA = 1;
}
/*---------------------------------------------------------------------------*/

View file

@ -8,6 +8,7 @@
#ifndef __CC2430_RF_H__
#define __CC2430_RF_H__
#include "banked.h"
#include "contiki.h"
#include "dev/radio.h"
#include "cc2430_sfr.h"
@ -66,15 +67,19 @@ void cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *));
int cc2430_rf_on(void);
int cc2430_rf_off(void);
int cc2430_rf_read(void *buf, unsigned short bufsize);
int cc2430_rf_send(const void *data, unsigned short len);
int cc2430_rf_read_banked (void *buf, unsigned short bufsize) __banked;
int cc2430_rf_send(void *data, unsigned short len);
int cc2430_rf_send_b (void *data, unsigned short len) __banked;
extern unsigned short cc2430_rf_payload_len;
extern void *cc2430_rf_payload;
/* RF driver functions */
void cc2430_rf_init(void);
void cc2430_rf_command(uint8_t command);
void cc2430_rf_init(void) __banked;
void cc2430_rf_command(uint8_t command) __banked;
int8_t cc2430_rf_channel_set(uint8_t channel);
int8_t cc2430_rf_power_set(uint8_t new_power);
int8_t cc2430_rf_rx_enable(void);
int8_t cc2430_rf_rx_disable(void);
int8_t cc2430_rf_rx_enable(void) __banked;
int8_t cc2430_rf_rx_disable(void) __banked;
int8_t cc2430_rf_tx_enable(void);
int8_t cc2430_rf_address_decoder_mode(rf_address_mode_t mode);
int8_t cc2430_rf_analyze_rssi(void);

View file

@ -0,0 +1,130 @@
/**
* \file
* CC2430 RF driver
* \author
* Zach Shelby <zach@sensinode.com>
*
* Non-bankable code for cc2430 rf driver.
* Interrupt routine and code called through function pointers
* must be placed into the HOME bank.
*
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/radio.h"
#include "dev/cc2430_rf.h"
#include "cc2430_sfr.h"
#ifdef RF_LED_ENABLE
#include "dev/leds.h"
#endif
#include "sys/clock.h"
#include "net/rime/packetbuf.h"
#include "net/rime/rimestats.h"
#ifdef RF_LED_ENABLE
#define RF_RX_LED_ON() leds_on(LEDS_RED);
#define RF_RX_LED_OFF() leds_off(LEDS_RED);
#define RF_TX_LED_ON() leds_on(LEDS_GREEN);
#define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
#else
#define RF_RX_LED_ON()
#define RF_RX_LED_OFF()
#define RF_TX_LED_ON()
#define RF_TX_LED_OFF()
#endif
#ifdef HAVE_RF_ERROR
uint8_t rf_error = 0;
#endif
/*---------------------------------------------------------------------------*/
PROCESS_NAME(cc2430_rf_process);
/*---------------------------------------------------------------------------*/
/**
* RF interrupt service routine.
*
*/
void
cc2430_rf_ISR( void ) __interrupt (RF_VECTOR)
{
EA = 0;
if(RFIF & IRQ_TXDONE) {
RF_TX_LED_OFF();
RFIF &= ~IRQ_TXDONE;
cc2430_rf_command(ISFLUSHTX);
}
if(RFIF & IRQ_FIFOP) {
if(RFSTATUS & FIFO) {
RF_RX_LED_ON();
/* Poll the RF process which calls cc2430_rf_read() */
process_poll(&cc2430_rf_process);
} else {
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
RFIF &= ~IRQ_FIFOP;
}
}
S1CON &= ~(RFIF_0 | RFIF_1);
EA = 1;
}
/*---------------------------------------------------------------------------*/
/**
* RF error interrupt service routine.
*
*/
void
cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR)
{
EA = 0;
TCON_RFERRIF = 0;
#ifdef HAVE_RF_ERROR
rf_error = 254;
#endif
cc2430_rf_command(ISRFOFF);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISRXON);
RF_RX_LED_OFF();
RF_TX_LED_OFF();
EA = 1;
}
extern void (* receiver_callback)(const struct radio_driver *);
void
cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *))
{
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/
/*
* non-banked functions called through function pointers then call banked code
*/
int
cc2430_rf_off(void)
{
return cc2430_rf_rx_disable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_on(void)
{
return cc2430_rf_rx_enable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_send(void *payload, unsigned short payload_len)
{
return cc2430_rf_send_b(payload, payload_len);
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_read(void *buf, unsigned short bufsize) __banked
{
return cc2430_rf_read_banked(buf, bufsize);
}
/*---------------------------------------------------------------------------*/

View file

@ -4,11 +4,14 @@
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*
* bankable DMA functions
*/
#include <stdio.h>
#include "contiki.h"
#include "banked.h"
#include "dev/dma.h"
#include "cc2430_sfr.h"
@ -18,10 +21,9 @@ struct process * dma_callback[4];
/*---------------------------------------------------------------------------*/
void
dma_init(void)
dma_init(void) __banked
{
uint16_t tmp_ptr;
memset(dma_conf, 0, 4*sizeof(dma_config_t));
for(tmp_ptr = 0; tmp_ptr < 4; tmp_ptr++) {
dma_callback[tmp_ptr] = 0;
@ -51,14 +53,15 @@ dma_init(void)
* \return Handle to DMA channel
* \return 0 invalid channel
*/
/* IMPLEMENTED dma_config as macro to reduce stack/code space
xDMAHandle
dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, dma_vlen_t vlen_mode, dma_type_t t_mode, dma_trigger_t trigger,
struct process * proc)
struct process * proc) __banked
{
return dma_config2(channel,src,src_inc, dst, dst_inc, length, 0, vlen_mode, t_mode, trigger, proc);
}
*/
/*---------------------------------------------------------------------------*/
/**
* Configure a DMA channel.
@ -81,8 +84,9 @@ dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t d
xDMAHandle
dma_config2(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, uint8_t word_mode, dma_vlen_t vlen_mode, dma_type_t t_mode, dma_trigger_t trigger,
struct process * proc)
struct process * proc) __banked
{
unsigned char jj;
if((!channel) || (channel > 4)) {
return 0;
}
@ -119,7 +123,7 @@ dma_config2(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_arm(xDMAHandle channel)
dma_arm(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t)channel);
if(!ch_id || (ch_id > 4)) {
@ -138,7 +142,7 @@ dma_arm(xDMAHandle channel)
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_abort(xDMAHandle channel)
dma_abort(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t) channel);
if(!ch_id || (ch_id > 4)) {
@ -157,7 +161,7 @@ dma_abort(xDMAHandle channel)
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_trigger(xDMAHandle channel)
dma_trigger(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t) channel);
if(!ch_id || (ch_id > 4)) {
@ -176,7 +180,7 @@ dma_trigger(xDMAHandle channel)
* \return pdFALSE not active
*/
uint8_t
dma_state(xDMAHandle channel)
dma_state(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t)channel);
if(!ch_id || (ch_id > 4)) {
@ -189,7 +193,7 @@ dma_state(xDMAHandle channel)
}
/*---------------------------------------------------------------------------*/
void
dma_config_print(xDMAHandle channel)
dma_config_print(xDMAHandle channel) __banked
{
uint8_t ch_id = channel - 1;
@ -210,50 +214,3 @@ dma_config_print(xDMAHandle channel)
}
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef HAVE_RF_DMA
extern void rf_dma_callback_isr(void);
#endif
#ifdef SPI_DMA_RX
extern void spi_rx_dma_callback(void);
#endif
/*---------------------------------------------------------------------------*/
/**
* DMA interrupt service routine.
*
* if callback defined a poll is made to that process
*/
void
dma_ISR(void) __interrupt (DMA_VECTOR)
{
#ifdef HAVE_DMA
uint8_t i;
#endif
EA=0;
#ifdef HAVE_RF_DMA
if((DMAIRQ & 1) != 0) {
DMAIRQ &= ~1;
DMAARM=0x81;
rf_dma_callback_isr();
}
#endif
#ifdef SPI_DMA_RX
if((DMAIRQ & 0x08) != 0) {
DMAIRQ &= ~(1 << 3);
spi_rx_dma_callback();
}
#endif
#ifdef HAVE_DMA
for(i = 0; i < 4; i++) {
if((DMAIRQ & (1 << i + 1)) != 0) {
DMAIRQ &= ~(1 << i+1);
if(dma_callback[i] != 0) {
process_poll(dma_callback[i]);
}
}
}
#endif
IRCON_DMAIF = 0;
EA = 1;
}
/*---------------------------------------------------------------------------*/

View file

@ -8,7 +8,7 @@
#ifndef __DMA_H
#define __DMA_H
#include "banked.h"
#include "cc2430_sfr.h"
/** DMA triggers */
@ -93,7 +93,7 @@ typedef struct dma_config_t
}dma_config_t;
extern void dma_init(void);
extern void dma_init(void) __banked;
typedef void (*dma_func)(void *);
extern dma_config_t dma_conf[4];
@ -101,14 +101,20 @@ extern dma_config_t dma_conf[4];
#ifdef HAVE_DMA
typedef uint8_t xDMAHandle;
extern xDMAHandle dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
#define dma_config(channel, src, src_inc, dst, dst_inc, length, vlen_mode, t_mode, trigger, proc) dma_config2(channel,src,src_inc, dst, dst_inc, length, 0, vlen_mode, t_mode, trigger, proc)
/*
extern xDMAHandle dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, dma_vlen_t vlen_mode, dma_type_t t_mode,
dma_trigger_t trigger, struct process * p);
extern uint8_t dma_arm(xDMAHandle channel);
extern uint8_t dma_abort(xDMAHandle channel);
extern uint8_t dma_trigger(xDMAHandle channel);
extern uint8_t dma_state(xDMAHandle channel);
void dma_config_print(xDMAHandle channel);
*/
extern xDMAHandle dma_config2(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, uint8_t word_mode, dma_vlen_t vlen_mode, dma_type_t t_mode,
dma_trigger_t trigger, struct process * p) __banked;
extern uint8_t dma_arm(xDMAHandle channel) __banked;
extern uint8_t dma_abort(xDMAHandle channel) __banked;
extern uint8_t dma_trigger(xDMAHandle channel) __banked;
extern uint8_t dma_state(xDMAHandle channel) __banked;
void dma_config_print(xDMAHandle channel) __banked;
#endif
extern void dma_ISR( void ) __interrupt (DMA_VECTOR);

67
cpu/cc2430/dev/dma_intr.c Normal file
View file

@ -0,0 +1,67 @@
/**
* \file
* DMA driver ISRs
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*
* DMA interrupt routines, must be stored in HOME bank
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/dma.h"
#include "cc2430_sfr.h"
#include "banked.h"
extern struct process * dma_callback[4];
/*---------------------------------------------------------------------------*/
#ifdef HAVE_RF_DMA
extern void rf_dma_callback_isr(void);
#endif
#ifdef SPI_DMA_RX
extern void spi_rx_dma_callback(void);
#endif
/*---------------------------------------------------------------------------*/
/**
* DMA interrupt service routine.
*
* if callback defined a poll is made to that process
*/
void
dma_ISR(void) __interrupt (DMA_VECTOR)
{
#ifdef HAVE_DMA
uint8_t i;
#endif
EA=0;
#ifdef HAVE_RF_DMA
if((DMAIRQ & 1) != 0) {
DMAIRQ &= ~1;
DMAARM=0x81;
rf_dma_callback_isr();
}
#endif
#ifdef SPI_DMA_RX
if((DMAIRQ & 0x08) != 0) {
DMAIRQ &= ~(1 << 3);
spi_rx_dma_callback();
}
#endif
#ifdef HAVE_DMA
for(i = 0; i < 4; i++) {
if((DMAIRQ & (1 << i + 1)) != 0) {
DMAIRQ &= ~(1 << i+1);
if(dma_callback[i] != 0) {
process_poll(dma_callback[i]);
}
}
}
#endif
IRCON_DMAIF = 0;
EA = 1;
}
/*---------------------------------------------------------------------------*/

View file

@ -28,7 +28,7 @@
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: hwconf.h,v 1.1 2009/12/22 09:28:15 zdshelby Exp $
* @(#)$Id: hwconf.h,v 1.2 2010/01/25 23:12:09 anthony-a Exp $
*/
#ifndef __HWCONF_H__
#define __HWCONF_H__
@ -40,14 +40,14 @@ extern uint8_t p0ien;
extern uint8_t p2ien;
#define HWCONF_PIN(name, port, bit) \
static CC_INLINE void name##_SELECT() { P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_IO() { P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_PM() { P##port##SEL |= 1 << bit;} \
static CC_INLINE void name##_SET() { P##port##_##bit = 1; } \
static CC_INLINE void name##_CLEAR() { P##port##_##bit = 0; } \
static CC_INLINE unsigned char name##_READ() { return P##port##_##bit; } \
static CC_INLINE void name##_MAKE_OUTPUT() { P##port##DIR |= 1 << bit;} \
static CC_INLINE void name##_MAKE_INPUT() { P##port##DIR &= ~(1 << bit); }
static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_IO() {P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_PM() {P##port##SEL |= 1 << bit;} \
static CC_INLINE void name##_SET() {P##port##_##bit = 1; } \
static CC_INLINE void name##_CLEAR() {P##port##_##bit = 0; } \
static CC_INLINE unsigned char name##_READ() {return P##port##_##bit; } \
static CC_INLINE void name##_MAKE_OUTPUT() {P##port##DIR |= 1 << bit;} \
static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit); }
#define HWCONF_IRQ_XXX(name, port, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \

View file

@ -1,3 +1,15 @@
/**
* \file
*
* uart write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* non-interrupt routines which may be called from ISR's and therefore should be in HOME bank.
*
*/
#include <stdlib.h>
#include <string.h>
@ -6,64 +18,6 @@
#include "dev/leds.h"
#include "dev/uart.h"
static int (*uart0_input_handler)(unsigned char c);
static int (*uart1_input_handler)(unsigned char c);
/*---------------------------------------------------------------------------*/
void
uart0_init(uint32_t speed)
{
if(speed == 115200) {
U0BAUD=216; /*115200*/
U0GCR =11; /*LSB first and 115200*/
}
else if(speed == 38400) {
U0BAUD=59; /*38400*/
U0GCR =10; /*LSB first and 38400*/
}
else if(speed == 9600) {
U0BAUD= 59; /* 9600 */
U0GCR = 8; /*LSB first and 9600*/
}
else { return; }
#ifdef UART0_ALTERNATIVE_2
PERCFG |= U0CFG; /*alternative port 2 = P1.5-2*/
#ifdef UART0_RTSCTS
P1SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P1SEL |= 0x30; /*peripheral select for TX and RX*/
P1 &= ~0x08; /*RTS down*/
#endif
P1DIR |= 0x28; /*RTS, TX out*/
P1DIR &= ~0x14; /*CTS & RX in*/
#else
PERCFG &= ~U0CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART0_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x0C; /*peripheral select for TX and RX*/
P0 &= ~0x20; /*RTS down*/
#endif
P0DIR |= 0x28; /*RTS & TX out*/
P0DIR &= ~0x14; /*CTS & RX in*/
#endif
#ifdef UART0_RTSCTS
U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U0CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX0IE = 1;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
@ -75,82 +29,6 @@ uart0_writeb(uint8_t byte)
IRCON2_UTX0IF = 0;
}
/*---------------------------------------------------------------------------*/
void
uart0_set_input(int (*input)(unsigned char c))
{
uart0_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart0_rxISR(void) __interrupt (URX0_VECTOR)
{
TCON_URX0IF = 0;
if(uart0_input_handler != NULL) {
uart0_input_handler(U0BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart0_txISR( void ) __interrupt (UTX0_VECTOR)
{
}
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init(uint32_t speed)
{
#ifdef UART1_ALTERNATIVE_1
PERCFG &= ~U1CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART1_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x30; /*peripheral select for TX and RX*/
P0 &= ~0x08; /*RTS down*/
#endif
P0DIR |= 0x18; /*RTS, TX out*/
P0DIR &= ~0x24; /*CTS, RX in*/
#else
PERCFG |= U1CFG; /*alternative port 2 = P1.7-4*/
#ifdef UART1_RTSCTS
P1SEL |= 0xF0; /*peripheral select for TX and RX*/
#else
P1SEL |= 0xC0; /*peripheral select for TX and RX*/
P1 &= ~0x20; /*RTS down*/
#endif
P1DIR |= 0x60; /*RTS, TX out*/
P1DIR &= ~0x90; /*CTS, RX in*/
#endif
if(speed == 115200) {
U1BAUD=216; /*115200*/
U1GCR =11; /*LSB first and 115200*/
}
if(speed == 38400) {
U1BAUD=59; /*38400*/
U1GCR =10; /*LSB first and 38400*/
}
if(speed == 9600) {
U1BAUD= 59; /* 9600 */
U1GCR = 8; /*LSB first and 9600*/
}
#ifdef UART1_RTSCTS
U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U1CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX1IE = 1; /* Enable the RX interrupt */
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart1_writeb(uint8_t byte)
@ -161,23 +39,3 @@ uart1_writeb(uint8_t byte)
IRCON2_UTX1IF = 0;
}
/*---------------------------------------------------------------------------*/
void
uart1_set_input(int (*input)(unsigned char c))
{
uart1_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart1_rxISR(void) __interrupt (URX1_VECTOR)
{
TCON_URX1IF = 0;
if(uart1_input_handler != NULL) {
uart1_input_handler(U1BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart1_txISR( void ) __interrupt (UTX1_VECTOR)
{
}
/*---------------------------------------------------------------------------*/

View file

@ -2,10 +2,11 @@
#define UART_H
#include "contiki-conf.h"
#include "banked.h"
#include "cc2430_sfr.h"
void uart0_init(uint32_t speed);
void uart0_init(uint32_t speed) __banked;
void uart0_writeb(uint8_t byte);
void uart0_set_input(int (*input)(unsigned char c));
@ -13,7 +14,7 @@ void uart0_set_input(int (*input)(unsigned char c));
void uart0_rxISR( void ) __interrupt (URX0_VECTOR);
void uart0_txISR( void ) __interrupt (UTX0_VECTOR);
void uart1_init(uint32_t speed);
void uart1_init(uint32_t speed) __banked;
void uart1_writeb(uint8_t byte);
void uart1_set_input(int (*input)(unsigned char c));

133
cpu/cc2430/dev/uart_init.c Normal file
View file

@ -0,0 +1,133 @@
/**
* \file
*
* uart initialization routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* non-interrupt routines typically only called once, stored in any bank.
*
*/
#include <stdlib.h>
#include <string.h>
#include "banked.h"
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart.h"
/*---------------------------------------------------------------------------*/
void
uart0_init(uint32_t speed) __banked
{
if(speed == 115200) {
U0BAUD=216; /*115200*/
U0GCR =11; /*LSB first and 115200*/
}
else if(speed == 38400) {
U0BAUD=59; /*38400*/
U0GCR =10; /*LSB first and 38400*/
}
else if(speed == 9600) {
U0BAUD= 59; /* 9600 */
U0GCR = 8; /*LSB first and 9600*/
}
else { return; }
#ifdef UART0_ALTERNATIVE_2
PERCFG |= U0CFG; /*alternative port 2 = P1.5-2*/
#ifdef UART0_RTSCTS
P1SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P1SEL |= 0x30; /*peripheral select for TX and RX*/
P1 &= ~0x08; /*RTS down*/
#endif
P1DIR |= 0x28; /*RTS, TX out*/
P1DIR &= ~0x14; /*CTS & RX in*/
#else
PERCFG &= ~U0CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART0_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x0C; /*peripheral select for TX and RX*/
P0 &= ~0x20; /*RTS down*/
#endif
P0DIR |= 0x28; /*RTS & TX out*/
P0DIR &= ~0x14; /*CTS & RX in*/
#endif
#ifdef UART0_RTSCTS
U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U0CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX0IE = 1;
}
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init(uint32_t speed) __banked
{
#ifdef UART1_ALTERNATIVE_1
PERCFG &= ~U1CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART1_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x30; /*peripheral select for TX and RX*/
P0 &= ~0x08; /*RTS down*/
#endif
P0DIR |= 0x18; /*RTS, TX out*/
P0DIR &= ~0x24; /*CTS, RX in*/
#else
PERCFG |= U1CFG; /*alternative port 2 = P1.7-4*/
#ifdef UART1_RTSCTS
P1SEL |= 0xF0; /*peripheral select for TX and RX*/
#else
P1SEL |= 0xC0; /*peripheral select for TX and RX*/
P1 &= ~0x20; /*RTS down*/
#endif
P1DIR |= 0x60; /*RTS, TX out*/
P1DIR &= ~0x90; /*CTS, RX in*/
#endif
if(speed == 115200) {
U1BAUD=216; /*115200*/
U1GCR =11; /*LSB first and 115200*/
}
if(speed == 38400) {
U1BAUD=59; /*38400*/
U1GCR =10; /*LSB first and 38400*/
}
if(speed == 9600) {
U1BAUD= 59; /* 9600 */
U1GCR = 8; /*LSB first and 9600*/
}
#ifdef UART1_RTSCTS
U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U1CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX1IE = 1; /* Enable the RX interrupt */
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,64 @@
/**
* \file
*
* uart write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* interrupt routines which must be in HOME bank. handles received data from UART.
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart.h"
static int (*uart0_input_handler)(unsigned char c);
static int (*uart1_input_handler)(unsigned char c);
/*---------------------------------------------------------------------------*/
void
uart0_set_input(int (*input)(unsigned char c))
{
uart0_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart0_rxISR(void) __interrupt (URX0_VECTOR)
{
TCON_URX0IF = 0;
if(uart0_input_handler != NULL) {
uart0_input_handler(U0BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart0_txISR( void ) __interrupt (UTX0_VECTOR)
{
}
/*---------------------------------------------------------------------------*/
void
uart1_set_input(int (*input)(unsigned char c))
{
uart1_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart1_rxISR(void) __interrupt (URX1_VECTOR)
{
TCON_URX1IF = 0;
if(uart1_input_handler != NULL) {
uart1_input_handler(U1BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart1_txISR( void ) __interrupt (UTX1_VECTOR)
{
}
/*---------------------------------------------------------------------------*/