void post_receive(void) { last_post = RX_POST; /* this sets the rxlen field */ /* this is undocumented but very important */ /* you will not receive anything without setting it */ *MACA_TXLEN = (MAX_PACKET_SIZE << 16); if(dma_rx == 0) { dma_rx = get_free_packet(); if (dma_rx == 0) { PRINTF("trying to fill MACA_DMARX in post_receieve but out of packet buffers\n\r"); /* set the sftclock so that we return to the maca_isr */ *MACA_SFTCLK = *MACA_CLK + RECV_SOFTIMEOUT; /* soft timeout */ *MACA_TMREN = (1 << maca_tmren_sft); /* no free buffers, so don't start a reception */ enable_irq(MACA); return; } } BOUND_CHECK(dma_rx); BOUND_CHECK(dma_tx); *MACA_DMARX = (uint32_t)&(dma_rx->data[0]); /* with timeout */ *MACA_SFTCLK = *MACA_CLK + RECV_SOFTIMEOUT; /* soft timeout */ *MACA_TMREN = (1 << maca_tmren_sft); /* start the receive sequence */ *MACA_CONTROL = ( (1 << maca_ctrl_asap) | ( 4 << PRECOUNT) | ( fcs_mode << NOFC ) | (1 << maca_ctrl_auto) | (1 << maca_ctrl_prm) | (maca_ctrl_seq_rx)); /* status bit 10 is set immediately */ /* then 11, 10, and 9 get set */ /* they are cleared once we get back to maca_isr */ }
/*------------------------------------------------------------------------ * radioWrite - write a packet from an Radioernet device *------------------------------------------------------------------------ */ devcall radioWrite ( struct dentry *devptr, /* entry in device switch table */ void *buf, /* buffer to hold packet */ uint32 len /* length of buffer */ ) { volatile packet_t *p; struct radio *rptr; uint32 i; char *from, *to; rptr = &radiotab[devptr->dvminor]; /* * Return immediately if a buffer is available */ p = get_free_packet(); if(p) { kprintf("radioWrite preparing 0x%08x\n", p); p->length = len; p->offset = 0; for (from = buf, to = (char *)p->data, i = 0; i < len; i++) *to++ = *from++; //kprintf("radioWrite semcount %d\n", semcount(rptr->osem)); //wait(rptr->osem); tx_packet(p); return len; } else { kprintf("radioWrite: can't get free packet\n"); return SYSERR; } }
void post_tx(void) { /* set dma tx pointer to the payload */ /* and set the tx len */ disable_irq(MACA); last_post = TX_POST; dma_tx = tx_head; #if PACKET_STATS dma_tx->post_tx++; #endif *MACA_TXSEQNR = dma_tx->data[2]; *MACA_TXLEN = (uint32_t)((dma_tx->length) + 2) | (3 << 16); /* set rx len to ACK length */ *MACA_DMATX = (uint32_t)&(dma_tx->data[ 0 + dma_tx->offset]); if(dma_rx == 0) { dma_rx = get_free_packet(); if (dma_rx == 0) { dma_rx = &dummy_ack; PRINTF("trying to fill MACA_DMARX on post_tx but out of packet buffers\n\r"); } } BOUND_CHECK(dma_rx); BOUND_CHECK(dma_tx); *MACA_DMARX = (uint32_t)&(dma_rx->data[0]); /* disable soft timeout clock */ /* disable start clock */ *MACA_TMRDIS = (1 << maca_tmren_sft) | ( 1<< maca_tmren_cpl) | ( 1 << maca_tmren_strt ) ; /* set complete clock to long value */ /* acts like a watchdog in case the MACA locks up */ *MACA_CPLCLK = *MACA_CLK + CPL_TIMEOUT; /* enable complete clock */ *MACA_TMREN = (1 << maca_tmren_cpl); enable_irq(MACA); *MACA_CONTROL = ( ( 4 << PRECOUNT) | ( prm_mode << PRM) | (maca_ctrl_mode_no_cca << maca_ctrl_mode) | (1 << maca_ctrl_asap) | (maca_ctrl_seq_tx)); /* status bit 10 is set immediately */ /* then 11, 10, and 9 get set */ /* they are cleared once we get back to maca_isr */ }
void main(void) { volatile packet_t *p; char c; uint16_t r=30; /* start reception 100us before ack should arrive */ uint16_t end=180; /* 750 us receive window*/ /* trim the reference osc. to 24MHz */ trim_xtal(); uart_init(UART1, 115200); vreg_init(); maca_init(); set_channel(0); /* channel 11 */ // set_power(0x0f); /* 0xf = -1dbm, see 3-22 */ // set_power(0x11); /* 0x11 = 3dbm, see 3-22 */ set_power(0x12); /* 0x12 is the highest, not documented */ /* sets up tx_on, should be a board specific item */ GPIO->FUNC_SEL_44 = 1; GPIO->PAD_DIR_SET_44 = 1; GPIO->FUNC_SEL_45 = 2; GPIO->PAD_DIR_SET_45 = 1; *MACA_RXACKDELAY = r; printf("rx warmup: %d\n\r", (int)(*MACA_WARMUP & 0xfff)); *MACA_RXEND = end; printf("rx end: %d\n\r", (int)(*MACA_RXEND & 0xfff)); set_prm_mode(AUTOACK); print_welcome("rftest-tx"); while(1) { /* call check_maca() periodically --- this works around */ /* a few lockup conditions */ check_maca(); while((p = rx_packet())) { if(p) { printf("RX: "); print_packet(p); free_packet(p); } } if(uart1_can_get()) { c = uart1_getc(); switch(c) { case 'z': r++; if(r > 4095) { r = 0; } *MACA_RXACKDELAY = r; printf("rx ack delay: %d\n\r", r); break; case 'x': if(r == 0) { r = 4095; } else { r--; } *MACA_RXACKDELAY = r; printf("rx ack delay: %d\n\r", r); break; case 'q': end++; if(r > 4095) { r = 0; } *MACA_RXEND = end; printf("rx end: %d\n\r", end); break; case 'w': end--; if(r == 0) { r = 4095; } else { r--; } *MACA_RXEND = end; printf("rx end: %d\n\r", end); break; default: p = get_free_packet(); if(p) { fill_packet(p); printf("autoack-tx --- "); print_packet(p); tx_packet(p); } break; } } } }
void main(void) { volatile packet_t *p; #ifdef CARRIER_SENSE volatile uint32_t i; #endif uint16_t r=30; /* start reception 100us before ack should arrive */ uint16_t end=180; /* 750 us receive window*/ /* trim the reference osc. to 24MHz */ trim_xtal(); uart_init(INC, MOD, SAMP); vreg_init(); maca_init(); ///* Setup the timer */ *TMR_ENBL = 0; /* tmrs reset to enabled */ *TMR0_SCTRL = 0; *TMR0_LOAD = 0; /* reload to zero */ *TMR0_COMP_UP = 18750; /* trigger a reload at the end */ *TMR0_CMPLD1 = 18750; /* compare 1 triggered reload level, 10HZ maybe? */ *TMR0_CNTR = 0; /* reset count register */ *TMR0_CTRL = (COUNT_MODE<<13) | (PRIME_SRC<<9) | (SEC_SRC<<7) | (ONCE<<6) | (LEN<<5) | (DIR<<4) | (CO_INIT<<3) | (OUT_MODE); *TMR_ENBL = 0xf; /* enable all the timers --- why not? */ set_channel(CHANNEL); /* channel 11 */ set_power(0x12); /* 0x12 is the highest, not documented */ /* sets up tx_on, should be a board specific item */ GPIO->FUNC_SEL_44 = 1; GPIO->PAD_DIR_SET_44 = 1; GPIO->FUNC_SEL_45 = 2; GPIO->PAD_DIR_SET_45 = 1; *MACA_RXACKDELAY = r; *MACA_RXEND = end; set_prm_mode(AUTOACK); while(1) { if((*TMR0_SCTRL >> 15) != 0) tick(); /* call check_maca() periodically --- this works around */ /* a few lockup conditions */ check_maca(); while((p = rx_packet())) { if(p) free_packet(p); } p = get_free_packet(); if(p) { fill_packet(p); #ifdef CARRIER_SENSE for(i=0; i<POWER_DELAY; i++) {continue;} while(get_power()>74) {} #endif #ifdef BLOCKING_TX blocking_tx_packet(p); #else tx_packet(p); #endif current_pkts++; #if defined(RANDOM_WAIT_TIME) || defined(FIXED_WAIT) random_wait(); #endif } } }
void maca_isr(void) { // print_packets("maca_isr"); maca_entry++; if (bit_is_set(*MACA_STATUS, maca_status_ovr)) { PRINTF("maca overrun\n\r"); } if (bit_is_set(*MACA_STATUS, maca_status_busy)) { PRINTF("maca busy\n\r"); } if (bit_is_set(*MACA_STATUS, maca_status_crc)) { PRINTF("maca crc error\n\r"); } if (bit_is_set(*MACA_STATUS, maca_status_to)) { PRINTF("maca timeout\n\r"); } if (data_indication_irq()) { *MACA_CLRIRQ = (1 << maca_irq_di); if (dma_rx != &dummy_ack && dma_rx != &dummy_rx) { dma_rx->length = *MACA_GETRXLVL - 2; /* packet length does not include FCS */ dma_rx->lqi = get_lqi(); dma_rx->rx_time = *MACA_TIMESTAMP; /* check if received packet needs an ack */ if(prm_mode == AUTOACK && (dma_rx->data[1] & 0x20)) { /* this wait is necessary to auto-ack */ volatile uint32_t wait_clk; wait_clk = *MACA_CLK + 200; while(*MACA_CLK < wait_clk) { continue; } } if(maca_rx_callback != 0) { maca_rx_callback(dma_rx); } add_to_rx(dma_rx); } dma_rx = 0; } if (filter_failed_irq()) { PRINTF("maca filter failed\n\r"); ResumeMACASync(); *MACA_CLRIRQ = (1 << maca_irq_flt); } if (checksum_failed_irq()) { PRINTF("maca checksum failed\n\r"); ResumeMACASync(); *MACA_CLRIRQ = (1 << maca_irq_crc); } if (softclock_irq()) { *MACA_CLRIRQ = (1 << maca_irq_sftclk); } if (poll_irq()) { *MACA_CLRIRQ = (1 << maca_irq_poll); } if(action_complete_irq()) { /* PRINTF("maca action complete %d\n\r", get_field(*MACA_CONTROL,SEQUENCE)); */ if(last_post == TX_POST) { tx_head->status = get_field(*MACA_STATUS,CODE); #if MACA_INSERT_ACK /* Having sent a message with the acknowledge request flag set the * MACA hardware will only give a tx success indication if the message * was acknowledged by the remote node. We need to detect this * condition and inject an ACK packet into the internal receive stream * as the higher layers are expecting to see an ACK packet.*/ if(tx_head->status == SUCCESS && (tx_head->data[0] & MAC_ACK_REQUEST_FLAG)) { /* Create the dummy ack packet */ static volatile packet_t *ack_p; if(ack_p = get_free_packet()) { ack_p->length = 3; ack_p->offset = 1; ack_p->data[0] = 3; ack_p->data[1] = 0x02; ack_p->data[2] = 0; ack_p->data[3] = *MACA_TXSEQNR; insert_at_rx_head(ack_p); } } #endif if(maca_tx_callback != 0) { maca_tx_callback(tx_head); } dma_tx = 0; free_tx_head(); last_post = NO_POST; } ResumeMACASync(); *MACA_CLRIRQ = (1 << maca_irq_acpl); } decode_status(); if (*MACA_IRQ != 0) { PRINTF("*MACA_IRQ %x\n\r", (unsigned int)*MACA_IRQ); } if(tx_head != 0) { post_tx(); } else { post_receive(); } }