1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "../../include/linux/westbridge/cyashal.h"
23#include "../../include/linux/westbridge/cyasdma.h"
24#include "../../include/linux/westbridge/cyaslowlevel.h"
25#include "../../include/linux/westbridge/cyaserr.h"
26#include "../../include/linux/westbridge/cyasregs.h"
27
28
29
30
31static void
32cy_as_dma_add_request_to_free_queue(cy_as_device *dev_p,
33 cy_as_dma_queue_entry *req_p)
34{
35 uint32_t imask;
36 imask = cy_as_hal_disable_interrupts();
37
38 req_p->next_p = dev_p->dma_freelist_p;
39 dev_p->dma_freelist_p = req_p;
40
41 cy_as_hal_enable_interrupts(imask);
42}
43
44
45
46
47static cy_as_dma_queue_entry *
48cy_as_dma_get_dma_queue_entry(cy_as_device *dev_p)
49{
50 cy_as_dma_queue_entry *req_p;
51 uint32_t imask;
52
53 cy_as_hal_assert(dev_p->dma_freelist_p != 0);
54
55 imask = cy_as_hal_disable_interrupts();
56 req_p = dev_p->dma_freelist_p;
57 dev_p->dma_freelist_p = req_p->next_p;
58 cy_as_hal_enable_interrupts(imask);
59
60 return req_p;
61}
62
63
64
65
66
67
68
69
70cy_as_return_status_t
71cy_as_dma_set_max_dma_size(cy_as_device *dev_p,
72 cy_as_end_point_number_t ep, uint32_t size)
73{
74
75 if ((!dev_p->is_mtp_firmware) || (ep != 0x02)) {
76 if (size < 64 || size > 1024)
77 return CY_AS_ERROR_INVALID_SIZE;
78 }
79
80 CY_AS_NUM_EP(dev_p, ep)->maxhwdata = (uint16_t)size;
81 return CY_AS_ERROR_SUCCESS;
82}
83
84
85
86
87
88
89
90
91static void
92cy_as_dma_request_callback(
93 cy_as_device *dev_p,
94 uint8_t context,
95 cy_as_ll_request_response *req_p,
96 cy_as_ll_request_response *resp_p,
97 cy_as_return_status_t ret)
98{
99 uint16_t v;
100 uint16_t datacnt;
101 cy_as_end_point_number_t ep;
102
103 (void)context;
104
105 cy_as_log_debug_message(5, "cy_as_dma_request_callback called");
106
107
108
109
110 if (ret == CY_AS_ERROR_SUCCESS) {
111 if (cy_as_ll_request_response__get_code(resp_p) !=
112 CY_RESP_SUCCESS_FAILURE)
113 ret = CY_AS_ERROR_INVALID_RESPONSE;
114 else
115 ret = cy_as_ll_request_response__get_word(resp_p, 0);
116 }
117
118
119
120
121
122 v = cy_as_ll_request_response__get_word(req_p, 0);
123 ep = (cy_as_end_point_number_t)((v >> 13) & 0x01);
124
125 if (ret == CY_AS_ERROR_SUCCESS) {
126
127
128
129
130
131
132 datacnt = v & 0x3FF;
133 } else {
134
135
136
137 datacnt = 0;
138 }
139
140
141
142
143
144 if (ep == 0) {
145 dev_p->usb_ep0_dma_req = req_p;
146 dev_p->usb_ep0_dma_resp = resp_p;
147 } else {
148 dev_p->usb_ep1_dma_req = req_p;
149 dev_p->usb_ep1_dma_resp = resp_p;
150 }
151
152
153
154
155
156
157
158
159
160
161 if (ret != CY_AS_ERROR_CANCELED)
162 cy_as_dma_completed_callback(dev_p->tag, ep, datacnt, ret);
163}
164
165
166
167
168
169
170static void
171cy_as_dma_set_drq(cy_as_device *dev_p,
172 cy_as_end_point_number_t ep, cy_bool state)
173{
174 uint16_t mask;
175 uint16_t v;
176 uint32_t intval;
177
178
179
180
181 if (ep == 0 || ep == 1)
182 return;
183
184
185
186
187
188 intval = cy_as_hal_disable_interrupts();
189
190
191
192
193 mask = (1 << ep);
194 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK);
195
196 if (state)
197 v |= mask;
198 else
199 v &= ~mask;
200
201 cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK, v);
202 cy_as_hal_enable_interrupts(intval);
203}
204
205
206
207
208static void
209cy_as_dma_send_next_dma_request(cy_as_device *dev_p, cy_as_dma_end_point *ep_p)
210{
211 uint32_t datacnt;
212 void *buf_p;
213 cy_as_dma_queue_entry *dma_p;
214
215 cy_as_log_debug_message(6, "cy_as_dma_send_next_dma_request called");
216
217
218 dma_p = ep_p->queue_p;
219 if (dma_p == 0) {
220
221
222
223
224
225
226
227 cy_as_dma_set_drq(dev_p, ep_p->ep, cy_false);
228 return;
229 }
230
231 cy_as_dma_end_point_set_running(ep_p);
232
233
234
235
236
237 datacnt = dma_p->size - dma_p->offset;
238 cy_as_hal_assert(datacnt >= 0);
239
240
241
242
243
244
245
246 cy_as_hal_assert(ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE
247 || ep_p->maxhaldata >= ep_p->maxhwdata);
248
249
250
251
252
253 if (ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE) {
254 if (datacnt > ep_p->maxhwdata)
255 datacnt = ep_p->maxhwdata;
256 } else {
257 if (datacnt > ep_p->maxhaldata)
258 datacnt = ep_p->maxhaldata;
259 }
260
261
262
263
264 buf_p = (((char *)dma_p->buf_p) + dma_p->offset);
265
266
267
268
269 cy_as_dma_end_point_set_in_transit(ep_p);
270
271 if (ep_p->ep == 0 || ep_p->ep == 1) {
272
273
274
275
276
277
278
279
280
281
282 if (dma_p->readreq == cy_false) {
283 uint16_t v;
284 uint16_t len;
285 cy_as_ll_request_response *resp_p;
286 cy_as_ll_request_response *req_p;
287 cy_as_return_status_t ret;
288
289 len = (uint16_t)(datacnt / 2);
290 if (datacnt % 2)
291 len++;
292
293 len++;
294
295 if (ep_p->ep == 0) {
296 req_p = dev_p->usb_ep0_dma_req;
297 resp_p = dev_p->usb_ep0_dma_resp;
298 dev_p->usb_ep0_dma_req = 0;
299 dev_p->usb_ep0_dma_resp = 0;
300 } else {
301 req_p = dev_p->usb_ep1_dma_req;
302 resp_p = dev_p->usb_ep1_dma_resp;
303 dev_p->usb_ep1_dma_req = 0;
304 dev_p->usb_ep1_dma_resp = 0;
305 }
306
307 cy_as_hal_assert(req_p != 0);
308 cy_as_hal_assert(resp_p != 0);
309 cy_as_hal_assert(len <= 64);
310
311 cy_as_ll_init_request(req_p, CY_RQT_USB_EP_DATA,
312 CY_RQT_USB_RQT_CONTEXT, len);
313
314 v = (uint16_t)(datacnt | (ep_p->ep << 13) | (1 << 14));
315 if (dma_p->offset == 0)
316 v |= (1 << 12);
317 if (dma_p->offset + datacnt == dma_p->size)
318 v |= (1 << 11);
319
320 cy_as_ll_request_response__set_word(req_p, 0, v);
321 cy_as_ll_request_response__pack(req_p,
322 1, datacnt, buf_p);
323
324 cy_as_ll_init_response(resp_p, 1);
325
326 ret = cy_as_ll_send_request(dev_p, req_p, resp_p,
327 cy_false, cy_as_dma_request_callback);
328 if (ret == CY_AS_ERROR_SUCCESS)
329 cy_as_log_debug_message(5,
330 "+++ send EP 0/1 data via mailbox registers");
331 else
332 cy_as_log_debug_message(5,
333 "+++ error sending EP 0/1 data via mailbox "
334 "registers - CY_AS_ERROR_TIMEOUT");
335
336 if (ret != CY_AS_ERROR_SUCCESS)
337 cy_as_dma_completed_callback(dev_p->tag,
338 ep_p->ep, 0, ret);
339 }
340 } else {
341
342
343
344
345
346
347
348
349
350
351
352
353
354 if (cy_as_dma_end_point_is_direction_in(ep_p))
355 cy_as_hal_dma_setup_write(dev_p->tag,
356 ep_p->ep, buf_p, datacnt, ep_p->maxhwdata);
357 else
358 cy_as_hal_dma_setup_read(dev_p->tag,
359 ep_p->ep, buf_p, datacnt, ep_p->maxhwdata);
360
361
362
363
364
365 cy_as_dma_set_drq(dev_p, ep_p->ep, cy_true);
366 }
367}
368
369
370
371
372
373
374
375
376void
377cy_as_dma_completed_callback(cy_as_hal_device_tag tag,
378 cy_as_end_point_number_t ep, uint32_t cnt, cy_as_return_status_t status)
379{
380 uint32_t mask;
381 cy_as_dma_queue_entry *req_p;
382 cy_as_dma_end_point *ep_p;
383 cy_as_device *dev_p = cy_as_device_find_from_tag(tag);
384
385
386 cy_as_hal_assert(dev_p != 0);
387 cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
388 cy_as_hal_assert(ep < 16);
389
390
391
392 ep_p = CY_AS_NUM_EP(dev_p, ep);
393 cy_as_hal_assert(ep_p->queue_p != 0);
394
395
396 mask = cy_as_hal_disable_interrupts();
397 req_p = ep_p->queue_p;
398
399
400 req_p->offset += cnt;
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 if (((req_p->offset != req_p->size) && (req_p->packet == cy_false) &&
421 ((cnt == ep_p->maxhaldata) || ((cnt == ep_p->maxhwdata) &&
422 ((ep != CY_AS_MTP_READ_ENDPOINT) ||
423 (cnt == dev_p->usb_max_tx_size)))))
424 || ((ep == 1) && (status == CY_AS_ERROR_TIMEOUT))) {
425 cy_as_hal_enable_interrupts(mask);
426
427
428
429
430
431
432
433 if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || (
434 (ep == CY_AS_MTP_READ_ENDPOINT) &&
435 (!cy_as_dma_end_point_is_direction_in(ep_p))))
436 cy_as_dma_end_point_set_stopped(ep_p);
437 else
438 cy_as_dma_send_next_dma_request(dev_p, ep_p);
439 } else {
440
441
442
443
444
445
446
447
448
449
450
451
452 cy_as_dma_end_point_clear_in_transit(ep_p);
453 ep_p->queue_p = req_p->next_p;
454 if (ep_p->last_p == req_p) {
455
456
457
458
459 ep_p->last_p = 0;
460 cy_as_hal_enable_interrupts(mask);
461 cy_as_dma_set_drq(dev_p, ep, cy_false);
462 } else
463 cy_as_hal_enable_interrupts(mask);
464
465 if (req_p->cb) {
466
467
468
469
470
471
472
473
474
475 cy_as_device_set_in_callback(dev_p);
476 (*req_p->cb)(dev_p, ep, req_p->buf_p,
477 req_p->offset, status);
478 cy_as_device_clear_in_callback(dev_p);
479 }
480
481
482
483
484
485 cy_as_dma_add_request_to_free_queue(dev_p, req_p);
486
487 if (ep_p->queue_p == 0) {
488
489
490
491
492 cy_as_dma_end_point_set_stopped(ep_p);
493
494
495
496
497
498 if (cy_as_dma_end_point_is_sleeping(ep_p)) {
499 cy_as_dma_end_point_set_wake_state(ep_p);
500 cy_as_hal_wake(&ep_p->channel);
501 }
502 } else {
503
504
505
506
507
508 if ((ep == CY_AS_MTP_WRITE_ENDPOINT) ||
509 ((ep == CY_AS_MTP_READ_ENDPOINT) &&
510 (!cy_as_dma_end_point_is_direction_in(ep_p))) ||
511 ((ep == dev_p->storage_read_endpoint) &&
512 (!cy_as_device_is_p2s_dma_start_recvd(dev_p)))
513 || ((ep == dev_p->storage_write_endpoint) &&
514 (!cy_as_device_is_p2s_dma_start_recvd(dev_p))))
515 cy_as_dma_end_point_set_stopped(ep_p);
516 else
517 cy_as_dma_send_next_dma_request(dev_p, ep_p);
518 }
519 }
520}
521
522
523
524
525
526
527
528
529cy_as_return_status_t
530cy_as_dma_kick_start(cy_as_device *dev_p, cy_as_end_point_number_t ep)
531{
532 cy_as_dma_end_point *ep_p;
533 cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
534
535 ep_p = CY_AS_NUM_EP(dev_p, ep);
536
537
538 if (cy_as_dma_end_point_is_running(ep_p))
539 return CY_AS_ERROR_SUCCESS;
540
541 cy_as_dma_send_next_dma_request(dev_p, ep_p);
542 return CY_AS_ERROR_SUCCESS;
543}
544
545
546
547
548
549
550static cy_as_return_status_t
551cy_as_dma_stop_end_point(cy_as_device *dev_p, cy_as_end_point_number_t ep)
552{
553 cy_as_return_status_t ret;
554 cy_as_dma_end_point *ep_p = CY_AS_NUM_EP(dev_p, ep);
555
556
557
558
559
560
561 ret = cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
562 if (ret != CY_AS_ERROR_SUCCESS)
563 return ret;
564
565
566
567
568 if (!cy_as_hal_destroy_sleep_channel(&ep_p->channel)
569 && ret == CY_AS_ERROR_SUCCESS)
570 ret = CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED;
571
572
573
574
575 cy_as_hal_free(ep_p);
576
577
578
579
580
581 dev_p->endp[ep] = 0;
582
583 return ret;
584}
585
586
587
588
589
590
591static cy_as_return_status_t
592cy_as_dma_stop_internal(cy_as_device *dev_p)
593{
594 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
595 cy_as_return_status_t lret;
596 cy_as_end_point_number_t i;
597
598
599
600
601
602 for (i = 0; i < sizeof(dev_p->endp)/(sizeof(dev_p->endp[0])); i++) {
603 lret = cy_as_dma_stop_end_point(dev_p, i);
604 if (lret != CY_AS_ERROR_SUCCESS && ret == CY_AS_ERROR_SUCCESS)
605 ret = lret;
606 }
607
608
609
610
611
612 while (dev_p->dma_freelist_p) {
613 cy_as_dma_queue_entry *req_p;
614 uint32_t imask = cy_as_hal_disable_interrupts();
615
616 req_p = dev_p->dma_freelist_p;
617 dev_p->dma_freelist_p = req_p->next_p;
618
619 cy_as_hal_enable_interrupts(imask);
620
621 cy_as_hal_free(req_p);
622 }
623
624 cy_as_ll_destroy_request(dev_p, dev_p->usb_ep0_dma_req);
625 cy_as_ll_destroy_request(dev_p, dev_p->usb_ep1_dma_req);
626 cy_as_ll_destroy_response(dev_p, dev_p->usb_ep0_dma_resp);
627 cy_as_ll_destroy_response(dev_p, dev_p->usb_ep1_dma_resp);
628
629 return ret;
630}
631
632
633
634
635
636
637
638
639
640
641
642cy_as_return_status_t
643cy_as_dma_stop(cy_as_device *dev_p)
644{
645 cy_as_return_status_t ret;
646
647 ret = cy_as_dma_stop_internal(dev_p);
648 cy_as_device_set_dma_stopped(dev_p);
649
650 return ret;
651}
652
653
654
655
656
657
658cy_as_return_status_t
659cy_as_dma_start(cy_as_device *dev_p)
660{
661 cy_as_end_point_number_t i;
662 uint16_t cnt;
663
664 if (cy_as_device_is_dma_running(dev_p))
665 return CY_AS_ERROR_ALREADY_RUNNING;
666
667
668
669
670 for (cnt = 0; cnt < 32; cnt++) {
671 cy_as_dma_queue_entry *entry_p = (cy_as_dma_queue_entry *)
672 cy_as_hal_alloc(sizeof(cy_as_dma_queue_entry));
673 if (entry_p == 0) {
674 cy_as_dma_stop_internal(dev_p);
675 return CY_AS_ERROR_OUT_OF_MEMORY;
676 }
677 cy_as_dma_add_request_to_free_queue(dev_p, entry_p);
678 }
679
680
681
682
683
684 dev_p->usb_ep0_dma_req = cy_as_ll_create_request(dev_p,
685 CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64);
686 dev_p->usb_ep1_dma_req = cy_as_ll_create_request(dev_p,
687 CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64);
688
689 if (dev_p->usb_ep0_dma_req == 0 || dev_p->usb_ep1_dma_req == 0) {
690 cy_as_dma_stop_internal(dev_p);
691 return CY_AS_ERROR_OUT_OF_MEMORY;
692 }
693 dev_p->usb_ep0_dma_req_save = dev_p->usb_ep0_dma_req;
694
695 dev_p->usb_ep0_dma_resp = cy_as_ll_create_response(dev_p, 1);
696 dev_p->usb_ep1_dma_resp = cy_as_ll_create_response(dev_p, 1);
697 if (dev_p->usb_ep0_dma_resp == 0 || dev_p->usb_ep1_dma_resp == 0) {
698 cy_as_dma_stop_internal(dev_p);
699 return CY_AS_ERROR_OUT_OF_MEMORY;
700 }
701 dev_p->usb_ep0_dma_resp_save = dev_p->usb_ep0_dma_resp;
702
703
704
705
706
707 cy_as_hal_mem_set(dev_p->endp, 0, sizeof(dev_p->endp));
708
709
710
711
712
713 for (i = 0; i < sizeof(dev_p->endp)/sizeof(dev_p->endp[0]); i++) {
714 dev_p->endp[i] = (cy_as_dma_end_point *)
715 cy_as_hal_alloc(sizeof(cy_as_dma_end_point));
716 if (dev_p->endp[i] == 0) {
717 cy_as_dma_stop_internal(dev_p);
718 return CY_AS_ERROR_OUT_OF_MEMORY;
719 }
720 cy_as_hal_mem_set(dev_p->endp[i], 0,
721 sizeof(cy_as_dma_end_point));
722
723 dev_p->endp[i]->ep = i;
724 dev_p->endp[i]->queue_p = 0;
725 dev_p->endp[i]->last_p = 0;
726
727 cy_as_dma_set_drq(dev_p, i, cy_false);
728
729 if (!cy_as_hal_create_sleep_channel(&dev_p->endp[i]->channel))
730 return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED;
731 }
732
733
734
735
736
737 cy_as_hal_dma_register_callback(dev_p->tag,
738 cy_as_dma_completed_callback);
739
740
741
742
743 cy_as_device_set_dma_running(dev_p);
744
745 return CY_AS_ERROR_SUCCESS;
746}
747
748
749
750
751
752
753
754cy_as_return_status_t
755cy_as_dma_drain_queue(cy_as_device *dev_p,
756 cy_as_end_point_number_t ep, cy_bool kickstart)
757{
758 cy_as_dma_end_point *ep_p;
759 int loopcount = 1000;
760 uint32_t mask;
761
762
763
764
765 if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
766 return CY_AS_ERROR_INVALID_ENDPOINT;
767
768
769 ep_p = CY_AS_NUM_EP(dev_p, ep);
770
771
772
773
774
775 mask = cy_as_hal_disable_interrupts();
776 if (ep_p->queue_p == 0) {
777 cy_as_hal_enable_interrupts(mask);
778 return CY_AS_ERROR_SUCCESS;
779 } else {
780
781
782
783
784 if (ep_p->queue_p->size > 0x10000)
785 loopcount += ((ep_p->queue_p->size / 0x10000) * 1000);
786 }
787 cy_as_hal_enable_interrupts(mask);
788
789
790 if (cy_as_dma_end_point_is_sleeping(ep_p))
791 return CY_AS_ERROR_NESTED_SLEEP;
792
793
794
795
796
797 cy_as_dma_enable_end_point(dev_p, ep,
798 cy_false, cy_as_direction_dont_change);
799
800 if (kickstart) {
801
802
803
804 cy_as_dma_kick_start(dev_p, ep);
805 }
806
807
808
809
810
811 if (ep_p->queue_p == 0) {
812 cy_as_dma_enable_end_point(dev_p, ep, cy_true,
813 cy_as_direction_dont_change);
814 return CY_AS_ERROR_SUCCESS;
815 }
816
817 while (loopcount-- > 0) {
818
819
820
821
822 cy_as_dma_end_point_set_sleep_state(ep_p);
823 cy_as_hal_sleep_on(&ep_p->channel, 10);
824
825
826 cy_as_dma_end_point_set_wake_state(ep_p);
827
828
829 if (ep_p->queue_p == 0) {
830
831
832
833
834 cy_as_dma_end_point_clear_in_transit(ep_p);
835 cy_as_dma_end_point_set_stopped(ep_p);
836
837 cy_as_dma_enable_end_point(dev_p, ep,
838 cy_true, cy_as_direction_dont_change);
839 return CY_AS_ERROR_SUCCESS;
840 }
841 }
842
843
844
845
846
847 cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_TIMEOUT);
848 cy_as_dma_enable_end_point(dev_p, ep,
849 cy_true, cy_as_direction_dont_change);
850 return CY_AS_ERROR_TIMEOUT;
851}
852
853
854
855
856
857
858cy_as_return_status_t
859cy_as_dma_queue_request(cy_as_device *dev_p,
860 cy_as_end_point_number_t ep, void *mem_p,
861 uint32_t size, cy_bool pkt, cy_bool readreq, cy_as_dma_callback cb)
862{
863 uint32_t mask;
864 cy_as_dma_queue_entry *entry_p;
865 cy_as_dma_end_point *ep_p;
866
867
868
869
870 if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
871 return CY_AS_ERROR_INVALID_ENDPOINT;
872
873
874 ep_p = CY_AS_NUM_EP(dev_p, ep);
875
876 if (!cy_as_dma_end_point_is_enabled(ep_p))
877 return CY_AS_ERROR_ENDPOINT_DISABLED;
878
879 entry_p = cy_as_dma_get_dma_queue_entry(dev_p);
880
881 entry_p->buf_p = mem_p;
882 entry_p->cb = cb;
883 entry_p->size = size;
884 entry_p->offset = 0;
885 entry_p->packet = pkt;
886 entry_p->readreq = readreq;
887
888 mask = cy_as_hal_disable_interrupts();
889 entry_p->next_p = 0;
890 if (ep_p->last_p)
891 ep_p->last_p->next_p = entry_p;
892 ep_p->last_p = entry_p;
893 if (ep_p->queue_p == 0)
894 ep_p->queue_p = entry_p;
895 cy_as_hal_enable_interrupts(mask);
896
897 return CY_AS_ERROR_SUCCESS;
898}
899
900
901
902
903
904
905cy_as_return_status_t
906cy_as_dma_enable_end_point(cy_as_device *dev_p,
907 cy_as_end_point_number_t ep, cy_bool enable, cy_as_dma_direction dir)
908{
909 cy_as_dma_end_point *ep_p;
910
911
912
913
914 if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
915 return CY_AS_ERROR_INVALID_ENDPOINT;
916
917
918 ep_p = CY_AS_NUM_EP(dev_p, ep);
919
920 if (dir == cy_as_direction_out)
921 cy_as_dma_end_point_set_direction_out(ep_p);
922 else if (dir == cy_as_direction_in)
923 cy_as_dma_end_point_set_direction_in(ep_p);
924
925
926
927
928
929
930
931
932
933
934
935
936
937 if (ep == 0 || ep == 1)
938 ep_p->maxhaldata = 64;
939 else
940 ep_p->maxhaldata = cy_as_hal_dma_max_request_size(
941 dev_p->tag, ep);
942
943 if (enable)
944 cy_as_dma_end_point_enable(ep_p);
945 else
946 cy_as_dma_end_point_disable(ep_p);
947
948 return CY_AS_ERROR_SUCCESS;
949}
950
951
952
953
954
955cy_as_return_status_t
956cy_as_dma_cancel(
957 cy_as_device *dev_p,
958 cy_as_end_point_number_t ep,
959 cy_as_return_status_t err)
960{
961 uint32_t mask;
962 cy_as_dma_end_point *ep_p;
963 cy_as_dma_queue_entry *entry_p;
964 cy_bool epstate;
965
966
967
968
969 if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
970 return CY_AS_ERROR_INVALID_ENDPOINT;
971
972
973 ep_p = CY_AS_NUM_EP(dev_p, ep);
974
975 if (ep_p) {
976
977 epstate = cy_as_dma_end_point_is_enabled(ep_p);
978
979
980
981
982
983 cy_as_dma_enable_end_point(dev_p, ep,
984 cy_false, cy_as_direction_dont_change);
985
986
987
988
989
990
991 cy_as_dma_set_drq(dev_p, ep, cy_false);
992
993
994
995
996 if (cy_as_dma_end_point_in_transit(ep_p))
997 cy_as_hal_dma_cancel_request(dev_p->tag, ep_p->ep);
998
999
1000
1001
1002
1003 cy_as_dma_end_point_set_stopped(ep_p);
1004
1005
1006
1007
1008
1009 cy_as_dma_end_point_clear_in_transit(ep_p);
1010
1011
1012
1013
1014
1015
1016 ep_p->last_p = 0;
1017 while (ep_p->queue_p != 0) {
1018
1019 mask = cy_as_hal_disable_interrupts();
1020
1021
1022 entry_p = ep_p->queue_p;
1023 ep_p->queue_p = entry_p->next_p;
1024
1025
1026
1027 cy_as_hal_enable_interrupts(mask);
1028
1029
1030
1031 if (entry_p->cb)
1032 entry_p->cb(dev_p, ep,
1033 entry_p->buf_p, entry_p->size, err);
1034
1035 cy_as_dma_add_request_to_free_queue(dev_p, entry_p);
1036 }
1037
1038 if (ep == 0 || ep == 1) {
1039
1040
1041
1042
1043
1044
1045 cy_as_ll_remove_ep_data_requests(dev_p, ep);
1046 }
1047
1048 if (epstate) {
1049
1050
1051
1052
1053 cy_as_dma_enable_end_point(dev_p, ep,
1054 cy_true, cy_as_direction_dont_change);
1055 }
1056 }
1057
1058 return CY_AS_ERROR_SUCCESS;
1059}
1060
1061cy_as_return_status_t
1062cy_as_dma_received_data(cy_as_device *dev_p,
1063 cy_as_end_point_number_t ep, uint32_t dsize, void *data)
1064{
1065 cy_as_dma_queue_entry *dma_p;
1066 uint8_t *src_p, *dest_p;
1067 cy_as_dma_end_point *ep_p;
1068 uint32_t xfersize;
1069
1070
1071
1072
1073 if (ep != 0 && ep != 1)
1074 return CY_AS_ERROR_INVALID_ENDPOINT;
1075
1076
1077 ep_p = CY_AS_NUM_EP(dev_p, ep);
1078 dma_p = ep_p->queue_p;
1079 if (dma_p == 0)
1080 return CY_AS_ERROR_SUCCESS;
1081
1082
1083
1084
1085
1086
1087
1088 if (dsize > dma_p->size - dma_p->offset)
1089 dsize = dma_p->size - dma_p->offset;
1090
1091
1092
1093
1094
1095 src_p = (uint8_t *)data;
1096 dest_p = ((uint8_t *)(dma_p->buf_p)) + dma_p->offset;
1097 xfersize = dsize;
1098 while (xfersize-- > 0)
1099 *dest_p++ = *src_p++;
1100
1101
1102
1103 cy_as_dma_completed_callback(dev_p->tag,
1104 ep, dsize, CY_AS_ERROR_SUCCESS);
1105
1106 return CY_AS_ERROR_SUCCESS;
1107}
1108