259 lines
7.9 KiB
C
Executable File
259 lines
7.9 KiB
C
Executable File
#include <driver/dma.h>
|
||
#include <bk_general_dma.h>
|
||
#include <driver/audio_ring_buff.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
|
||
//#define RWP_SAFE_INTERVAL (4)
|
||
#define RWP_SAFE_INTERVAL (0)
|
||
|
||
void ring_buffer_init(RingBufferContext* rb, uint8_t* addr, uint32_t capacity, dma_id_t dma_id, uint32_t dma_type)
|
||
{
|
||
rb->address = addr;
|
||
rb->capacity = capacity;
|
||
rb->wp = 0;
|
||
rb->rp = 0;
|
||
rb->dma_id = dma_id;
|
||
rb->dma_type = dma_type;
|
||
|
||
if(dma_id != DMA_ID_MAX)
|
||
{
|
||
if(rb->dma_type == RB_DMA_TYPE_READ)
|
||
{
|
||
//dma_channel_src_curr_address_set(dma, (uint32_t)addr);
|
||
dma_set_src_pause_addr(dma_id, (uint32_t)addr);
|
||
}
|
||
else if(rb->dma_type == RB_DMA_TYPE_WRITE)
|
||
{
|
||
//dma_channel_dst_curr_address_set(dma, (uint32_t)addr + capacity);
|
||
dma_set_dst_pause_addr(dma_id, (uint32_t)addr + capacity);
|
||
}
|
||
}
|
||
}
|
||
|
||
void ring_buffer_clear(RingBufferContext* rb)
|
||
{
|
||
rb->wp = 0;
|
||
rb->rp = 0;
|
||
|
||
if(rb->dma_id != DMA_ID_MAX)
|
||
{
|
||
if(rb->dma_type == RB_DMA_TYPE_READ)
|
||
{
|
||
//ring buffer数据都清空了,所以设置读暂停的地址为ring buffer起始地址,上来就暂停
|
||
//dma_channel_src_curr_address_set(rb->dma, (uint32_t)rb->address);
|
||
dma_set_src_pause_addr(rb->dma_id, (uint32_t)rb->address);
|
||
}
|
||
else if(rb->dma_type == RB_DMA_TYPE_WRITE)
|
||
{
|
||
//ring buffer数据都清空了,所以设置写暂停的地址为ring buffer结束地址,上来可以写满ring buffer
|
||
//dma_channel_dst_curr_address_set(rb->dma, (uint32_t)rb->address + rb->capacity);
|
||
dma_set_dst_pause_addr(rb->dma_id, (uint32_t)rb->address + rb->capacity);
|
||
}
|
||
}
|
||
}
|
||
|
||
uint32_t ring_buffer_read(RingBufferContext* rb, uint8_t* buffer, uint32_t size)
|
||
{
|
||
uint32_t required_bytes = size;
|
||
uint32_t read_bytes;
|
||
uint32_t remain_bytes;
|
||
uint32_t wp;
|
||
|
||
if((rb->dma_id != DMA_ID_MAX) && (rb->dma_type == RB_DMA_TYPE_WRITE))
|
||
{
|
||
//读取DMA寄存器[dma1_dest_wr_addr],获取此时已经读到的地址
|
||
//wp = rb->wp = dma_channel_is_enabled(rb->dma) ? dma_channel_dst_curr_pointer_get(rb->dma) - (uint32_t)rb->address : 0;
|
||
wp = rb->wp = bk_dma_get_enable_status(rb->dma_id) ? dma_get_dest_write_addr(rb->dma_id) - (uint32_t)rb->address : 0;
|
||
}
|
||
else
|
||
{
|
||
wp = rb->wp;
|
||
}
|
||
|
||
if(required_bytes == 0) return 0;
|
||
|
||
if(wp >= rb->rp)
|
||
{
|
||
remain_bytes = wp - rb->rp;
|
||
|
||
if(required_bytes > remain_bytes)
|
||
{
|
||
read_bytes = remain_bytes;
|
||
memcpy(buffer, &rb->address[rb->rp], read_bytes);
|
||
//rb->rp += read_bytes;
|
||
rb->rp = (rb->rp + read_bytes) % rb->capacity;
|
||
}
|
||
else
|
||
{
|
||
read_bytes = required_bytes;
|
||
memcpy(buffer, &rb->address[rb->rp], read_bytes);
|
||
//rb->rp += read_bytes;
|
||
rb->rp = (rb->rp + read_bytes) % rb->capacity;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
remain_bytes = rb->capacity - rb->rp;
|
||
|
||
if(required_bytes > remain_bytes)
|
||
{
|
||
read_bytes = remain_bytes;
|
||
memcpy(buffer, &rb->address[rb->rp], read_bytes);
|
||
|
||
if(required_bytes - read_bytes > wp)
|
||
{
|
||
memcpy(buffer + read_bytes, &rb->address[0], wp);
|
||
rb->rp = wp;
|
||
read_bytes += wp;
|
||
}
|
||
else
|
||
{
|
||
memcpy(buffer + read_bytes, &rb->address[0], required_bytes - read_bytes);
|
||
rb->rp = required_bytes - read_bytes;
|
||
read_bytes = required_bytes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
read_bytes = required_bytes;
|
||
memcpy(buffer, &rb->address[rb->rp], read_bytes);
|
||
//rb->rp += read_bytes;
|
||
rb->rp = (rb->rp + read_bytes) % rb->capacity;
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
if(rb->dma && rb->dma_type == RB_DMA_TYPE_WRITE)
|
||
{
|
||
dma_channel_dst_curr_address_set(rb->dma, (uint32_t)&rb->address[rb->rp]);
|
||
}
|
||
#endif
|
||
|
||
return read_bytes;
|
||
}
|
||
|
||
uint32_t ring_buffer_write(RingBufferContext* rb, uint8_t* buffer, uint32_t size)
|
||
{
|
||
uint32_t remain_bytes;
|
||
uint32_t write_bytes = size;
|
||
uint32_t rp;
|
||
|
||
if(write_bytes == 0) return 0;
|
||
|
||
if((rb->dma_id != DMA_ID_MAX) && (rb->dma_type == RB_DMA_TYPE_READ))
|
||
{
|
||
//读取DMA寄存器[dma0_src_rd_addr],获取此时已经读到的地址
|
||
//rp = rb->rp = dma_channel_is_enabled(rb->dma) ? dma_channel_src_curr_pointer_get(rb->dma) - (uint32_t)rb->address : 0;
|
||
rp = rb->rp = bk_dma_get_enable_status(rb->dma_id) ? dma_get_src_read_addr(rb->dma_id) - (uint32_t)rb->address : 0;
|
||
}
|
||
else
|
||
{
|
||
rp = rb->rp;
|
||
}
|
||
|
||
if(rb->wp >= rp)
|
||
{
|
||
remain_bytes = rb->capacity - rb->wp + rp;
|
||
|
||
if(remain_bytes >= write_bytes + RWP_SAFE_INTERVAL)
|
||
{
|
||
remain_bytes = rb->capacity - rb->wp;
|
||
|
||
if(remain_bytes >= write_bytes)
|
||
{
|
||
memcpy(&rb->address[rb->wp], buffer, write_bytes);
|
||
//rb->wp += write_bytes;
|
||
rb->wp = (rb->wp + write_bytes) % rb->capacity;
|
||
}
|
||
else
|
||
{
|
||
memcpy(&rb->address[rb->wp], buffer, remain_bytes);
|
||
rb->wp = write_bytes - remain_bytes;
|
||
memcpy(&rb->address[0], &buffer[remain_bytes], rb->wp);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
remain_bytes = rp - rb->wp;
|
||
|
||
if(remain_bytes >= write_bytes + RWP_SAFE_INTERVAL)
|
||
{
|
||
memcpy(&rb->address[rb->wp], buffer, write_bytes);
|
||
//rb->wp += write_bytes;
|
||
rb->wp = (rb->wp + write_bytes) % rb->capacity;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
if(rb->wp >= rb->capacity && rb->rp)
|
||
{
|
||
rb->wp = 0;
|
||
}
|
||
|
||
if((rb->dma_id != DMA_ID_MAX) && (rb->dma_type == RB_DMA_TYPE_READ))
|
||
{
|
||
//dma_channel_src_curr_address_set(rb->dma, (uint32_t)&rb->address[rb->wp]); //作用是啥?
|
||
//向dma读取的ring buffer写数据,写入一段数据后需要将“写指针wp”指向的地址值写入[dma0_src_pause_addr]
|
||
//这样可以确保DMA读取到该地址时暂停搬运
|
||
dma_set_src_pause_addr(rb->dma_id, (uint32_t)&rb->address[rb->wp]);
|
||
}
|
||
|
||
return write_bytes;
|
||
}
|
||
|
||
uint32_t ring_buffer_get_fill_size(RingBufferContext* rb)
|
||
{
|
||
uint32_t rp, wp;
|
||
uint32_t fill_size;
|
||
|
||
if(rb->dma_id != DMA_ID_MAX)
|
||
{
|
||
if(rb->dma_type == RB_DMA_TYPE_READ)
|
||
{
|
||
//rp = rb->rp = dma_channel_is_enabled(rb->dma) ? dma_channel_src_curr_pointer_get(rb->dma) - (uint32_t)rb->address : 0;
|
||
rp = rb->rp = bk_dma_get_enable_status(rb->dma_id) ? dma_get_src_read_addr(rb->dma_id) - (uint32_t)rb->address : 0;
|
||
wp = rb->wp;
|
||
}
|
||
else if(rb->dma_type == RB_DMA_TYPE_WRITE)
|
||
{
|
||
rp = rb->rp;
|
||
//wp = rb->wp = dma_channel_is_enabled(rb->dma) ? dma_channel_dst_curr_pointer_get(rb->dma) - (uint32_t)rb->address : 0;
|
||
wp = rb->wp = bk_dma_get_enable_status(rb->dma_id) ? dma_get_dest_write_addr(rb->dma_id) - (uint32_t)rb->address : 0;
|
||
}
|
||
else
|
||
{
|
||
rp = rb->rp;
|
||
wp = rb->wp;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rp = rb->rp;
|
||
wp = rb->wp;
|
||
}
|
||
|
||
fill_size = wp >= rp ? wp - rp : rb->capacity - rp + wp;
|
||
|
||
return fill_size;
|
||
}
|
||
|
||
uint32_t ring_buffer_get_free_size(RingBufferContext* rb)
|
||
{
|
||
uint32_t free_size;
|
||
|
||
free_size = rb->capacity - ring_buffer_get_fill_size(rb);
|
||
|
||
return free_size > RWP_SAFE_INTERVAL ? free_size - RWP_SAFE_INTERVAL : 0;
|
||
}
|
||
|