void stop_rx_cmd(void) { streaming_p = false; dsp_rx_regs->clear_state = 1; // flush cmd queue bp_clear_buf(DSP_RX_BUF_0); bp_clear_buf(DSP_RX_BUF_1); }
// Rx DSP overrun void overrun_irq_handler(unsigned irq) { dsp_rx_regs->clear_state = 1; bp_clear_buf(DSP_RX_BUF_0); bp_clear_buf(DSP_RX_BUF_1); dbsm_stop(&dsp_rx_sm); // FIXME anything else? putstr("\nirq: overrun\n"); }
static void setup_tx() { dsp_tx_regs->clear_state = 1; bp_clear_buf(DSP_TX_BUF_0); bp_clear_buf(DSP_TX_BUF_1); int tx_scale = 2500; int interp = 8; // * 4 // setup some defaults dsp_tx_regs->freq = 429496730; // 10MHz dsp_tx_regs->scale_iq = (tx_scale << 16) | tx_scale; dsp_tx_regs->interp_rate = (1 << 9) | (1 << 8) | interp; }
static void setup_tx() { dsp_tx_regs->clear_state = 1; bp_clear_buf(DSP_TX_BUF_0); bp_clear_buf(DSP_TX_BUF_1); int tx_scale = 256; int interp = 32; // setup some defaults dsp_tx_regs->freq = 0; dsp_tx_regs->scale_iq = (tx_scale << 16) | tx_scale; dsp_tx_regs->interp_rate = interp; }
static void start_tx_transfers(void) { bp_clear_buf(DSP_TX_BUF_0); // FIXME, really goes in state machine bp_clear_buf(DSP_TX_BUF_1); // fill everything with a constant 32k + 0j uint32_t const_sample = (32000 << 16) | 0; int i; for (i = 0; i < BP_NLINES; i++){ buffer_ram(DSP_TX_BUF_0)[i] = const_sample; buffer_ram(DSP_TX_BUF_1)[i] = const_sample; } /* * Construct ethernet header and word0 and preload into two buffers */ u2_eth_packet_t pkt; memset(&pkt, 0, sizeof(pkt)); //pkt.ehdr.dst = *host; pkt.ehdr.ethertype = U2_ETHERTYPE; u2p_set_word0(&pkt.fixed, U2P_TX_IMMEDIATE | U2P_TX_START_OF_BURST, 0); u2p_set_timestamp(&pkt.fixed, T_NOW); memcpy_wa(buffer_ram(DSP_TX_BUF_0), &pkt, sizeof(pkt)); memcpy_wa(buffer_ram(DSP_TX_BUF_1), &pkt, sizeof(pkt)); int tx_scale = 256; // setup Tx DSP regs dsp_tx_regs->clear_state = 1; // reset dsp_tx_regs->freq = 408021893; // 9.5 MHz [2**32 * fc/fsample] dsp_tx_regs->scale_iq = (tx_scale << 16) | tx_scale; dsp_tx_regs->interp_rate = 32; // kick off the state machine // dbsm_start(&dsp_rx_sm); SEND_CONST_TO_DSP_TX(); // send constant buffer to DSP TX }
void buffer_irq_handler(unsigned irq) { uint32_t status = buffer_pool_status->status; if (0){ putstr("irq: "); puthex32(status); putchar('\n'); } if (status & BPS_ERROR_ALL){ // FIXME rare path, handle error conditions } if (status & BPS_DONE(DSP_TX_BUF_0)){ bp_clear_buf(DSP_TX_BUF_0); SEND_CONST_TO_DSP_TX(); hal_toggle_leds(0x1); } }
void double_buffering(int port) { unsigned int localstatus = buffer_pool_status->status; if(localstatus & BPS_DONE_0) { bp_clear_buf(0); if(buffer_state[0] == FILLING) { buffer_state[0] = FULL; if(buffer_state[1] == EMPTY) { bp_receive_to_buf(1, 1, 1, 10, 509); // DSP_RX to buffer 1, use 500 lines buffer_state[1] = FILLING; } else dsp_rx_idle = 1; if(serdes_tx_idle) { serdes_tx_idle = 0; bp_send_from_buf(0, port, 1, 10, 509); // SERDES_TX from buffer 0 buffer_state[0] = EMPTYING; } } else { // buffer was emptying buffer_state[0] = EMPTY; if(dsp_rx_idle) { dsp_rx_idle = 0; bp_receive_to_buf(0, 1, 1, 10, 509); // DSP_RX to buffer 0, use 500 lines buffer_state[0] = FILLING; } if(buffer_state[1] == FULL) { bp_send_from_buf(1, port, 1, 10, 509); // SERDES_TX from buffer 1 buffer_state[1] = EMPTYING; } else serdes_tx_idle = 1; } putstr("Int Proc'ed 0\n"); } if(localstatus & BPS_DONE_1) { bp_clear_buf(1); if(buffer_state[1] == FILLING) { buffer_state[1] = FULL; if(buffer_state[0] == EMPTY) { bp_receive_to_buf(0, 1, 1, 10, 509); // DSP_RX to buffer 1, use 500 lines buffer_state[0] = FILLING; } else dsp_rx_idle = 1; if(serdes_tx_idle) { serdes_tx_idle = 0; bp_send_from_buf(1, port, 1, 10, 509); // SERDES_TX from buffer 1 buffer_state[1] = EMPTYING; } } else { // buffer was emptying buffer_state[1] = EMPTY; if(dsp_rx_idle) { dsp_rx_idle = 0; bp_receive_to_buf(1, 1, 1, 10, 509); // DSP_RX to buffer 1, use 500 lines buffer_state[1] = FILLING; } if(buffer_state[0] == FULL) { bp_send_from_buf(0, port, 1, 10, 509); // SERDES_TX from buffer 0 buffer_state[0] = EMPTYING; } else serdes_tx_idle = 1; } putstr("Int Proc'ed 1\n"); } if(localstatus & BPS_DONE_2) { bp_clear_buf(2); if(buffer_state[2] == FILLING) { buffer_state[2] = FULL; if(buffer_state[3] == EMPTY) { bp_receive_to_buf(3, port, 1, 5, 504); // SERDES_RX to buffer 3, use 500 lines buffer_state[3] = FILLING; } else serdes_rx_idle = 1; if(dsp_tx_idle) { dsp_tx_idle = 0; bp_send_from_buf(2, 1, 1, 5, 504); // DSP_TX from buffer 2 buffer_state[2] = EMPTYING; } } else { // buffer was emptying buffer_state[2] = EMPTY; if(serdes_rx_idle) { serdes_rx_idle = 0; bp_receive_to_buf(2, port, 1, 5, 504); // SERDES_RX to buffer 2 buffer_state[2] = FILLING; } if(buffer_state[3] == FULL) { bp_send_from_buf(3, 1, 1, 5, 504); // DSP_TX from buffer 3 buffer_state[3] = EMPTYING; } else dsp_tx_idle = 1; } putstr("Int Proc'ed 2\n"); } if(localstatus & BPS_DONE_3) { bp_clear_buf(3); if(buffer_state[3] == FILLING) { buffer_state[3] = FULL; if(buffer_state[2] == EMPTY) { bp_receive_to_buf(2, port, 1, 5, 504); // SERDES_RX to buffer 2, use 500 lines buffer_state[2] = FILLING; } else serdes_rx_idle = 1; if(dsp_tx_idle) { dsp_tx_idle = 0; bp_send_from_buf(3, 1, 1, 5, 504); // DSP_TX from buffer 3 buffer_state[3] = EMPTYING; } } else { // buffer was emptying buffer_state[3] = EMPTY; if(serdes_rx_idle) { serdes_rx_idle = 0; bp_receive_to_buf(3, port, 1, 5, 504); // SERDES_RX to buffer 3 buffer_state[3] = FILLING; } if(buffer_state[2] == FULL) { bp_send_from_buf(2, 1, 1, 5, 504); // DSP_TX from buffer 2 buffer_state[2] = EMPTYING; } else dsp_tx_idle = 1; } putstr("Int Proc'ed 3\n"); } }