From 9cfe29612af32b7a0db0290ddb25604e256c1800 Mon Sep 17 00:00:00 2001 From: anthony-a Date: Mon, 25 Jan 2010 23:12:09 +0000 Subject: [PATCH] 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. --- cpu/cc2430/dev/adc.c | 67 +++++++++++++ cpu/cc2430/dev/banked.h | 40 ++++++++ cpu/cc2430/dev/bus.c | 7 +- cpu/cc2430/dev/bus.h | 14 ++- cpu/cc2430/dev/cc2430_rf.c | 106 +++----------------- cpu/cc2430/dev/cc2430_rf.h | 15 ++- cpu/cc2430/dev/cc2430_rf_intr.c | 130 +++++++++++++++++++++++++ cpu/cc2430/dev/dma.c | 71 +++----------- cpu/cc2430/dev/dma.h | 22 +++-- cpu/cc2430/dev/dma_intr.c | 67 +++++++++++++ cpu/cc2430/dev/hwconf.h | 18 ++-- cpu/cc2430/dev/uart.c | 166 +++----------------------------- cpu/cc2430/dev/uart.h | 5 +- cpu/cc2430/dev/uart_init.c | 133 +++++++++++++++++++++++++ cpu/cc2430/dev/uart_intr.c | 64 ++++++++++++ 15 files changed, 594 insertions(+), 331 deletions(-) create mode 100644 cpu/cc2430/dev/adc.c create mode 100644 cpu/cc2430/dev/banked.h create mode 100644 cpu/cc2430/dev/cc2430_rf_intr.c create mode 100644 cpu/cc2430/dev/dma_intr.c create mode 100644 cpu/cc2430/dev/uart_init.c create mode 100644 cpu/cc2430/dev/uart_intr.c diff --git a/cpu/cc2430/dev/adc.c b/cpu/cc2430/dev/adc.c new file mode 100644 index 000000000..9c22fd521 --- /dev/null +++ b/cpu/cc2430/dev/adc.c @@ -0,0 +1,67 @@ +/** + * \file + * ADC functions + * \author + * Anthony "Asterisk" Ambuehl + * + * ADC initialization routine, trigger and result conversion routines. + * + */ + +#include +#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; +} diff --git a/cpu/cc2430/dev/banked.h b/cpu/cc2430/dev/banked.h new file mode 100644 index 000000000..d5cb55ca2 --- /dev/null +++ b/cpu/cc2430/dev/banked.h @@ -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*/ diff --git a/cpu/cc2430/dev/bus.c b/cpu/cc2430/dev/bus.c index 0ce5de117..48470f7f7 100644 --- a/cpu/cc2430/dev/bus.c +++ b/cpu/cc2430/dev/bus.c @@ -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 */ +#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*/ diff --git a/cpu/cc2430/dev/bus.h b/cpu/cc2430/dev/bus.h index 826918c2e..707633541 100644 --- a/cpu/cc2430/dev/bus.h +++ b/cpu/cc2430/dev/bus.h @@ -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__ */ diff --git a/cpu/cc2430/dev/cc2430_rf.c b/cpu/cc2430/dev/cc2430_rf.c index 3e5afd026..da9e704b3 100644 --- a/cpu/cc2430/dev/cc2430_rf.c +++ b/cpu/cc2430/dev/cc2430_rf.c @@ -3,6 +3,9 @@ * CC2430 RF driver * \author * Zach Shelby + * + * bankable code for cc2430 rf driver. this code can be placed in any bank. + * */ #include @@ -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,33 +153,25 @@ 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; - + if(rf_flags & TX_ACK) { return -1; } 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; -} -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/cc2430_rf.h b/cpu/cc2430/dev/cc2430_rf.h index 40e49bef9..edaf1e0f5 100644 --- a/cpu/cc2430/dev/cc2430_rf.h +++ b/cpu/cc2430/dev/cc2430_rf.h @@ -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); diff --git a/cpu/cc2430/dev/cc2430_rf_intr.c b/cpu/cc2430/dev/cc2430_rf_intr.c new file mode 100644 index 000000000..70b082039 --- /dev/null +++ b/cpu/cc2430/dev/cc2430_rf_intr.c @@ -0,0 +1,130 @@ +/** + * \file + * CC2430 RF driver + * \author + * Zach Shelby + * + * Non-bankable code for cc2430 rf driver. + * Interrupt routine and code called through function pointers + * must be placed into the HOME bank. + * + */ + +#include + +#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); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.c b/cpu/cc2430/dev/dma.c index f4a12bb89..f5b6ca3d7 100644 --- a/cpu/cc2430/dev/dma.c +++ b/cpu/cc2430/dev/dma.c @@ -4,11 +4,14 @@ * \author * Original: Martti Huttunen * Port: Zach Shelby + * + * bankable DMA functions */ #include #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; -} -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.h b/cpu/cc2430/dev/dma.h index 36c32c06c..f8ac02802 100644 --- a/cpu/cc2430/dev/dma.h +++ b/cpu/cc2430/dev/dma.h @@ -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); diff --git a/cpu/cc2430/dev/dma_intr.c b/cpu/cc2430/dev/dma_intr.c new file mode 100644 index 000000000..eee433594 --- /dev/null +++ b/cpu/cc2430/dev/dma_intr.c @@ -0,0 +1,67 @@ +/** + * \file + * DMA driver ISRs + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + * + * DMA interrupt routines, must be stored in HOME bank + */ + +#include + +#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; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/hwconf.h b/cpu/cc2430/dev/hwconf.h index b795b5657..5bf0f56a2 100644 --- a/cpu/cc2430/dev/hwconf.h +++ b/cpu/cc2430/dev/hwconf.h @@ -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() { \ diff --git a/cpu/cc2430/dev/uart.c b/cpu/cc2430/dev/uart.c index 32e5a9da3..86fc8fc48 100644 --- a/cpu/cc2430/dev/uart.c +++ b/cpu/cc2430/dev/uart.c @@ -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 #include @@ -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) -{ -} -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/uart.h b/cpu/cc2430/dev/uart.h index a53cd3584..8b39cff3a 100644 --- a/cpu/cc2430/dev/uart.h +++ b/cpu/cc2430/dev/uart.h @@ -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)); diff --git a/cpu/cc2430/dev/uart_init.c b/cpu/cc2430/dev/uart_init.c new file mode 100644 index 000000000..95d5f7284 --- /dev/null +++ b/cpu/cc2430/dev/uart_init.c @@ -0,0 +1,133 @@ +/** + * \file + * + * uart initialization routines + * + * \author + * + * Anthony "Asterisk" Ambuehl + * + * non-interrupt routines typically only called once, stored in any bank. + * + */ +#include +#include + +#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 */ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/uart_intr.c b/cpu/cc2430/dev/uart_intr.c new file mode 100644 index 000000000..c0f8a7f5f --- /dev/null +++ b/cpu/cc2430/dev/uart_intr.c @@ -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 +#include + +#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) +{ +} +/*---------------------------------------------------------------------------*/