1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
// Copyright 2012 Ettus Research LLC
#include <wb_pkt_iface64.h>
#include <wb_utils.h>
#include <printf.h>
#define NUM_BYTES_MASK 0x1fff
static uint32_t get_status(wb_pkt_iface64_config_t *config)
{
return wb_peek32(config->config_addr);
}
static void set_control(wb_pkt_iface64_config_t *config)
{
wb_poke32(config->config_addr, config->ctrl);
}
wb_pkt_iface64_config_t wb_pkt_iface64_init(const uint32_t base, const size_t ctrl_offset)
{
wb_pkt_iface64_config_t config;
config.base = base;
config.ctrl = 0;
config.config_addr = base + ctrl_offset;
set_control(&config);
wb_pkt_iface64_rx_release(&config); //always release, in case left in a filled state
return config;
}
const void *wb_pkt_iface64_rx_try_claim(wb_pkt_iface64_config_t *config, size_t *num_bytes)
{
const uint32_t status = get_status(config);
const uint32_t rx_state_flag = (status >> 31) & 0x1;
*num_bytes = (status & NUM_BYTES_MASK);
//if (*num_bytes & 0x7) *num_bytes -= 8; //adjust for tuser
if (rx_state_flag == 0) return NULL;
return (void *)config->base;
}
void wb_pkt_iface64_rx_release(wb_pkt_iface64_config_t *config)
{
config->ctrl |= 1ul << 31; //does a release
set_control(config);
while (true)
{
const uint32_t status = get_status(config);
const uint32_t rx_state_flag = (status >> 31) & 0x1;
if (rx_state_flag == 0)
{
config->ctrl &= ~(1ul << 31); //allows for next claim
set_control(config);
return;
}
}
}
void *wb_pkt_iface64_tx_claim(wb_pkt_iface64_config_t *config)
{
while (true)
{
const uint32_t status = get_status(config);
const uint32_t tx_state_flag = (status >> 30) & 0x1;
if (tx_state_flag == 1) break;
}
return (void *)config->base;
}
void wb_pkt_iface64_tx_submit(wb_pkt_iface64_config_t *config, size_t num_bytes)
{
config->ctrl |= (1ul << 30); //allows for next claim
config->ctrl &= ~(NUM_BYTES_MASK); //clear num bytes
if (num_bytes & 0x7) num_bytes += 8; //adjust for tuser
config->ctrl |= num_bytes & NUM_BYTES_MASK; //set num bytes
set_control(config);
//wait for state machine to transition
while (true)
{
const uint32_t status = get_status(config);
const uint32_t tx_state_flag = (status >> 30) & 0x1;
if (tx_state_flag == 0) break;
}
config->ctrl &= ~(1ul << 30); //release
set_control(config);
}
|