网站建设公司排名,网络规划设计师考试科目,昆明网站建设电话,四川省建设规划局官方网站由于公司设备升级后出了问题#xff0c;需要对USB驱动进行修改#xff0c;原本使用的是寄存器模式进行UART传输#xff0c;但是由于FX3寄存器模式会出现长时间延时等待的问题#xff0c;不得不对其传输模式进行修改。虽然赛普拉斯的EZ-USB FX3系列芯片功能强大#xff0c;… 由于公司设备升级后出了问题需要对USB驱动进行修改原本使用的是寄存器模式进行UART传输但是由于FX3寄存器模式会出现长时间延时等待的问题不得不对其传输模式进行修改。虽然赛普拉斯的EZ-USB FX3系列芯片功能强大成本适中但共享资源太少API参考手册里面的干货不多直接导致开发困难出现问题只能去官方社区寻找答案。新模式的开发也不是一帆风顺找来找去只有在固件库中找到了UartLpDmaMode这个例程还比较相似。于是便在其基础上进行修改。 在UartLpDmaMode例程中其数据流通方向是这样的 只是从将接收到的数据进行了循环发送这样一来其生产者和消费者ID便很好设置但是你无法对DMA通道进行直接操作换句话说你无法发送你想要发送的数据也无法将你接收到的数据存入自己开辟的缓冲区中进行存储使用当然这样并不是我想要的。 我想要操作的数据传输是能够实现想传什么传什么接收到的数据能想什么时候用就可以什么时候用。其数据流通就如同下图 但是我在初期对FX3的DMA消费者生产者理解不深一度认为这是不能实现的但经过几天的社区询问以及个人摸索发现可以这样使用由于期间走了很多弯路深知百度找不到任何有关赛普拉斯有用资料的苦衷现在把这段代码分享出来。 开发环境EZ-USB FX3 Development Kit SDK1.3.4 开发板型号CYUSB3KIT-003CYUSB3014 开发目的实现串口DMA模式的数据发送以及接收能够随意发送自己缓冲区中的数据接收到的数据能够储存在个人开辟的缓冲区中 1 /*此DEMO使用DMA模式可以发送自己缓冲区中的数据接收到数据后可将接收到的数据存入全局变量glRxBuffer-buffer中。2 *注意3 * 赛普拉斯FX3的DMA缓冲区大小最小是16个字节缓冲区大小必须是16的倍数也就是说发送数据至少发送16个字节发送的数据最大不能超过缓冲区的设定值接收也一样否则缓冲区未满无法触发接收和发送4 *如果与其他设备通讯可以让其他设备强制发送16个字节的数据自己取有效位使用。如果想一个字节一个字节的发送和接收可以使用寄存器模式。5 */6 7 #include cyu3system.h8 #include cyu3os.h9 #include cyu3error.h10 #include cyu3uart.h11 12 #define CY_FX_UARTLP_THREAD_STACK (0x0400) /* UART application thread stack size */13 #define CY_FX_UARTLP_THREAD_PRIORITY (8) /* UART application thread priority */14 #define CY_FX_UART_DMA_TX_SIZE (0) /* DMA transfer size */15 #define CY_FX_UART_DMA_BUF_SIZE (16) /* Buffer size */16 17 CyU3PThread UartLpAppThread; /* UART Example application thread structure */18 19 uint8_t testBuffer[16] {0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xff};20 21 CyU3PDmaChannel glUartRXChHandle;22 CyU3PDmaChannel glUartTXChHandle;23 CyU3PDmaBuffer_t* glTxBuffer;24 CyU3PDmaBuffer_t* glRxBuffer;25 uint8_t ClearFlag 0;26 27 /* Application error handler */28 void29 CyFxAppErrorHandler (30 CyU3PReturnStatus_t apiRetStatus /* API return status */31 )32 {33 /* Application failed with the error code apiRetStatus */34 35 /* Add custom debug or recovery actions here */36 37 /* Loop indefinitely */38 for (;;)39 {40 /* Thread sleep : 100 ms */41 CyU3PThreadSleep (100);42 }43 }44 /***********************************************************************************************45 *函数名 SendData46 *函数功能描述 通过DMA模式 由串口发送数据47 *函数参数 buffer-所需要发送的数据 len-发送数据的长度48 *函数返回值 无49 *注意len最小为1650 ***********************************************************************************************/51 void SendData(uint8_t * buffer, unsigned int len)52 {53 CyU3PReturnStatus_t status;54 unsigned int i 0;55 CyU3PDmaChannelGetBuffer(glUartTXChHandle, glTxBuffer, 0);56 for(i 0; i len; i)57 {58 glTxBuffer-buffer[i] buffer[i];59 }60 CyU3PDmaChannelSetupSendBuffer(glUartTXChHandle,glTxBuffer);61 status CyU3PDmaChannelCommitBuffer(glUartTXChHandle, 16, 0);62 if (status CY_U3P_SUCCESS)63 {64 65 }66 }67 68 /***********************************************************************************************69 *函数名 ReceivedDataCallBack70 *函数功能描述 接收缓冲区充满后的回调函数71 *函数参数 chHandle-DMA通道的句柄 type-事件类型 input-输入72 *函数返回值 无73 *注意形参已经被设置好直接可以使用74 ***********************************************************************************************/75 void ReceivedDataCallBack(76 CyU3PDmaChannel *chHandle, /* Handle to the DMA channel. */77 CyU3PDmaCbType_t type, /* Callback type. */78 CyU3PDmaCBInput_t *input)79 {80 CyU3PReturnStatus_t status;81 if(type CY_U3P_DMA_CB_PROD_EVENT)82 {83 //CyU3PDmaChannelSetWrapUp(glUartRXChHandle);84 status CyU3PDmaChannelGetBuffer(glUartRXChHandle, glRxBuffer, 0);85 //测试用将收到的信息在发送出去此时测试为接收到16个字节的数据86 SendData(glRxBuffer-buffer, 16);87 //SendData(testBuffer, 16);88 ClearFlag 1;89 if (status CY_U3P_SUCCESS)90 {91 CyU3PDmaChannelDiscardBuffer(glUartRXChHandle);92 }93 }94 }95 96 /* This function initializes the UART module */97 void98 CyFxUartDMAlnInit (void)99 {
100 CyU3PUartConfig_t uartConfig;
101 CyU3PDmaChannelConfig_t dmaConfig;
102 CyU3PReturnStatus_t apiRetStatus CY_U3P_SUCCESS;
103
104 //开启DCache后 一定设置为32未开启最好也设置成32但也可设置为16不影响使用
105 glTxBuffer (CyU3PDmaBuffer_t*)CyU3PDmaBufferAlloc (32);
106 glRxBuffer (CyU3PDmaBuffer_t*)CyU3PDmaBufferAlloc (32);
107
108 /* Initialize the UART module */
109 apiRetStatus CyU3PUartInit ();
110 if (apiRetStatus ! CY_U3P_SUCCESS)
111 {
112 /* Error handling */
113 CyFxAppErrorHandler(apiRetStatus);
114 }
115
116 /* Configure the UART
117 Baudrate 115200, One stop bit, No parity, Hardware flow control enabled.
118 */
119 CyU3PMemSet ((uint8_t *)uartConfig, 0, sizeof(uartConfig));
120 uartConfig.baudRate CY_U3P_UART_BAUDRATE_115200;
121 uartConfig.stopBit CY_U3P_UART_ONE_STOP_BIT;
122 uartConfig.parity CY_U3P_UART_NO_PARITY;
123 uartConfig.flowCtrl CyFalse; //一定不能为真
124 uartConfig.txEnable CyTrue;
125 uartConfig.rxEnable CyTrue;
126 uartConfig.isDma CyTrue; /* DMA mode */
127
128 /* Set the UART configuration */
129 apiRetStatus CyU3PUartSetConfig (uartConfig, NULL);
130 if (apiRetStatus ! CY_U3P_SUCCESS )
131 {
132 /* Error handling */
133 CyFxAppErrorHandler(apiRetStatus);
134 }
135
136 /* Create a DMA Manual channel between UART producer socket
137 and UART consumer socket */
138 CyU3PMemSet ((uint8_t *)dmaConfig, 0, sizeof(dmaConfig));
139 dmaConfig.size CY_FX_UART_DMA_BUF_SIZE;
140 dmaConfig.count 1;
141 dmaConfig.prodSckId CY_U3P_LPP_SOCKET_UART_PROD; //生产者为RX
142 dmaConfig.consSckId CY_U3P_CPU_SOCKET_CONS; //消费者
143 dmaConfig.dmaMode CY_U3P_DMA_MODE_BYTE;
144 dmaConfig.notification CY_U3P_DMA_CB_PROD_EVENT; //缓冲区充满产生的事件此事件触发回调函数
145 dmaConfig.cb ReceivedDataCallBack;
146 dmaConfig.prodHeader 0;
147 dmaConfig.prodFooter 0;
148 dmaConfig.consHeader 0;
149 dmaConfig.prodAvailCount 0;
150 /* Create the channel */
151 apiRetStatus CyU3PDmaChannelCreate (glUartRXChHandle,
152 CY_U3P_DMA_TYPE_MANUAL_IN, dmaConfig);
153
154 if (apiRetStatus ! CY_U3P_SUCCESS)
155 {
156 /* Error handling */
157 CyFxAppErrorHandler(apiRetStatus);
158 }
159
160 dmaConfig.size CY_FX_UART_DMA_BUF_SIZE;
161 dmaConfig.count 1;
162 dmaConfig.prodSckId CY_U3P_CPU_SOCKET_PROD; //生产者CPU
163 dmaConfig.consSckId CY_U3P_LPP_SOCKET_UART_CONS; //消费者为TX
164 dmaConfig.dmaMode CY_U3P_DMA_MODE_BYTE;
165 dmaConfig.notification 0;
166 dmaConfig.cb NULL;
167 dmaConfig.prodHeader 0;
168 dmaConfig.prodFooter 0;
169 dmaConfig.consHeader 0;
170 dmaConfig.prodAvailCount 0;
171
172 /* Create the channel */
173 apiRetStatus CyU3PDmaChannelCreate (glUartTXChHandle,
174 CY_U3P_DMA_TYPE_MANUAL_OUT, dmaConfig);
175
176 if (apiRetStatus ! CY_U3P_SUCCESS)
177 {
178 /* Error handling */
179 CyFxAppErrorHandler(apiRetStatus);
180 }
181 /* Set UART Tx and Rx transfer Size to infinite */
182 apiRetStatus CyU3PUartTxSetBlockXfer(0xFFFFFFFF);
183 if (apiRetStatus ! CY_U3P_SUCCESS)
184 {
185 /* Error handling */
186 CyFxAppErrorHandler(apiRetStatus);
187 }
188
189 apiRetStatus CyU3PUartRxSetBlockXfer(0xFFFFFFFF);
190 if (apiRetStatus ! CY_U3P_SUCCESS)
191 {
192 /* Error handling */
193 CyFxAppErrorHandler(apiRetStatus);
194 }
195
196 /* Set DMA Channel transfer size */
197 apiRetStatus CyU3PDmaChannelSetXfer (glUartRXChHandle, 0);
198 if (apiRetStatus ! CY_U3P_SUCCESS)
199 {
200 /* Error handling */
201 CyFxAppErrorHandler(apiRetStatus);
202 }
203
204 apiRetStatus CyU3PDmaChannelSetXfer (glUartTXChHandle, 0);
205 if (apiRetStatus ! CY_U3P_SUCCESS)
206 {
207 /* Error handling */
208 CyFxAppErrorHandler(apiRetStatus);
209 }
210 }
211
212 /* Entry function for the UartLpAppThread */
213 void
214 UartLpAppThread_Entry (
215 uint32_t input)
216 {
217 /* Initialize the UART Example Application */
218 CyFxUartDMAlnInit();
219
220 //uint8_t testBuffer[8] {0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8};
221 for (;;)
222 {
223
224 //if中的语句是为了接收完毕后清除缓冲区如果不清除缓冲区如果所发数据超过缓冲区长度第二次发送时会将上次未发送完的数据发送过来。
225 if(ClearFlag 1)
226 {
227 //SendData(glRxBuffer-buffer, 16);
228 CyU3PDmaChannelReset(glUartRXChHandle);
229 CyU3PThreadSleep(10);
230 CyU3PDmaChannelSetXfer(glUartRXChHandle,0);
231 ClearFlag 0;
232 }
233 /* No operation in the thread */
234 CyU3PThreadSleep (100);
235 }
236 }
237
238 /* Application define function which creates the threads. */
239 void
240 CyFxApplicationDefine (
241 void)
242 {
243 void *ptr NULL;
244 uint32_t retThrdCreate CY_U3P_SUCCESS;
245
246 /* Allocate the memory for the threads */
247 ptr CyU3PMemAlloc (CY_FX_UARTLP_THREAD_STACK);
248
249 /* Create the thread for the application */
250 retThrdCreate CyU3PThreadCreate (UartLpAppThread, /* UART Example App Thread structure */
251 21:UART_loopback_DMA_mode, /* Thread ID and Thread name */
252 UartLpAppThread_Entry, /* UART Example App Thread Entry function */
253 0, /* No input parameter to thread */
254 ptr, /* Pointer to the allocated thread stack */
255 CY_FX_UARTLP_THREAD_STACK, /* UART Example App Thread stack size */
256 CY_FX_UARTLP_THREAD_PRIORITY, /* UART Example App Thread priority */
257 CY_FX_UARTLP_THREAD_PRIORITY, /* UART Example App Thread priority */
258 CYU3P_NO_TIME_SLICE, /* No time slice for the application thread */
259 CYU3P_AUTO_START /* Start the Thread immediately */
260 );
261
262 /* Check the return code */
263 if (retThrdCreate ! 0)
264 {
265 /* Thread Creation failed with the error code retThrdCreate */
266
267 /* Add custom recovery or debug actions here */
268
269 /* Application cannot continue */
270 /* Loop indefinitely */
271 while(1);
272 }
273 }
274
275 /*
276 * Main function
277 */
278 int
279 main (void)
280 {
281 CyU3PIoMatrixConfig_t io_cfg;
282 CyU3PReturnStatus_t status CY_U3P_SUCCESS;
283
284 /* Initialize the device */
285 status CyU3PDeviceInit (0);
286 if (status ! CY_U3P_SUCCESS)
287 {
288 goto handle_fatal_error;
289 }
290
291 /* Initialize the caches. Enable both Instruction and Data Caches. */
292 status CyU3PDeviceCacheControl (CyTrue, CyTrue, CyTrue);
293 if (status ! CY_U3P_SUCCESS)
294 {
295 goto handle_fatal_error;
296 }
297
298 /* Configure the IO matrix for the device. On the FX3 DVK board, the COM port
299 * is connected to the IO(53:56). This means that either DQ32 mode should be
300 * selected or lppMode should be set to UART_ONLY. Here we are choosing
301 * UART_ONLY configuration. */
302 CyU3PMemSet ((uint8_t *)io_cfg, 0, sizeof(io_cfg));
303 io_cfg.isDQ32Bit CyFalse;
304 io_cfg.s0Mode CY_U3P_SPORT_INACTIVE;
305 io_cfg.s1Mode CY_U3P_SPORT_INACTIVE;
306 io_cfg.useUart CyTrue;
307 io_cfg.useI2C CyFalse;
308 io_cfg.useI2S CyFalse;
309 io_cfg.useSpi CyFalse;
310 io_cfg.lppMode CY_U3P_IO_MATRIX_LPP_UART_ONLY;
311 /* No GPIOs are enabled. */
312 io_cfg.gpioSimpleEn[0] 0;
313 io_cfg.gpioSimpleEn[1] 0;
314 io_cfg.gpioComplexEn[0] 0;
315 io_cfg.gpioComplexEn[1] 0;
316 status CyU3PDeviceConfigureIOMatrix (io_cfg);
317 if (status ! CY_U3P_SUCCESS)
318 {
319 goto handle_fatal_error;
320 }
321
322 /* This is a non returnable call for initializing the RTOS kernel */
323 CyU3PKernelEntry ();
324
325 /* Dummy return to make the compiler happy */
326 return 0;
327
328 handle_fatal_error:
329 /* Cannot recover from this error. */
330 while (1);
331
332 } 实验效果能够实现发送和接收FX3将接收到的数据再发送给主机如图 将110行的 SendData(glRxBuffer-buffer, 16);改为111行的SendData(testBuffer, 16);能够实现接收16位数据后将testBuffer中的数据返回给主机效果如图 需要注意的是DMA_BUFFER_SIZE的大小必须为16的倍数最小为16也就是说一次至少需要发送或者接收16个字节的数据或者说是将缓冲区填满的数据 转载于:https://www.cnblogs.com/Lxk0825/p/9632830.html