| 最近在做一个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
 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
 |