diff --git a/lib/include/maca.h b/lib/include/maca.h index 665b972d3..c6fe8e438 100644 --- a/lib/include/maca.h +++ b/lib/include/maca.h @@ -1,15 +1,16 @@ #ifndef _MACA_H_ #define _MACA_H_ +#include #include #include -#define MACA_BASE ((volatile uint32_t *) 0x80004000) -#define MACA_RESET ((volatile uint32_t *) 0x80004004) -#define MACA_RANDOM ((volatile uint32_t *) 0x80004008) - -#define MACA_CONTROL ((volatile uint32_t *) 0x8000400c) /* write only, reads as 0 */ +#define MACA_BASE (0x80004000) +#define MACA_RESET ((volatile uint32_t *) (MACA_BASE+0x04)) +#define MACA_RANDOM ((volatile uint32_t *) (MACA_BASE+0x08)) +#define MACA_CONTROL ((volatile uint32_t *) (MACA_BASE+0x0c)) +/* MACA_CONTROL bits and fields */ #define ISM 20 #define PRECOUNT 16 /* preamble reapeat counter */ #define PRECOUNT_MASK bit_mask(4,PRECOUNT) @@ -32,12 +33,78 @@ #define SEQUENCE 0 #define SEQUENCE_MASK bit_mask(3,SEQUENCE) +/* end of MACA_CONTROL bits and fields */ -#define MACA_STATUS ((volatile uint32_t *) 0x80004010) -#define MACA_DMARX ((volatile uint32_t *) 0x80004080) -#define MACA_DMATX ((volatile uint32_t *) 0x80004084) -#define MACA_GETRXLVL ((volatile uint32_t *) 0x80004098) -#define MACA_PREAMBLE ((volatile uint32_t *) 0x8000411c) +#define MACA_STATUS ((volatile uint32_t *) (MACA_BASE+0x10)) +/* MACA_STATUS bits and fields */ +#define STATUS_TIMEOUT 15 +#define CRC 14 +#define BUSY 13 +#define OVR 12 +#define CODE 0 +#define CODE_MASK bit_mask(4,CODE) +/* status codes */ +#define SUCCESS 0 +#define CODE_TIMEOUT 1 +#define CHANNEL_BUSY 2 +#define CRC_FAILED 3 +#define ABORTED 4 +#define NO_ACK 5 +#define NO_DATA 6 +#define LATE_START 7 +#define EXT_TIMEOUT 8 +#define EXT_PND_TIMEOUT 9 +#define PLL_UNLOCK 12 +#define EXTERNAL_ABORT 13 +#define NOT_COMPLETED 14 +#define DMA_BUS_ERROR 15 +/* end of MACA_CONTROL bits and fields */ + +#define MACA_FRMPND ((volatile uint32_t *) (MACA_BASE+0x14)) +#define MACA_TMREN ((volatile uint32_t *) (MACA_BASE+0x40)) +#define MACA_TMRDIS ((volatile uint32_t *) (MACA_BASE+0x44)) +#define MACA_CLK ((volatile uint32_t *) (MACA_BASE+0x48)) +#define MACA_STARTCLK ((volatile uint32_t *) (MACA_BASE+0x4c)) +#define MACA_CPLCLK ((volatile uint32_t *) (MACA_BASE+0x50)) +#define MACA_SFTCLK ((volatile uint32_t *) (MACA_BASE+0x54)) +#define MACA_CLKOFFSET ((volatile uint32_t *) (MACA_BASE+0x58)) +#define MACA_RELCLK ((volatile uint32_t *) (MACA_BASE+0x5c)) +#define MACA_CPLTIM ((volatile uint32_t *) (MACA_BASE+0x60)) +#define MACA_SLOTOFFSET ((volatile uint32_t *) (MACA_BASE+0x64)) +#define MACA_TIMESTAMP ((volatile uint32_t *) (MACA_BASE+0x68)) +#define MACA_DMARX ((volatile uint32_t *) (MACA_BASE+0x80)) +#define MACA_DMATX ((volatile uint32_t *) (MACA_BASE+0x84)) +#define MACA_DMAPOLL ((volatile uint32_t *) (MACA_BASE+0x88)) +#define MACA_TXLEN ((volatile uint32_t *) (MACA_BASE+0x8c)) +#define MACA_TXSEQNR ((volatile uint32_t *) (MACA_BASE+0x90)) +#define MACA_SETRXLVL ((volatile uint32_t *) (MACA_BASE+0x94)) +#define MACA_GETRXLVL ((volatile uint32_t *) (MACA_BASE+0x98)) +#define MACA_IRQ ((volatile uint32_t *) (MACA_BASE+0xc0)) +#define MACA_CLRIRQ ((volatile uint32_t *) (MACA_BASE+0xc4)) +#define MACA_SETIRQ ((volatile uint32_t *) (MACA_BASE+0xc8)) +#define MACA_MASKIRQ ((volatile uint32_t *) (MACA_BASE+0xcc)) +#define MACA_MACPANID ((volatile uint32_t *) (MACA_BASE+0x100)) +#define MACA_MAC16ADDR ((volatile uint32_t *) (MACA_BASE+0x104)) +#define MACA_MAC64HI ((volatile uint32_t *) (MACA_BASE+0x108)) +#define MACA_MAC64LO ((volatile uint32_t *) (MACA_BASE+0x10c)) +#define MACA_FLTREJ ((volatile uint32_t *) (MACA_BASE+0x110)) +#define MACA_CLKDIV ((volatile uint32_t *) (MACA_BASE+0x114)) +#define MACA_WARMUP ((volatile uint32_t *) (MACA_BASE+0x118)) +#define MACA_PREAMBLE ((volatile uint32_t *) (MACA_BASE+0x11c)) +#define MACA_WHITESEED ((volatile uint32_t *) (MACA_BASE+0x120)) +#define MACA_FRAMESYNC0 ((volatile uint32_t *) (MACA_BASE+0x124)) +#define MACA_FRAMESYNC1 ((volatile uint32_t *) (MACA_BASE+0x128)) +#define MACA_TXACKDELAY ((volatile uint32_t *) (MACA_BASE+0x140)) +#define MACA_RXACKDELAY ((volatile uint32_t *) (MACA_BASE+0x144)) +#define MACA_EOFDELAY ((volatile uint32_t *) (MACA_BASE+0x148)) +#define MACA_CCADELAY ((volatile uint32_t *) (MACA_BASE+0x14c)) +#define MACA_RXEND ((volatile uint32_t *) (MACA_BASE+0x150)) +#define MACA_TXCCADELAY ((volatile uint32_t *) (MACA_BASE+0x154)) +#define MACA_KEY3 ((volatile uint32_t *) (MACA_BASE+0x158)) +#define MACA_KEY2 ((volatile uint32_t *) (MACA_BASE+0x15c)) +#define MACA_KEY1 ((volatile uint32_t *) (MACA_BASE+0x160)) +#define MACA_KEY0 ((volatile uint32_t *) (MACA_BASE+0x164)) +#define MACA_OPTIONS ((volatile uint32_t *) (MACA_BASE+0x180)) void reset_maca(void); void init_phy(void); @@ -50,6 +117,12 @@ uint32_t init_from_flash(uint32_t addr); void set_power(uint8_t power); void set_channel(uint8_t chan); +void tx_packet(volatile packet_t *p); +volatile packet_t* rx_packet(void); +volatile packet_t* get_free_packet(void); +void free_packet(volatile packet_t *p); +void free_all_packets(void); + /******************************************************************************/ /* everything under this comment is messy, needs cleaning, and will */ /* probably change in the future */ @@ -113,143 +186,6 @@ enum { control_seq_cca = 6, control_seq_ed = 7 }; - -#define maca_status_cc_mask (0x0F) - -#define maca_reset_rst (1<<0) -#define maca_reset_cln_on (1<<1) - -#define maca_frmpnd_data_pending (1<<0) -#define maca_frmpnd_no_data_pending (0x00) - -#define maca_txlen_max_rxlen (127<<16) - -#define max_rx_ackwnd_slotted_mode (0xFFF<<16) -#define max_rx_ackwnd_normal_mode (0xFFF) - - - -#define maca_irq_strt (1<<15) /* - STRT - Bit 15 - Action Started Interrupt—An auto-sequence is started, either - immediately or by timer trigger. - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_sync (1<<14) /* - SYNC - Bit 14 - Sync Detected Interrupt—The modem has detected the beginning - of a new packet - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_cm (1<<13) /* - CM - Bit 13 - Complete Clock Interrupt—The complete clock has generated a - trigger. - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_crc (1<<12) /* - CRC - Bit 12 - Checksum Failed Interrupt—The checksum failed for the received - packet. - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_flt (1<<11) /* - FLT - Bit 11 - Filter Failed Interrupt—The receive header filter failed. 1 = Clear interrupt source - 0 = Leave source untouched - SFT - Bit 10 - Soft Complete Clock Interrupt—The soft complete clock has - generated a trigger. - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_sftclk (1<<10) - -#define maca_irq_lvl (1<<9) /* - LVL - Bit 9 - FIFO Level interrupt—The receive FIFO level is reached or - exceeded. - 1 = Clear interrupt source - 0 = Leave source untouched - Bit 8-5 Reserved bits—Read as zero and written with zero for future - compatibility. N/A - */ -#define maca_irq_rst (1<<4) /* - RST - Bit 4 - Reset Interrupt—A non maskable reset interrupt detected (TBD!!!) 1 = Clear interrupt source - 0 = Leave source untouched - WU - Bit 3 - Wake-up Interrupt—Low power mode has been exited (TBD in - connection with CCM module). - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_wu (1<<3) - -#define maca_irq_di (1<<2) /* - DI - Bit 2 - Data Indication Interrupt—During receive, a packet has been - successfully received. - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_poll (1<<1) /* - POLL - Bit 1 - Poll Indication Interrupt—Issued when data request received (and - before ACK transmitted). MCU may then set MACA_FRMPND and - prepare fast response. TBD: Shall this be skipped if - MACA_FRMPND is clear? - 1 = Clear interrupt source - 0 = Leave source untouched - */ -#define maca_irq_acpl (1<<0) /* - ACPL - Action Complete Interrupt—Marks the completion of a complete - auto-sequence. - 1 = Clear interrupt source - 0 = Leave source untouched - */ - - -#define maca_start_clk (1<<0)/* - TMREN & TMRDIS enable/disable start clock - */ - -#define maca_cpl_clk (1<<1)/* - TMREN & TMRDIS enable/disable complete clock - */ - -#define maca_soft_clk (1<<2)/* - TMREN & TMRDIS enable/disable soft complete clock - */ - -#define maca_abort_start_clk (1<<3)/* - TMRDIS abort start clock - */ - -#define maca_abort_cpl_clk (1<<4)/* - TMRDIS abort complete clock - */ - -#define maca_abort_soft_clk (1<<5)/* - TMRDIS abort soft complete clock - */ - #define maca_version (*((volatile uint32_t *)(0x80004000))) #define maca_reset (*((volatile uint32_t *)(0x80004004))) @@ -378,24 +314,6 @@ typedef union maca_reset_reg_tag #define MACA_CTRL_MODE_NON_SLOTTED (1) #define MACA_CTRL_MODE_SLOTTED (2) - -typedef union maca_status_reg_tag -{ - struct - { - uint32_t RESERVED:16; - uint32_t TO:1; - uint32_t CRC:1; - uint32_t BUSY:1; - uint32_t OVR:1; - uint32_t zigbee:1; - uint32_t :7; - uint32_t COMPLETE_CODE:4; - } Bits; - uint32_t Reg; -} maca_status_reg_t; - - typedef enum maca_freq_chann_tag { SMAC_CHANN_11 = 0, @@ -418,32 +336,107 @@ typedef enum maca_freq_chann_tag } maca_freq_chann_t; -typedef union maca_maskirq_reg_tag -{ - struct - { - uint32_t RESERVED1:16; - uint32_t STRT:1; - uint32_t SYNC:1; - uint32_t CM:1; - uint32_t CRC:1; - uint32_t FLT:1; - uint32_t SFT:1; - uint32_t LVL:1; - uint32_t RESERVED0:4; - uint32_t NOT_USED1:1; - uint32_t NOT_USED0:1; - uint32_t DI:1; - uint32_t POLL:1; - uint32_t ACPL:1; - } Bits; - uint32_t Reg; -} maca_maskirq_reg_t; +/* Sequence complete codes */ +enum maca_complete_code { + maca_cc_success = 0, + maca_cc_timeout = 1, + maca_cc_channel_busy = 2, + maca_cc_crc_fail = 3, + maca_cc_aborted = 4, + maca_cc_no_ack = 5, + maca_cc_no_data = 6, + maca_cc_late_start = 7, + maca_cc_ext_timeout = 8, + maca_cc_ext_pnd_timeout = 9, + maca_cc_nc1 = 10, + maca_cc_nc2 = 11, + maca_cc_nc3 = 12, + maca_cc_cc_external_abort= 13, + maca_cc_not_completed = 14, + maca_cc_bus_error = 15 +}; +/* control sequence codes */ +enum maca_ctrl_seq { + maca_ctrl_seq_nop = 0, + maca_ctrl_seq_abort = 1, + maca_ctrl_seq_wait = 2, + maca_ctrl_seq_tx = 3, + maca_ctrl_seq_rx = 4, + maca_ctrl_seq_txpoll = 5, + maca_ctrl_seq_cca = 6, + maca_ctrl_seq_ed = 7 +}; -#define _is_action_complete_interrupt(x) (0 != (maca_irq_acpl & x)) -#define _is_filter_failed_interrupt(x) (0 != (maca_irq_flt & x)) -#define _is_checksum_failed_interrupt(x) (0 != (maca_irq_crc & x)) +/* transmission modes */ +enum maca_ctrl_modes { + maca_ctrl_mode_no_cca = 0, + maca_ctrl_mode_non_slotted_csma_ca = 1, + maca_ctrl_mode_slotted_csma_ca = 2, +}; + +/* MACA_CONTROL bits */ +enum maca_ctrl_bits { + maca_ctrl_seq = 0, /* 3 bits */ + maca_ctrl_mode = 3, /* 2 bits */ + maca_ctrl_tm = 5, + maca_ctrl_lfsr = 6, + maca_ctrl_auto = 7, + maca_ctrl_bcn = 8, + maca_ctrl_asap = 9, + maca_ctrl_rel = 10, + maca_ctrl_prm = 11, + maca_ctrl_nofc = 12, + maca_ctrl_role = 13, + /* 14 reserved */ + maca_ctrl_rsto = 15, + maca_ctrl_pre_count = 16, /* 4 bits */ + maca_ctrl_ism = 20, +}; + +/* MACA_IRQ bits */ +enum maca_irqs { + maca_irq_acpl = 0, + maca_irq_poll = 1, + maca_irq_di = 2, + maca_irq_wu = 3, + maca_irq_rst = 4, + maca_irq_lvl = 9, + maca_irq_sftclk = 10, + maca_irq_flt = 11, + maca_irq_crc = 12, + maca_irq_cm = 13, + maca_irq_sync = 14, + maca_irq_strt = 15, +}; + +/* MACA_RESET bits */ +enum maca_reset_bits { + maca_reset_rst = 0, + maca_reset_clkon = 1, +}; + +/* MACA_TMREN bits */ +enum maca_tmren_bits { + maca_tmren_strt = 0, + maca_tmren_cpl = 1, + maca_tmren_sft = 2, +}; + +enum maca_status_bits { + maca_status_ovr = 12, + maca_status_busy = 13, + maca_status_crc = 14, + maca_status_to = 15, +}; + +#define action_complete_irq() bit_is_set(*MACA_IRQ,maca_irq_acpl) +#define filter_failed_irq() bit_is_set(*MACA_IRQ,maca_irq_flt) +#define checksum_failed_irq() bit_is_set(*MACA_IRQ,maca_irq_crc) +#define data_indication_irq() bit_is_set(*MACA_IRQ,maca_irq_di) + +#define status_is_not_completed() ((*MACA_STATUS & 0xffff) == maca_cc_not_completed) +#define status_is_success() ((*MACA_STATUS & 0xffff) == maca_cc_success) #define SMAC_MACA_CNTL_INIT_STATE ( control_prm | control_nofc | control_mode_non_slotted ) diff --git a/lib/maca.c b/lib/maca.c index 72292eac8..eb4f22f94 100644 --- a/lib/maca.c +++ b/lib/maca.c @@ -10,50 +10,289 @@ #define PRINTF(...) #endif +#ifndef NUM_PACKETS +#define NUM_PACKETS 8 +#endif + +#define MACA_CLOCK_DIV 95 + #define reg(x) (*(volatile uint32_t *)(x)) +static volatile packet_t packet_pool[NUM_PACKETS]; +static volatile packet_t *free_head, *rx_head, *rx_end, *tx_head, *tx_end, *dma_tx, *dma_rx = 0; + +enum posts { + TX, + RX, + MAX_POST, +}; +static volatile uint8_t last_post = MAX_POST; + +/* public packet routines */ +/* heads are to the right */ +/* ends are to the left */ +void free_packet(volatile packet_t *p) { + p->length = 0; + p->left = free_head; p->right = 0; + free_head = p; + return; +} + +volatile packet_t* get_free_packet(void) { + volatile packet_t *p; + p = free_head; + if( p != 0 ) { + free_head = p->left; + free_head->right = 0; + } + return p; +} + +volatile packet_t* rx_packet(void) { + volatile packet_t *p; + p = rx_head; + if( p != 0 ) { + rx_head = p->left; + rx_head->right = 0; + } + return p; +} + +void tx_packet(volatile packet_t *p) { + tx_end->left = p; + p->right = tx_end; + tx_end = p; tx_end->left = 0; + if(tx_head == 0) { tx_head = tx_end; } + if(get_field(*MACA_STATUS,CODE) != NOT_COMPLETED) { post_tx(); } + return; +} + +void free_all_packets(void) { + volatile int i; + free_head = 0; + for(i=0; ileft; + free_packet(p); + return; +} + +void add_to_rx(packet_t *p) { + rx_end->left = p; + p->right = rx_end; + rx_end = p; rx_end->left = 0; + return; +} + +void post_receive(void) { + /* this sets the rxlen field */ + /* this is undocumented but very important */ + /* you will not receive anything without setting it */ + last_post = RX; + *MACA_TXLEN = (MAX_PACKET_SIZE << 16); + if(dma_rx == 0) { + dma_rx = get_free_packet(); + if (dma_rx == 0) + printf("out of packet buffers\n"); + } + *MACA_DMARX = (uint32_t)&(dma_rx->data[0]); + /* with timeout */ + *MACA_SFTCLK = *MACA_CLK - 1; + *MACA_TMREN = (1 << maca_tmren_sft); + /* start the receive sequence */ + *MACA_CONTROL = ( (1 << maca_ctrl_asap) | + (1 << maca_ctrl_auto) | + (1 << maca_ctrl_prm) | + (maca_ctrl_seq_rx)); +} + +void post_tx(void) { + /* set dma tx pointer to the payload */ + /* and set the tx len */ + last_post = TX; + dma_tx = tx_head; + *MACA_TXLEN = (uint32_t)(dma_tx->length + 2); + *MACA_DMATX = (uint32_t)&(dma_tx->data[0]); + dma_rx = get_free_packet(); + *MACA_DMARX = (uint32_t)&(dma_rx->data[0]); + *MACA_TMREN = 0; + /* do the transmit */ + *MACA_CONTROL = ( (1 << maca_ctrl_prm) | + (maca_ctrl_mode_no_cca << maca_ctrl_mode) | + (1 << maca_ctrl_asap) | + (maca_ctrl_seq_tx)); +} + + +static void decode_status(int status) { + switch(status) + { + case maca_cc_aborted: + { + PRINTF("maca: aborted\n\r"); + ResumeMACASync(); + break; + + } + case maca_cc_not_completed: + { +// PRINTF("maca: not completed\n\r"); + ResumeMACASync(); + break; + + } + case maca_cc_timeout: + { + PRINTF("maca: timeout\n\r"); + ResumeMACASync(); + break; + + } + case maca_cc_no_ack: + { + PRINTF("maca: no ack\n\r"); + ResumeMACASync(); + break; + + } + case maca_cc_ext_timeout: + { +// PRINTF("maca: ext timeout\n\r"); + ResumeMACASync(); + break; + + } + case maca_cc_ext_pnd_timeout: + { + PRINTF("maca: ext pnd timeout\n\r"); + ResumeMACASync(); + break; + } + case maca_cc_success: + { + //PRINTF("maca: success\n\r"); + break; + } + default: + { + PRINTF("status: %x", status); + ResumeMACASync(); + + } + } +} + +void maca_isr(void) { + int i, status; + struct packet_t *packet; + + status = *MACA_STATUS; + + if (data_indication_irq()) { + *MACA_CLRIRQ = (1 << maca_irq_di); + dma_rx->length = *MACA_GETRXLVL - 2; + PRINTF("data ind %x %d\n", dma_rx, dma_rx->length); + add_to_rx(dma_rx); + dma_rx = 0; + } + if (filter_failed_irq()) { + PRINTF("filter failed\n"); + ResumeMACASync(); + *MACA_CLRIRQ = (1 << maca_irq_flt); + } + if (checksum_failed_irq()) { + PRINTF("checksum failed\n"); + ResumeMACASync(); + *MACA_CLRIRQ = (1 << maca_irq_crc); + } + if(action_complete_irq()) { + PRINTF("action complete %d\n", get_field(*MACA_CONTROL,SEQUENCE)); + if(last_post == TX) { + free_packet(dma_tx); + } + + *MACA_CLRIRQ = (1 << maca_irq_acpl); + status &= 0x0000ffff; + decode_status(status); + } + if (bit_is_set(status, maca_status_ovr)) + PRINTF("ISR overrun\n"); + if (bit_is_set(status, maca_status_busy)) + PRINTF("ISR busy\n"); + if (bit_is_set(status, maca_status_crc)) + PRINTF("ISR crc\n"); + if (bit_is_set(status, maca_status_to)) + PRINTF("ISR timeout\n"); + + i = *MACA_IRQ; + if (i != 0) + PRINTF("MACA IRQ %x\n", i); + + if(tx_head != 0) { + post_tx(); + } else { + post_receive(); + } +} + + static uint8_t ram_values[4]; + void init_phy(void) { volatile uint32_t cnt; - - maca_reset = maca_reset_rst; - - for(cnt=0; cnt < 100; cnt++); - - maca_reset = maca_reset_cln_on; - maca_control = control_seq_nop; -#define DELAY 400000 - for(cnt=0; cnt < DELAY; cnt++); - maca_tmren = maca_start_clk | maca_cpl_clk; - maca_divider = gMACA_Clock_DIV_c; - maca_warmup = 0x00180012; - maca_eofdelay = 0x00000004; - maca_ccadelay = 0x001a0022; - maca_txccadelay = 0x00000025; - maca_framesync = 0x000000A7; - maca_clk = 0x00000008; -// maca_maskirq = 0; //(maca_irq_cm | maca_irq_acpl | maca_irq_rst | maca_irq_di | maca_irq_crc | maca_irq_flt ); - maca_maskirq = (maca_irq_rst | maca_irq_acpl | maca_irq_cm | maca_irq_flt | maca_irq_crc); - maca_slotoffset = 0x00350000; + *MACA_RESET = (1 << maca_reset_rst); + + for(cnt = 0; cnt < 100; cnt++) {}; + + *MACA_RESET = (1 << maca_reset_clkon); + + *MACA_CONTROL = maca_ctrl_seq_nop; + + for(cnt = 0; cnt < 400000; cnt++) {}; + + *MACA_TMREN = (1 << maca_tmren_strt) | (1 << maca_tmren_cpl); + *MACA_CLKDIV = MACA_CLOCK_DIV; + *MACA_WARMUP = 0x00180012; + *MACA_EOFDELAY = 0x00000004; + *MACA_CCADELAY = 0x001a0022; + *MACA_TXCCADELAY = 0x00000025; + *MACA_FRAMESYNC0 = 0x000000A7; + *MACA_CLK = 0x00000008; + *MACA_MASKIRQ = ((1 << maca_irq_rst) | (1 << maca_irq_acpl) | (1 << maca_irq_cm) | + (1 << maca_irq_flt) | (1 << maca_irq_crc) | (1 << maca_irq_di)); + *MACA_SLOTOFFSET = 0x00350000; + } void reset_maca(void) { uint32_t tmp; - MACA_WRITE(maca_control, control_seq_nop); - do - { - tmp = MACA_READ(maca_status); - } - while ((tmp & maca_status_cc_mask) == cc_not_completed); - - /* Clear all interrupts. */ - MACA_WRITE(maca_clrirq, 0xFFFF); + *MACA_CONTROL = maca_ctrl_seq_nop; + do { + tmp = *MACA_STATUS; + } while ((tmp & 0xf) == maca_cc_not_completed); + + /* Clear all interrupts. */ + *MACA_CLRIRQ = 0xffff; } + /* 004030c4 : 4030c4: 4806 ldr r0, [pc, #24] (4030e0 ) // r0 gets base 0x80009a00 @@ -341,7 +580,15 @@ const uint32_t AIMVAL[19] = { #define ADDR_POW3 ADDR_POW1 + 64 void set_power(uint8_t power) { reg(ADDR_POW1) = PSMVAL[power]; - reg(ADDR_POW2) = (ADDR_POW1>>18) | PAVAL[power]; + +/* see http://devl.org/pipermail/mc1322x/2009-October/000065.html */ +/* reg(ADDR_POW2) = (ADDR_POW1>>18) | PAVAL[power]; */ +#ifdef USE_PA + reg(ADDR_POW2) = 0xffffdfff & PAVAL[power]; /* single port */ +#else + reg(ADDR_POW2) = 0x00002000 | PAVAL[power]; /* dual port */ +#endif + reg(ADDR_POW3) = AIMVAL[power]; } diff --git a/tests/per.c b/tests/per.c index aa0aa78a9..82727c964 100644 --- a/tests/per.c +++ b/tests/per.c @@ -15,27 +15,69 @@ #define DEBUG_MACA 1 -typedef struct { - int type; -} packet_t; +/* how long to wait between session requests */ +#define SESSION_REQ_TIMEOUT 10 /* phony seconds */ enum STATES { SCANNING, MAX_STATE }; +typedef uint32_t ptype_t; enum PACKET_TYPE { - PACKET_PERTEST, + PACKET_SESS_REQ, MAX_PACKET_TYPE }; +/* get protocol level packet type */ +/* this is not 802.15.4 packet type */ +ptype_t get_packet_type(packet_t *p) { + return MAX_PACKET_TYPE; +} -int get_packet(packet_t *p) { return 0; } -void print_packet(packet_t p) { return; } +typedef uint32_t session_id_t; + +/* phony get_time */ +uint32_t get_time(void) { + static volatile int32_t cur_time = 0; + cur_time++; + return cur_time; +} + + +#define random_short_addr() (*MACA_RANDOM & ones(sizeof(short_addr_t)*8)) + +void build_session_req(volatile packet_t *p) { + p->length = 4; + p->data[0] = 0xff; + p->data[1] = 0x01; + p->data[2] = 0x23; + p->data[3] = 0x45; + return; +} + +void session_req(short_addr_t addr) { + static volatile int time = 0; + volatile packet_t *p; + +// if((get_time() - time) > SESSION_REQ_TIMEOUT) { +// time = get_time(); + p = get_free_packet(); + build_session_req(p); + tx_packet(p); +// } + return; +} + +void print_packet(packet_t *p) { return; } +session_id_t open_session(short_addr_t addr) { return 0; } void main(void) { uint32_t state; - packet_t p; - + volatile packet_t *p; + session_id_t sesid; + ptype_t type; + short_addr_t addr, my_addr; + uart_init(INC,MOD); print_welcome("Packet error test"); @@ -46,29 +88,47 @@ void main(void) { vreg_init(); flyback_init(); init_phy(); - + free_all_packets(); + /* trim the reference osc. to 24MHz */ pack_XTAL_CNTL(CTUNE_4PF, CTUNE, FTUNE, IBIAS); set_power(0x0f); /* 0dbm */ set_channel(0); /* channel 11 */ + enable_irq(MACA); + /* initial radio command */ /* nop, promiscuous, no cca */ *MACA_CONTROL = (1 << PRM) | (NO_CCA << MODE); + /* generate a random short address */ + my_addr = random_short_addr(); + state = SCANNING; while(1) { - + switch(state) { case SCANNING: - if(get_packet(&p)) { - print_packet(p); - /* if we have a packet */ - /* check if it's a pertest beacon */ - if(p.type == PACKET_PERTEST) { - /* try to start a session */ + if((p = rx_packet())) { + /* extract what we need and free the packet */ + print_packet(p); + type = get_packet_type(p); + addr = p->addr; + free_packet(p); + /* pick a new address if someone else is using ours */ + if(addr == my_addr) { + my_addr = random_short_addr(); + printf("DUP addr received, changing to new addr 0x%x02\n\r",my_addr); } + /* if we have a packet */ + /* check if it's a session request beacon */ + if(type == PACKET_SESS_REQ) { + /* try to start a session */ + sesid = open_session(p->addr); + } + } else { + session_req(my_addr); } break; default: