mirror of
https://github.com/steve-m/hsdaoh-rp2350.git
synced 2025-12-10 07:44:39 +01:00
make rbuf len configurable, signal overflow to host
This commit is contained in:
parent
1bdf43ae94
commit
c5cf8c1178
7 changed files with 44 additions and 33 deletions
|
|
@ -49,7 +49,7 @@
|
|||
#define DMACH_PIO_PONG 1
|
||||
|
||||
static bool pio_dma_pong = false;
|
||||
uint16_t ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") pio_dma_irq_handler()
|
||||
|
|
@ -59,7 +59,7 @@ void __scratch_y("") pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
pio_dma_pong = !pio_dma_pong;
|
||||
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_SLICES;
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&ringbuffer[ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = RBUF_MAX_DATA_LEN;
|
||||
|
|
@ -130,7 +130,7 @@ int main()
|
|||
stdio_init_all();
|
||||
|
||||
hsdaoh_init(GPIO_DRIVE_STRENGTH_4MA, GPIO_SLEW_RATE_SLOW);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, ringbuffer);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, RBUF_DEFAULT_SLICES, ringbuffer);
|
||||
hsdaoh_start();
|
||||
init_pio_input();
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define DMACH_PIO_PONG 1
|
||||
|
||||
static bool pio_dma_pong = false;
|
||||
uint16_t ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") pio_dma_irq_handler()
|
||||
|
|
@ -77,7 +77,7 @@ void __scratch_y("") pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
pio_dma_pong = !pio_dma_pong;
|
||||
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_SLICES;
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&ringbuffer[ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = ADC_DATA_LEN/2;
|
||||
|
|
@ -143,7 +143,7 @@ void init_pio_input(void)
|
|||
#define DMACH_AUDIO_PIO_PONG 3
|
||||
|
||||
static bool audio_pio_dma_pong = false;
|
||||
uint16_t audio_ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t audio_ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int audio_ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") audio_pio_dma_irq_handler()
|
||||
|
|
@ -153,7 +153,7 @@ void __scratch_y("") audio_pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
audio_pio_dma_pong = !audio_pio_dma_pong;
|
||||
|
||||
audio_ringbuf_head = (audio_ringbuf_head + 1) % RBUF_SLICES;
|
||||
audio_ringbuf_head = (audio_ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&audio_ringbuffer[audio_ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = AUDIO_DATA_LEN/2;
|
||||
|
|
@ -231,7 +231,6 @@ int main()
|
|||
);
|
||||
|
||||
pll_init(pll_usb, 1, 1536 * MHZ, 4, 2);
|
||||
// pll_init(pll_usb, 1, (983 * MHZ) + (40 * KHZ), 4, 2);
|
||||
|
||||
/* set USB clock to clk_usb/4 */
|
||||
hw_write_masked(&clocks_hw->clk[clk_usb].div, 4 << CLOCKS_CLK_USB_DIV_INT_LSB, CLOCKS_CLK_USB_DIV_INT_BITS);
|
||||
|
|
@ -242,8 +241,8 @@ int main()
|
|||
stdio_init_all();
|
||||
|
||||
hsdaoh_init(GPIO_DRIVE_STRENGTH_4MA, GPIO_SLEW_RATE_SLOW);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, ADC_DATA_LEN, ringbuffer);
|
||||
hsdaoh_add_stream(1, 1, 75000, AUDIO_DATA_LEN, audio_ringbuffer);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, ADC_DATA_LEN, RBUF_DEFAULT_SLICES, ringbuffer);
|
||||
hsdaoh_add_stream(1, 1, 75000, AUDIO_DATA_LEN, RBUF_DEFAULT_SLICES, audio_ringbuffer);
|
||||
hsdaoh_start();
|
||||
init_pio_input();
|
||||
init_audio_pio_input();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
#define DMACH_PIO_PONG 1
|
||||
|
||||
static bool pio_dma_pong = false;
|
||||
uint16_t ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") pio_dma_irq_handler()
|
||||
|
|
@ -76,7 +76,7 @@ void __scratch_y("") pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
pio_dma_pong = !pio_dma_pong;
|
||||
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_SLICES;
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&ringbuffer[ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = ADC_DATA_LEN;
|
||||
|
|
@ -137,7 +137,7 @@ void init_pio_input(void)
|
|||
#define DMACH_AUDIO_PIO_PONG 3
|
||||
|
||||
static bool audio_pio_dma_pong = false;
|
||||
uint16_t audio_ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t audio_ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int audio_ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") audio_pio_dma_irq_handler()
|
||||
|
|
@ -147,7 +147,7 @@ void __scratch_y("") audio_pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
audio_pio_dma_pong = !audio_pio_dma_pong;
|
||||
|
||||
audio_ringbuf_head = (audio_ringbuf_head + 1) % RBUF_SLICES;
|
||||
audio_ringbuf_head = (audio_ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&audio_ringbuffer[audio_ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = AUDIO_DATA_LEN/2;
|
||||
|
|
@ -220,7 +220,6 @@ int main()
|
|||
);
|
||||
|
||||
pll_init(pll_usb, 1, 1536 * MHZ, 4, 2);
|
||||
// pll_init(pll_usb, 1, (983 * MHZ) + (40 * KHZ), 4, 2);
|
||||
|
||||
/* set USB clock to clk_usb/4 */
|
||||
hw_write_masked(&clocks_hw->clk[clk_usb].div, 4 << CLOCKS_CLK_USB_DIV_INT_LSB, CLOCKS_CLK_USB_DIV_INT_BITS);
|
||||
|
|
@ -231,8 +230,8 @@ int main()
|
|||
stdio_init_all();
|
||||
|
||||
hsdaoh_init(GPIO_DRIVE_STRENGTH_4MA, GPIO_SLEW_RATE_SLOW);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/4) * 1000, ADC_DATA_LEN, ringbuffer);
|
||||
hsdaoh_add_stream(1, 1, 75000, AUDIO_DATA_LEN, audio_ringbuffer);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/4) * 1000, ADC_DATA_LEN, RBUF_DEFAULT_SLICES, ringbuffer);
|
||||
hsdaoh_add_stream(1, 1, 75000, AUDIO_DATA_LEN, RBUF_DEFAULT_SLICES, audio_ringbuffer);
|
||||
hsdaoh_start();
|
||||
init_pio_input();
|
||||
init_audio_pio_input();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#define DMACH_ADC_PONG 1
|
||||
|
||||
static bool dma_adc_pong = false;
|
||||
uint16_t ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") adc_dma_irq_handler()
|
||||
|
|
@ -64,7 +64,7 @@ void __scratch_y("") adc_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
dma_adc_pong = !dma_adc_pong;
|
||||
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_SLICES;
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&ringbuffer[ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = RBUF_MAX_DATA_LEN;
|
||||
|
|
@ -153,7 +153,7 @@ int main()
|
|||
stdio_init_all();
|
||||
|
||||
hsdaoh_init(GPIO_DRIVE_STRENGTH_4MA, GPIO_SLEW_RATE_SLOW);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, ringbuffer);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, RBUF_DEFAULT_SLICES, ringbuffer);
|
||||
hsdaoh_start();
|
||||
init_adc_input();
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
#define DMACH_PIO_PONG 1
|
||||
|
||||
static bool pio_dma_pong = false;
|
||||
uint16_t ringbuffer[RBUF_TOTAL_LEN];
|
||||
uint16_t ringbuffer[RBUF_DEFAULT_TOTAL_LEN];
|
||||
int ringbuf_head = 2;
|
||||
|
||||
void __scratch_y("") pio_dma_irq_handler()
|
||||
|
|
@ -63,7 +63,7 @@ void __scratch_y("") pio_dma_irq_handler()
|
|||
dma_hw->intr = 1u << ch_num;
|
||||
pio_dma_pong = !pio_dma_pong;
|
||||
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_SLICES;
|
||||
ringbuf_head = (ringbuf_head + 1) % RBUF_DEFAULT_SLICES;
|
||||
|
||||
ch->write_addr = (uintptr_t)&ringbuffer[ringbuf_head * RBUF_SLICE_LEN];
|
||||
ch->transfer_count = RBUF_MAX_DATA_LEN;
|
||||
|
|
@ -136,7 +136,7 @@ int main()
|
|||
stdio_init_all();
|
||||
|
||||
hsdaoh_init(GPIO_DRIVE_STRENGTH_4MA, GPIO_SLEW_RATE_SLOW);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, ringbuffer);
|
||||
hsdaoh_add_stream(0, 1, (SYS_CLK/8) * 1000, RBUF_MAX_DATA_LEN, RBUF_DEFAULT_SLICES, ringbuffer);
|
||||
hsdaoh_start();
|
||||
init_pio_input();
|
||||
|
||||
|
|
|
|||
|
|
@ -75,10 +75,12 @@ typedef struct
|
|||
uint16_t *rbuf;
|
||||
uint tail;
|
||||
uint head;
|
||||
uint rbuf_slices;
|
||||
uint16_t format;
|
||||
uint32_t srate;
|
||||
uint16_t len;
|
||||
uint64_t data_cnt;
|
||||
bool overflow;
|
||||
} stream_t;
|
||||
|
||||
stream_t streams[MAX_STREAMS];
|
||||
|
|
@ -157,7 +159,10 @@ void init_info_packet(void)
|
|||
|
||||
void hsdaoh_update_head(int stream_id, int head)
|
||||
{
|
||||
streams[stream_id].head = head;
|
||||
if (streams[stream_id].tail == head)
|
||||
streams[stream_id].overflow = true;
|
||||
else
|
||||
streams[stream_id].head = head;
|
||||
}
|
||||
|
||||
#define DMACH_HSTX_START 13
|
||||
|
|
@ -234,11 +239,18 @@ void __scratch_x("") hstx_dma_irq_handler()
|
|||
if (!stream->active)
|
||||
continue;
|
||||
|
||||
int next_tail = (stream->tail + 1) % RBUF_SLICES;
|
||||
int next_tail = (stream->tail + 1) % stream->rbuf_slices;
|
||||
if (stream->head != next_tail) {
|
||||
next_line = &stream->rbuf[stream->tail * RBUF_SLICE_LEN];
|
||||
stream->tail = next_tail;
|
||||
next_line[RBUF_SLICE_LEN - 1] = stream->len;
|
||||
stream->data_cnt += stream->len;
|
||||
if (stream->overflow) {
|
||||
/* signal that there has been an overflow */
|
||||
next_line[RBUF_SLICE_LEN - 1] = 0x0fff;
|
||||
stream->overflow = false;
|
||||
} else
|
||||
next_line[RBUF_SLICE_LEN - 1] = stream->len;
|
||||
|
||||
next_line[RBUF_SLICE_LEN - 3] = i; // stream ID
|
||||
break;
|
||||
}
|
||||
|
|
@ -284,7 +296,7 @@ void hsdaoh_start(void)
|
|||
dma_channel_start(DMACH_HSTX_START);
|
||||
}
|
||||
|
||||
int hsdaoh_add_stream(uint16_t stream_id, uint16_t format, uint32_t samplerate, uint length, uint16_t *ringbuf)
|
||||
int hsdaoh_add_stream(uint16_t stream_id, uint16_t format, uint32_t samplerate, uint length, uint slices, uint16_t *ringbuf)
|
||||
{
|
||||
if (stream_id >= MAX_STREAMS)
|
||||
return -1;
|
||||
|
|
@ -294,7 +306,8 @@ int hsdaoh_add_stream(uint16_t stream_id, uint16_t format, uint32_t samplerate,
|
|||
stream->format = format;
|
||||
stream->srate = samplerate;
|
||||
stream->len = length;
|
||||
stream->tail = RBUF_SLICES-1;
|
||||
stream->rbuf_slices = slices;
|
||||
stream->tail = slices-1;
|
||||
stream->head = 0;
|
||||
stream->data_cnt = 0;
|
||||
stream->active = true;
|
||||
|
|
@ -378,7 +391,7 @@ void hsdaoh_init(int dstrength, int slewrate)
|
|||
}
|
||||
|
||||
/* All channels are set up identically, to transfer a whole scanline and
|
||||
* then chain to the net channel. Each time a channel finishes, we
|
||||
* then chain to the next channel. Each time a channel finishes, we
|
||||
* reconfigure the one that just finished, meanwhile another channel
|
||||
* is already making progress. */
|
||||
for (int i = 0; i < DMACH_HSTX_COUNT; i++) {
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@
|
|||
|
||||
// stream ID, CRC word and length/metadata word, so 3 reserved words
|
||||
#define NUM_RESERVED_WORDS 3
|
||||
#define RBUF_SLICES 16
|
||||
#define RBUF_DEFAULT_SLICES 16
|
||||
#define RBUF_SLICE_LEN MODE_H_ACTIVE_PIXELS
|
||||
#define RBUF_MAX_DATA_LEN (RBUF_SLICE_LEN - NUM_RESERVED_WORDS)
|
||||
#define RBUF_TOTAL_LEN (RBUF_SLICE_LEN * RBUF_SLICES)
|
||||
#define RBUF_DEFAULT_TOTAL_LEN (RBUF_SLICE_LEN * RBUF_DEFAULT_SLICES)
|
||||
|
||||
#define MAX_STREAMS 8
|
||||
#define MAX_STREAMS 4
|
||||
|
||||
enum crc_config {
|
||||
CRC_NONE, /* No CRC, just 16 bit idle counter */
|
||||
|
|
@ -51,6 +51,6 @@ typedef struct
|
|||
void hsdaoh_start(void);
|
||||
void hsdaoh_init(int dstrength, int slewrate);
|
||||
void hsdaoh_update_head(int stream_id, int head);
|
||||
int hsdaoh_add_stream(uint16_t stream_id, uint16_t format, uint32_t samplerate, uint length, uint16_t *ringbuf);
|
||||
int hsdaoh_add_stream(uint16_t stream_id, uint16_t format, uint32_t samplerate, uint length, uint slices, uint16_t *ringbuf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue