Deploying to gh-pages from @ cherry-embedded/CherryUSB@aa0e5acfc7 🚀

This commit is contained in:
sakumisu 2024-11-27 11:50:16 +00:00
parent 7be398718a
commit aee8628bda
10 changed files with 407 additions and 4 deletions

View File

@ -1,2 +1,101 @@
usbd_cdc_acm
===============
本 demo 主要用于演示 cdc acm 功能包含收发测试DTR 控制ZLP 测试,性能测试。
- 开辟读写 buffer用于收发数据并且buffer需要用 nocache 修饰,这里我们读写都是用 2048字节是为了后面的 ZLP 测试和性能测试使用。
.. code-block:: C
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
- 协议栈回调中,我们需要在枚举完成后启动第一次传输,并清除相关 flag可以在 reset 事件中清除,也可以在 configured 事件中清除。
.. code-block:: C
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
ep_tx_busy_flag = false;
/* setup first out ep read transfer */
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
- 在接收完成中断中继续发起接收;在发送完成中断中判断是否需要发送 ZLP。
.. code-block:: C
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
// for (int i = 0; i < 100; i++) {
// printf("%02x ", read_buffer[i]);
// }
// printf("\r\n");
/* setup next out ep read transfer */
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
}
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
} else {
ep_tx_busy_flag = false;
}
}
- 以下是为了测试 DTR 功能并控制 USB 发送DTR 和 RTS 只用于搭配 UART 使用,如果是纯 USB没什么用这里仅做测试。DTR 开关使用任意串口上位机并勾选 DTR。
.. code-block:: C
void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
{
if (dtr) {
dtr_enable = 1;
} else {
dtr_enable = 0;
}
}
- 在主函数中一直调用发送即可
.. code-block:: C
void cdc_acm_data_send_with_dtr_test(uint8_t busid)
{
if (dtr_enable) {
ep_tx_busy_flag = true;
usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
while (ep_tx_busy_flag) {
}
}
}
- 上述我们需要注意,长度设置为 2048 是为了测试 ZLP 功能,通常实际使用时,接收长度应该使用 CDC_MAX_MPS 。具体原因参考 :ref:`usb_ext`
- 如果需要做性能测试,使用 tools/test_srcipts/test_cdc_speed.py 进行测试,并在测试之前删除 `usbd_cdc_acm_bulk_out` 和 `usbd_cdc_acm_bulk_in` 中的打印,否则会影响测试结果。

View File

@ -1,2 +1,83 @@
usbd_video
===============
本节主要演示 USB UAC 功能,支持 YUYV, MJPEG, H264 格式。为了方便演示,都采用的静态图。
demo 包含 **video_static_yuyv_template**, **video_static_mjpeg_template**, **video_static_h264_template**, 仅描述符和图片数据不同。
- 在高速模式下默认最大是1024字节但是如果芯片支持 additional transcations可以配置为最高 2048字节或者3072字节这样可以提高传输效率。
.. code-block:: C
#ifdef CONFIG_USB_HS
#define MAX_PAYLOAD_SIZE 1024 // for high speed with one transcations every one micro frame
#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11))
// #define MAX_PAYLOAD_SIZE 2048 // for high speed with two transcations every one micro frame
// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 2)) | (0x01 << 11))
// #define MAX_PAYLOAD_SIZE 3072 // for high speed with three transcations every one micro frame
// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 3)) | (0x02 << 11))
#else
#define MAX_PAYLOAD_SIZE 1020
#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11))
#endif
- 通常只需要修改 WIDTH 和 HEIGHT
.. code-block:: C
#define WIDTH (unsigned int)(640)
#define HEIGHT (unsigned int)(480)
#define CAM_FPS (30)
#define INTERVAL (unsigned long)(10000000 / CAM_FPS)
#define MIN_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) //16 bit
#define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS)
#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2)
- USB 端点配置,默认 interval 为 1也就是全速模式下 1ms高速模式下 125us。同步类型使用异步模式。
.. code-block:: C
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
- 使用 `usbd_video_stream_start_write` 传输数据
1传输采用双缓冲的形式 **MAX_PACKETS_IN_ONE_TRANSFER** 表示一次传输可以携带多少个 **MAX_PAYLOAD_SIZE**,通常 IP 只能为 1。
2在中断完成中调用 `usbd_video_stream_split_transfer` 继续下一次传输,直到返回为 true 表示传输完成。这边的分裂传输只是表示将图片数据拆成 **MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE** 份传输。
3通常 IP 不支持一次传输非常大的数据,比如传输 1MB因此需要做分裂传输但是会增加中断次数。并且一次传输非常大数据也是需要足够的 RAM。
.. code-block:: C
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
void video_test(uint8_t busid)
{
memset(packet_buffer, 0, sizeof(packet_buffer));
while (1) {
if (tx_flag) {
iso_tx_busy = true;
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
}

View File

@ -33,9 +33,32 @@
仓库参考https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
- 飞腾派支持两个 USB3.0 主机, 两个 USB2.0 主从机
- 飞腾派支持两个 USB3.0 主机(采用 XHCI 两个 USB2.0 主从机
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
基于 Essemi 系列芯片
---------------------------
仓库参考https://github.com/CherryUSB/cherryusb_es32
- 支持全速和高速主从机
基于 NXP MCX系列芯片
---------------------------
仓库参考https://github.com/CherryUSB/cherryusb_mcx 或者 https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx
- 支持全速 IP 和高速 IP 高速 IP 支持主机和从机
- 支持全速和高速主从机
基于 Artinchip 系列芯片
---------------------------
仓库参考https://gitee.com/artinchip/luban-lite
- 支持全速和高速主从机,主机采用 EHCI + OHCI。
基于 ST 系列芯片
---------------------------

View File

@ -1,3 +1,5 @@
.. _usb_ext:
USB 知识点拓展
===========================

View File

@ -151,6 +151,104 @@
<section id="usbd-cdc-acm">
<h1>usbd_cdc_acm<a class="headerlink" href="#usbd-cdc-acm" title="Link to this heading"></a></h1>
<p>本 demo 主要用于演示 cdc acm 功能包含收发测试DTR 控制ZLP 测试,性能测试。</p>
<ul class="simple">
<li><p>开辟读写 buffer用于收发数据并且buffer需要用 nocache 修饰,这里我们读写都是用 2048字节是为了后面的 ZLP 测试和性能测试使用。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">USB_NOCACHE_RAM_SECTION</span><span class="w"> </span><span class="n">USB_MEM_ALIGNX</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">read_buffer</span><span class="p">[</span><span class="mi">2048</span><span class="p">];</span><span class="w"> </span><span class="cm">/* 2048 is only for test speed , please use CDC_MAX_MPS for common*/</span>
<span class="n">USB_NOCACHE_RAM_SECTION</span><span class="w"> </span><span class="n">USB_MEM_ALIGNX</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">write_buffer</span><span class="p">[</span><span class="mi">2048</span><span class="p">];</span>
</pre></div>
</div>
<ul class="simple">
<li><p>协议栈回调中,我们需要在枚举完成后启动第一次传输,并清除相关 flag可以在 reset 事件中清除,也可以在 configured 事件中清除。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">usbd_event_handler</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">event</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">event</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_RESET</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_CONNECTED</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_DISCONNECTED</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_RESUME</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_SUSPEND</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_CONFIGURED</span><span class="p">:</span>
<span class="w"> </span><span class="n">ep_tx_busy_flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* setup first out ep read transfer */</span>
<span class="w"> </span><span class="n">usbd_ep_start_read</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">CDC_OUT_EP</span><span class="p">,</span><span class="w"> </span><span class="n">read_buffer</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_SET_REMOTE_WAKEUP</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">USBD_EVENT_CLR_REMOTE_WAKEUP</span><span class="p">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">default</span><span class="o">:</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p>在接收完成中断中继续发起接收;在发送完成中断中判断是否需要发送 ZLP。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbd_cdc_acm_bulk_out</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">ep</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">nbytes</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">&quot;actual out len:%d</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">nbytes</span><span class="p">);</span>
<span class="w"> </span><span class="c1">// for (int i = 0; i &lt; 100; i++) {</span>
<span class="w"> </span><span class="c1">// printf(&quot;%02x &quot;, read_buffer[i]);</span>
<span class="w"> </span><span class="c1">// }</span>
<span class="w"> </span><span class="c1">// printf(&quot;\r\n&quot;);</span>
<span class="w"> </span><span class="cm">/* setup next out ep read transfer */</span>
<span class="w"> </span><span class="n">usbd_ep_start_read</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">CDC_OUT_EP</span><span class="p">,</span><span class="w"> </span><span class="n">read_buffer</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">usbd_cdc_acm_bulk_in</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">ep</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">nbytes</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">&quot;actual in len:%d</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">nbytes</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">((</span><span class="n">nbytes</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">usbd_get_ep_mps</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">ep</span><span class="p">))</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">nbytes</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* send zlp */</span>
<span class="w"> </span><span class="n">usbd_ep_start_write</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">CDC_IN_EP</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">ep_tx_busy_flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p>以下是为了测试 DTR 功能并控制 USB 发送DTR 和 RTS 只用于搭配 UART 使用,如果是纯 USB没什么用这里仅做测试。DTR 开关使用任意串口上位机并勾选 DTR。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbd_cdc_acm_set_dtr</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">intf</span><span class="p">,</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">dtr</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">dtr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">dtr_enable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">dtr_enable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p>在主函数中一直调用发送即可</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">cdc_acm_data_send_with_dtr_test</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">dtr_enable</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">ep_tx_busy_flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span>
<span class="w"> </span><span class="n">usbd_ep_start_write</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">CDC_IN_EP</span><span class="p">,</span><span class="w"> </span><span class="n">write_buffer</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">);</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">ep_tx_busy_flag</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p>上述我们需要注意,长度设置为 2048 是为了测试 ZLP 功能,通常实际使用时,接收长度应该使用 CDC_MAX_MPS 。具体原因参考 <a class="reference internal" href="../usb/usb_ext.html#usb-ext"><span class="std std-ref">USB 知识点拓展</span></a></p></li>
<li><p>如果需要做性能测试,使用 tools/test_srcipts/test_cdc_speed.py 进行测试,并在测试之前删除 <cite>usbd_cdc_acm_bulk_out</cite><cite>usbd_cdc_acm_bulk_in</cite> 中的打印,否则会影响测试结果。</p></li>
</ul>
</section>

View File

@ -151,6 +151,81 @@
<section id="usbd-video">
<h1>usbd_video<a class="headerlink" href="#usbd-video" title="Link to this heading"></a></h1>
<p>本节主要演示 USB UAC 功能,支持 YUYV, MJPEG, H264 格式。为了方便演示,都采用的静态图。</p>
<p>demo 包含 <strong>video_static_yuyv_template</strong>, <strong>video_static_mjpeg_template</strong>, <strong>video_static_h264_template</strong>, 仅描述符和图片数据不同。</p>
<ul class="simple">
<li><p>在高速模式下默认最大是1024字节但是如果芯片支持 additional transcations可以配置为最高 2048字节或者3072字节这样可以提高传输效率。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef CONFIG_USB_HS</span>
<span class="cp">#define MAX_PAYLOAD_SIZE 1024 </span><span class="c1">// for high speed with one transcations every one micro frame</span>
<span class="cp">#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 &lt;&lt; 11))</span>
<span class="c1">// #define MAX_PAYLOAD_SIZE 2048 // for high speed with two transcations every one micro frame</span>
<span class="c1">// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 2)) | (0x01 &lt;&lt; 11))</span>
<span class="c1">// #define MAX_PAYLOAD_SIZE 3072 // for high speed with three transcations every one micro frame</span>
<span class="c1">// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 3)) | (0x02 &lt;&lt; 11))</span>
<span class="cp">#else</span>
<span class="cp">#define MAX_PAYLOAD_SIZE 1020</span>
<span class="cp">#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 &lt;&lt; 11))</span>
<span class="cp">#endif</span>
</pre></div>
</div>
<ul class="simple">
<li><p>通常只需要修改 WIDTH 和 HEIGHT</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="cp">#define WIDTH (unsigned int)(640)</span>
<span class="cp">#define HEIGHT (unsigned int)(480)</span>
<span class="cp">#define CAM_FPS (30)</span>
<span class="cp">#define INTERVAL (unsigned long)(10000000 / CAM_FPS)</span>
<span class="cp">#define MIN_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) </span><span class="c1">//16 bit</span>
<span class="cp">#define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS)</span>
<span class="cp">#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2)</span>
</pre></div>
</div>
<ul class="simple">
<li><p>USB 端点配置,默认 interval 为 1也就是全速模式下 1ms高速模式下 125us。同步类型使用异步模式。</p></li>
</ul>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="cm">/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */</span>
<span class="n">USB_ENDPOINT_DESCRIPTOR_INIT</span><span class="p">(</span><span class="n">VIDEO_IN_EP</span><span class="p">,</span><span class="w"> </span><span class="mh">0x05</span><span class="p">,</span><span class="w"> </span><span class="n">VIDEO_PACKET_SIZE</span><span class="p">,</span><span class="w"> </span><span class="mh">0x01</span><span class="p">),</span>
</pre></div>
</div>
<ul class="simple">
<li><p>使用 <cite>usbd_video_stream_start_write</cite> 传输数据</p></li>
</ul>
<p>1传输采用双缓冲的形式 <strong>MAX_PACKETS_IN_ONE_TRANSFER</strong> 表示一次传输可以携带多少个 <strong>MAX_PAYLOAD_SIZE</strong>,通常 IP 只能为 1。</p>
<p>2在中断完成中调用 <cite>usbd_video_stream_split_transfer</cite> 继续下一次传输,直到返回为 true 表示传输完成。这边的分裂传输只是表示将图片数据拆成 <strong>MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE</strong> 份传输。</p>
<p>3通常 IP 不支持一次传输非常大的数据,比如传输 1MB因此需要做分裂传输但是会增加中断次数。并且一次传输非常大数据也是需要足够的 RAM。</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbd_video_iso_callback</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">ep</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">nbytes</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">usbd_video_stream_split_transfer</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">ep</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* one frame has done */</span>
<span class="w"> </span><span class="n">iso_tx_busy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="n">USB_NOCACHE_RAM_SECTION</span><span class="w"> </span><span class="n">USB_MEM_ALIGNX</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">packet_buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="n">MAX_PACKETS_IN_ONE_TRANSFER</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_PAYLOAD_SIZE</span><span class="p">];</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">video_test</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">busid</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">memset</span><span class="p">(</span><span class="n">packet_buffer</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">packet_buffer</span><span class="p">));</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">tx_flag</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">iso_tx_busy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span>
<span class="w"> </span><span class="n">usbd_video_stream_start_write</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="n">VIDEO_IN_EP</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">packet_buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span><span class="w"> </span><span class="o">&amp;</span><span class="n">packet_buffer</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span><span class="w"> </span><span class="n">MAX_PACKETS_IN_ONE_TRANSFER</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_PAYLOAD_SIZE</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">cherryusb_mjpeg</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">cherryusb_mjpeg</span><span class="p">));</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">iso_tx_busy</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">tx_flag</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>

Binary file not shown.

View File

@ -50,6 +50,9 @@
<li class="toctree-l2"><a class="reference internal" href="#hpmicro">基于 HPMicro 系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#esp32s2-s3-p4">基于 esp32s2/s3/p4 系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id1">基于飞腾派系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#essemi">基于 Essemi 系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#nxp-mcx">基于 NXP MCX系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#artinchip">基于 Artinchip 系列芯片</a></li>
<li class="toctree-l2"><a class="reference internal" href="#st">基于 ST 系列芯片</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#usb-device">USB Device 移植要点</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usb-host">USB Host 移植要点</a></li>
@ -192,10 +195,32 @@
<h2>基于飞腾派系列芯片<a class="headerlink" href="#id1" title="Link to this heading"></a></h2>
<p>仓库参考:<a class="reference external" href="https://gitee.com/phytium_embedded/phytium-free-rtos-sdk">https://gitee.com/phytium_embedded/phytium-free-rtos-sdk</a></p>
<ul class="simple">
<li><p>飞腾派支持两个 USB3.0 主机, 两个 USB2.0 主从机</p></li>
<li><p>飞腾派支持两个 USB3.0 主机(采用 XHCI 两个 USB2.0 主从机</p></li>
<li><p>USB 的相关应用位于 <cite>example/peripheral/usb</cite> ,根据官方环境搭建完成后,即可编译使用。</p></li>
</ul>
</section>
<section id="essemi">
<h2>基于 Essemi 系列芯片<a class="headerlink" href="#essemi" title="Link to this heading"></a></h2>
<p>仓库参考:<a class="reference external" href="https://github.com/CherryUSB/cherryusb_es32">https://github.com/CherryUSB/cherryusb_es32</a></p>
<ul class="simple">
<li><p>支持全速和高速主从机</p></li>
</ul>
</section>
<section id="nxp-mcx">
<h2>基于 NXP MCX系列芯片<a class="headerlink" href="#nxp-mcx" title="Link to this heading"></a></h2>
<p>仓库参考:<a class="reference external" href="https://github.com/CherryUSB/cherryusb_mcx">https://github.com/CherryUSB/cherryusb_mcx</a> 或者 <a class="reference external" href="https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx">https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx</a></p>
<ul class="simple">
<li><p>支持全速 IP 和高速 IP 高速 IP 支持主机和从机</p></li>
<li><p>支持全速和高速主从机</p></li>
</ul>
</section>
<section id="artinchip">
<h2>基于 Artinchip 系列芯片<a class="headerlink" href="#artinchip" title="Link to this heading"></a></h2>
<p>仓库参考:<a class="reference external" href="https://gitee.com/artinchip/luban-lite">https://gitee.com/artinchip/luban-lite</a></p>
<ul class="simple">
<li><p>支持全速和高速主从机,主机采用 EHCI + OHCI。</p></li>
</ul>
</section>
<section id="st">
<h2>基于 ST 系列芯片<a class="headerlink" href="#st" title="Link to this heading"></a></h2>
<p>仓库参考:<a class="reference external" href="https://github.com/CherryUSB/cherryusb_stm32">https://github.com/CherryUSB/cherryusb_stm32</a></p>

File diff suppressed because one or more lines are too long

View File

@ -156,7 +156,7 @@
<div itemprop="articleBody">
<section id="usb">
<h1>USB 知识点拓展<a class="headerlink" href="#usb" title="Link to this heading"></a></h1>
<span id="usb-ext"></span><h1>USB 知识点拓展<a class="headerlink" href="#usb" title="Link to this heading"></a></h1>
<section id="id1">
<h2>什么是分包<a class="headerlink" href="#id1" title="Link to this heading"></a></h2>
<p>由于 USB 协议中规定了每个包的最大长度,所以当我们发送的数据长度超过了最大包长度时,就需要分包发送,这就是分包。比如 ep mps 为 64数据长度为 129则 USB 会按照 64 + 64 + 1 的形式传输。