关于CH565 DMA内存访问的问题

最近在用CH565开发实时传输(isochronous)USB3.0 UVC相机。发现必须允许DVP中断被USBSS中断打断,才能保证相机的帧率(640*480 166 FPS @RAW8)正常。

//设置DVP中断,0x80表示可以被打断,

?//注意:USB3.0 ISO传输成功的关键所在

PFIC_SetPriority(DVP_IRQn, 0x80 | 13);

但是这也产生另外一个后果, 就是USBSS中断和DVP中断可能同时写DMA内存。例如:DVP接收完Image Sensor送来的一行图像数据,我把行首和行尾在DMA内存中用字符串标记,以方便USB抓包分析。

void DVP_Handler_USB30(void)

{....

???? uint8_t* pRecvBuff=pRecvSlot->ptrImageBegin + pRecvSlot->dataLength;

????//行首标记:RW<行号>

????pRecvBuff[0]='R';

???? pRecvBuff[1]='W';


???? int rowCount = g_Usb30SSDvpDmaInfo.rowCount;

????//char digits[4];

????nt divisor = 1000;

????for(int i=0; i < 4; i++)

????{

????????g_dbgDigits[i] = 0x30 + rowCount/divisor;


????????owCount = rowCount % divisor;

????????divisor? = divisor / 10;

??????}

???????? pRecvBuff[2] = digits[0];

???????? pRecvBuff[3] = digits[1];

????? ? ?pRecvBuff[4] = digits[2];

???????? pRecvBuff[5] = digits[3];


????????int width = g_Usb30SSDvpDmaInfo.nImageWidth;

????????//行尾标记:<行号>end

????pRecvBuff[width - 1]='d';

????pRecvBuff[width - 2]='n';

????pRecvBuff[width - 3]='e';

????pRecvBuff[width - 4] = digits[3];

????pRecvBuff[width - 5] = digits[2];

????pRecvBuff[width - 6] = digits[1];

????pRecvBuff[width - 7] = digits[0];

...

}

USBSS IN中断抢了DVP中断,在USBSS IN中断中准备UVC ISO PayloadHeader


void EP3_IN_Callback()

{...


????if(bHasPayloadeHeader)

????{

????PayloadHeader* PH = (PayloadHeader*)g_USB30DMAInfo.dvpData;

????//PH->bHeaderLength = sizeof(PayloadHeader);

????PH->bmHeaderInfo = g_Usb30SSDvpDmaInfo.bmHeaderInfo;

????PH->scrSourceClock.dwSourceClock = g_ClkCount;

????PH->scrSourceClock.wSOFTokenCounter = (USBSS->USB_ITP >> 3) & 0x3FF;

????//PH->alignPadByte = 0x00524448 | ((USBSS->USB_ITP%26 + 0x41) << 24);//"HDR#"

????PH->dwPresentationTime = g_ClkCount;//帧开始采集时刻

????}

...

}


通过USBCap抓包分析,发现一般正常的包如下

08a0? ?6b 7c 7d 67 6f 5d 64 6c 7c 70 75 66 65 6c 75 79? ?k|}go]dl|pufeluy

08b0? ?30 30 30 30 65 6e 64 52 57 30 30 30 31 aa 8f aa? ?0000endRW0001...

08c0? ?98 bb 92 b1 92 af 8d 98 98 c3 8a c3 9c bb 91 b8? ?................

但是也出现了如下诡异的现象

5da0? ?94 71 8c 78 aa 74 9f 6f 89 71 8e 81 99 6b 87 7a? ?.q.x.t.o.q...k.z

5db0? ?88 82 84 61 7a 76 7b 6a 78 6a 6d 6c 89 60 76 66? ?...azv{jxjml.`vf

5dc0? ?30 30 33 34 65 6e 64 c5 89 30 30 33 35 b7 92 c0? ?0034end..0035...

5dd0? ?90 bf 87 b5 8c bf a0 ad a6 cb 99 cd 93 b9 9d bf? ?................


6030? ?79 83 73 79 62 7d 75 7c 7f 7c 6f 78 61 74 68 6d? ?y.syb}u|.|oxathm

6040? ?6a 7d 71 76 6f 66 5f 84 ab 30 30 33 36 85 bd 76? ?j}qvof_..0036..v

6050? ?ba 7a b2 8f c3 93 de 8b c6 97 bb 93 c6 8f c9 7f? ?.z..............

发现标记内容与程序意图不一致,刚开始怀疑是程序Bug, 将相机设置于曝光状态即像素值都为0xFF方便查看,做了各种实验发现关了中断嵌套后问题消失。怀疑问题的根本原因是不是DMA内存访问出现了冲突。

CH565.png

请教一下: 1)USB3.0对DMA内存读的带宽是5GBPS,DVP对DMA内存写的带宽是60MB/s, 那么USB3.0和DVP对DMA内存的读写时钟显然不一样。RISC-V内部DVP和USB3.0,是不是共用数据总线和地址总线的?如果是,如何解决时钟频率冲突的。

2)如果在中断嵌套情形下, 中断A在写DMA然后中断B打断中断A的写入,中断B也写入一些东西到DMA内存,然后中断B退出,中断A继续写入,这样会不会导致DMA内存的数据总线和地址总线时序紊乱呢?

1)USB3.0对DMA内存读的带宽是5GBPS,没有这种说法

DVP对DMA内存写的带宽是60MB/s, 没有这种说法

那么USB3.0和DVP对DMA内存的读写时钟显然不一样。总线、DMA频率始终是固定的

RISC-V内部DVP和USB3.0,是不是共用数据总线和地址总线的?DVP和USB共用DMA1

如果是,如何解决时钟频率冲突的。无该问题

2)如果在中断嵌套情形下, 中断A在写DMA然后中断B打断中断A的写入,中断B也写入一些东西到DMA内存,然后中断B退出,中断A继续写入,这样会不会导致DMA内存的数据总线和地址总线时序紊乱呢?显然不会


所有的软件USB抓包,都是在协议层做解析,底层的错误均无法显示。即用于开发这类软件比较羸弱。


同步传输时,不应当完全依赖IN事务完成中断,需要在ITP到来之后,才开始每个服务周期(微帧)的传输事务(1~3次burst)。如果只依赖IN完成中断,可能会造成时间轴上的数据包和ITP的重合,这是不被允许的。

image.png


谢谢回复!

有一个疑问:

系统时钟是80MHz,是不是意味着DMA带宽上限为320MB/s?


DMA1是128bit位宽的!

image.png


系统时钟是80MHz,  DMA1 访问RAMX的带框就是16Bytes*80Mhz = 1280MB/s.请问这个带宽是所有DMA1连接的外设共享的带宽对吗?多个外设同时使用DMA1, 单个外设是达不到1280MB/s的,我的理解对吗?


是,但实际应用其实不需要也不应该关心这一层的实现。


只有登录才能回复,可以选择微信账号登录