最近在做一个source工程项目,主要是实现将I2S的音频通过蓝牙发射出去,串口作为控制外扩芯片的接口,真是困难重重啊,只想吐槽下ADK的功能强大,但是难用的特色(个人观点)。
因为CSR在source工程中已经封装了任务Task,所以就不能安装裸跑的方式,简单实现收发,而是需要注册任务的方式实现:
但是考虑到只有MessageSinkTask函数,所以这样写:
void uartStreamInit(void)
{
/* Assign task message handler */
theUARTStreamTask.task.handler = uart_stream_handler;
StreamConfigure(VM_STREAM_UART_CONFIG, VM_STREAM_UART_THROUGHPUT);
/* Configure uart settings */
StreamUartConfigure(VM_UART_RATE_57K6, VM_UART_STOP_ONE, VM_UART_PARITY_NONE);
/* Get the source for the uart */
theUARTStreamTask.uart_source = StreamUartSource();
if(theUARTStreamTask.uart_source != 0)
PanicNull(theUARTStreamTask.uart_source);
/* Register uart source with task */
MessageSinkTask(StreamSinkFromSource(theUARTStreamTask.uart_source), &theUARTStreamTask.task);
}
而发送接收则参考网上的同志写为:
static void uartSendData(uint8 *buf, uint16 len)
{
uint16 offset;
uint8 *dest;
/*get the sink for the uart, panic if not available*/
Sink sink = StreamUartSink();
PanicNull(sink);
/*claim space in the sink, getting the offset to it*/
offset = SinkClaim(sink, len);
if(offset == 0xFFFF)
Panic(); /*space not available*/
/*Map the sink into memory space*/
dest = SinkMap(sink);
(void)PanicNull(dest);
/*copy the string into the claimed space*/
memcpy(dest + offset, buf, len);
/*Flush the data out to the uart*/
PanicZero(SinkFlush(sink, len));
}
/*static uint8 uartRecvData(uint8* dataBuff,uint8 len)*/
static uint8 uartRecvData(void)
{
/* uint8 i = 0;uint8 tempBuff[]="test...";*/
uint8 ret = 0;
Source src = StreamUartSource();
uint8 recvLen = SourceSize(src);
uint8*recvPtr = (uint8*)SourceMap(src);
if(recvLen > 0 && needRecv == 1){
if(recvLen >= UART_RECV_BUF_SIZE){
memcpy(&uartRecvBuf[uartRecvLen],recvPtr,UART_RECV_BUF_SIZE-1);
uartRecvLen = UART_RECV_BUF_SIZE;
}else{
memcpy(&uartRecvBuf[uartRecvLen],recvPtr,recvLen);
uartRecvLen += recvLen;
}
needRecv = 0;
}
if(recvLen == 1 && needRecv == 0 && *recvPtr == '@'){
uartRecvBuf[0] = *recvPtr;
uartRecvLen = 1;
needRecv = 1;
}
SourceDrop(src,recvLen);
/*parse and handle data*/
if(uartRecvLen >= UART_RECV_BUF_SIZE){
/*uartSendData(uartRecvBuf,UART_RECV_BUF_SIZE);*/
memset(uartRecvBuf,0,sizeof(uartRecvBuf));
uartRecvLen = 0;
}
return ret;
}
static void uart_stream_handler(Task t, MessageId id, Message payload)
{
switch(id)
{
case MESSAGE_MORE_DATA:
{
uartRecvData();
}
break;
default:
break;
}
}
定义:
typedef struct
{
TaskData task;
Task client;
Source uart_source;
unsigned uart_src_need_drop:1;
uint8* pUartSrcStart;
uint8* pUartSrcEnd;
uint16 send_packet_length;
}UARTStreamTask_t;
#define UART_RECV_BUF_SIZE 8
static UARTStreamTask_t theUARTStreamTask;
static uint8 uartRecvBuf[UART_RECV_BUF_SIZE] = {0};
static uint8 uartRecvLen = 0;
static uint8 needRecv = 0;
调用初始化函数:
int main(void)
{
sourceAhiInit(&theSource->ahiTask);
ChargerConfigure(CHARGER_SUPPRESS_LED0, TRUE);
if(sourceAhiGetAppMode() == ahi_app_mode_configuration){
states_set_state(SOURCE_STATE_CONFIGURE_MODE);
}else{
states_set_state(SOURCE_STATE_INITIALISING);
}
uartStreamInit();
MessageLoop();
return 0;
}
需要注意的是,在ADK中编译下载后,需要通过pstool工具配置几个pskey值:因为用的是VM_STREAM_UART_CONFIG,所以要通过pstool配置Host interface为VM access to the UART:
当然还有波特率:
校验要求:无校验
将transport改成Raw
配置完成后需要在ADK中,reset,然后点击运行才能正常工作。
当然如果你觉得调试比较麻烦,也可以将这些参数写到默认的配置中:因为source工程中有个默认的psr配置文件,会随着ADK调试将配置写人:
// PSKEY_USR0 - Company ID
&028a = 0000 0a12
// PSKEY_DEVICE_NAME - QTIL Audio Dongle
&0108 = 5451 4c49 4120 6475 6f69 6420 6e6f 6c67 65
// PSKEY_LOCAL_SUPPORTED_FEATURES - Default
&00ef -
// PSKEY_HOST_INTERFACE - USB
&01f9 = 0004
// PSKEY_UART_CONFIG_USR
&01c2 = 0880
// PSKEY_UART_BAUDRATE baud 57600
&01ea = E100
...
重新编译再烧写,就不用再次配置了。
补充说明:
调试发现不关接收的数据为多少,只要大于2Byte,必会收到两包数据,第一包一直为1byte,第二包为剩下的字节格式,有兴趣的同胞可以进去跟一下代码,我想的方法是拼凑的方式,即接收的数据以‘@’开头为起始,第二包为有效的解析数据。至于原因有可能是利用一个字节告知你数据已经到来,也可能是没有用流控的原因。如果有大师找到原因还请告知。
来源:https://blog.csdn.net/u014159143/article/details/100519348 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
|