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/cyasmisc.h"
24#include "../../include/linux/westbridge/cyasdma.h"
25#include "../../include/linux/westbridge/cyasintr.h"
26#include "../../include/linux/westbridge/cyaserr.h"
27#include "../../include/linux/westbridge/cyasregs.h"
28#include "../../include/linux/westbridge/cyaslowlevel.h"
29#include "../../include/linux/westbridge/cyasprotocol.h"
30
31
32
33
34static cy_as_device *g_device_list;
35
36
37
38
39static uint8_t debug_level;
40
41
42
43
44
45void
46cy_as_misc_set_log_level(uint8_t level)
47{
48 debug_level = level;
49}
50
51#ifdef CY_AS_LOG_SUPPORT
52
53
54
55
56void
57cy_as_log_debug_message(int level, const char *str)
58{
59 if (level <= debug_level)
60 cy_as_hal_print_message("log %d: %s\n", level, str);
61}
62
63#endif
64
65#define cy_as_check_device_ready(dev_p) \
66{\
67 if (!(dev_p) || ((dev_p)->sig != \
68 CY_AS_DEVICE_HANDLE_SIGNATURE)) \
69 return CY_AS_ERROR_INVALID_HANDLE; \
70\
71 if (!cy_as_device_is_configured(dev_p)) \
72 return CY_AS_ERROR_NOT_CONFIGURED; \
73\
74 if (!cy_as_device_is_firmware_loaded(dev_p))\
75 return CY_AS_ERROR_NO_FIRMWARE; \
76}
77
78
79cy_as_device *
80cy_as_device_find_from_tag(cy_as_hal_device_tag tag)
81{
82 cy_as_device *dev_p;
83
84 for (dev_p = g_device_list; dev_p != 0; dev_p = dev_p->next_p) {
85 if (dev_p->tag == tag)
86 return dev_p;
87 }
88
89 return 0;
90}
91
92
93static void
94cy_as_bus_from_media_type(cy_as_media_type type,
95 cy_as_bus_number_t *bus)
96{
97 if (type == cy_as_media_nand)
98 *bus = 0;
99 else
100 *bus = 1;
101}
102
103static cy_as_return_status_t
104my_handle_response_no_data(cy_as_device *dev_p,
105 cy_as_ll_request_response *req_p,
106 cy_as_ll_request_response *reply_p)
107{
108 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
109
110 if (cy_as_ll_request_response__get_code(reply_p) !=
111 CY_RESP_SUCCESS_FAILURE)
112 ret = CY_AS_ERROR_INVALID_RESPONSE;
113 else
114 ret = cy_as_ll_request_response__get_word(reply_p, 0);
115
116 cy_as_ll_destroy_request(dev_p, req_p);
117 cy_as_ll_destroy_response(dev_p, reply_p);
118
119 return ret;
120}
121
122
123
124
125cy_as_return_status_t
126cy_as_misc_create_device(cy_as_device_handle *handle_p,
127 cy_as_hal_device_tag tag)
128{
129 cy_as_device *dev_p;
130 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
131
132 cy_as_log_debug_message(6, "cy_as_misc_create_device called");
133
134 dev_p = (cy_as_device *)cy_as_hal_alloc(sizeof(cy_as_device));
135 if (dev_p == 0)
136 return CY_AS_ERROR_OUT_OF_MEMORY;
137 cy_as_hal_mem_set(dev_p, 0, sizeof(cy_as_device));
138
139
140
141
142
143 dev_p->usb_ep_data = (uint8_t *)cy_as_hal_alloc(64 * sizeof(uint8_t));
144 if (dev_p->usb_ep_data == 0) {
145 cy_as_hal_free(dev_p);
146 return CY_AS_ERROR_OUT_OF_MEMORY;
147 }
148
149 dev_p->sig = CY_AS_DEVICE_HANDLE_SIGNATURE;
150 dev_p->tag = tag;
151 dev_p->usb_max_tx_size = 0x40;
152
153 dev_p->storage_write_endpoint = CY_AS_P2S_WRITE_ENDPOINT;
154 dev_p->storage_read_endpoint = CY_AS_P2S_READ_ENDPOINT;
155
156 dev_p->func_cbs_misc = cy_as_create_c_b_queue(CYAS_FUNC_CB);
157 if (dev_p->func_cbs_misc == 0)
158 goto destroy;
159
160 dev_p->func_cbs_res = cy_as_create_c_b_queue(CYAS_FUNC_CB);
161 if (dev_p->func_cbs_res == 0)
162 goto destroy;
163
164 dev_p->func_cbs_stor = cy_as_create_c_b_queue(CYAS_FUNC_CB);
165 if (dev_p->func_cbs_stor == 0)
166 goto destroy;
167
168 dev_p->func_cbs_usb = cy_as_create_c_b_queue(CYAS_FUNC_CB);
169 if (dev_p->func_cbs_usb == 0)
170 goto destroy;
171
172 dev_p->func_cbs_mtp = cy_as_create_c_b_queue(CYAS_FUNC_CB);
173 if (dev_p->func_cbs_mtp == 0)
174 goto destroy;
175
176
177
178
179
180 ret = cy_as_dma_start(dev_p);
181 if (ret != CY_AS_ERROR_SUCCESS)
182 goto destroy;
183
184 cy_as_device_set_dma_stopped(dev_p);
185
186
187
188
189
190 ret = cy_as_ll_start(dev_p);
191 if (ret != CY_AS_ERROR_SUCCESS)
192 goto destroy;
193
194 cy_as_device_set_low_level_stopped(dev_p);
195
196 dev_p->next_p = g_device_list;
197 g_device_list = dev_p;
198
199 *handle_p = dev_p;
200 cy_as_hal_init_dev_registers(tag, cy_false);
201 return CY_AS_ERROR_SUCCESS;
202
203destroy:
204
205 if (dev_p->func_cbs_misc)
206 cy_as_destroy_c_b_queue(dev_p->func_cbs_misc);
207
208 if (dev_p->func_cbs_res)
209 cy_as_destroy_c_b_queue(dev_p->func_cbs_res);
210
211 if (dev_p->func_cbs_stor)
212 cy_as_destroy_c_b_queue(dev_p->func_cbs_stor);
213
214 if (dev_p->func_cbs_usb)
215 cy_as_destroy_c_b_queue(dev_p->func_cbs_usb);
216
217 if (dev_p->func_cbs_mtp)
218 cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp);
219
220 cy_as_hal_free(dev_p->usb_ep_data);
221 cy_as_hal_free(dev_p);
222
223 if (ret != CY_AS_ERROR_SUCCESS)
224 return ret;
225 else
226 return CY_AS_ERROR_OUT_OF_MEMORY;
227}
228
229
230
231
232cy_as_return_status_t
233cy_as_misc_destroy_device(cy_as_device_handle handle)
234{
235 cy_as_return_status_t ret;
236 cy_as_device *dev_p;
237
238 cy_as_log_debug_message(6, "cy_as_misc_destroy_device called");
239
240 dev_p = (cy_as_device *)handle;
241 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
242 return CY_AS_ERROR_INVALID_HANDLE;
243
244
245
246
247
248 if (dev_p->usb_count > 0)
249 return CY_AS_ERROR_STILL_RUNNING;
250
251
252
253
254
255 if (dev_p->storage_count > 0)
256 return CY_AS_ERROR_STILL_RUNNING;
257
258 if (cy_as_device_is_intr_running(dev_p))
259 ret = cy_as_intr_stop(dev_p);
260
261 ret = cy_as_ll_stop(dev_p);
262 if (ret != CY_AS_ERROR_SUCCESS) {
263 cy_as_intr_start(dev_p, dev_p->use_int_drq);
264 return ret;
265 }
266
267 ret = cy_as_dma_stop(dev_p);
268 if (ret != CY_AS_ERROR_SUCCESS) {
269 cy_as_intr_start(dev_p, dev_p->use_int_drq);
270 return ret;
271 }
272
273
274 cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG,
275 CY_AS_MEM_RST_CTRL_REG_HARD);
276
277
278
279
280 if (g_device_list == dev_p) {
281 g_device_list = dev_p->next_p;
282 } else {
283 cy_as_device *tmp_p = g_device_list;
284 while (tmp_p && tmp_p->next_p != dev_p)
285 tmp_p = tmp_p->next_p;
286
287 cy_as_hal_assert(tmp_p != 0);
288 tmp_p->next_p = dev_p->next_p;
289 }
290
291
292
293
294
295 dev_p->sig = 0;
296
297 cy_as_destroy_c_b_queue(dev_p->func_cbs_misc);
298 cy_as_destroy_c_b_queue(dev_p->func_cbs_res);
299 cy_as_destroy_c_b_queue(dev_p->func_cbs_stor);
300 cy_as_destroy_c_b_queue(dev_p->func_cbs_usb);
301 cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp);
302
303
304
305
306 cy_as_hal_free(dev_p->usb_ep_data);
307 cy_as_hal_free(dev_p);
308
309 return CY_AS_ERROR_SUCCESS;
310}
311
312
313
314
315
316static void
317cy_as_setup_endian_mode(cy_as_device *dev_p)
318{
319
320
321
322
323
324
325
326
327
328
329
330
331
332 cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_ENDIAN,
333 CY_AS_LITTLE_ENDIAN);
334}
335
336
337
338
339cy_as_return_status_t
340cy_as_misc_in_standby(cy_as_device_handle handle, cy_bool *standby)
341{
342 cy_as_device *dev_p;
343
344 cy_as_log_debug_message(6, "cy_as_misc_in_standby called");
345
346 dev_p = (cy_as_device *)handle;
347 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
348 return CY_AS_ERROR_INVALID_HANDLE;
349
350 if (cy_as_device_is_pin_standby(dev_p) ||
351 cy_as_device_is_register_standby(dev_p)) {
352 *standby = cy_true;
353 } else
354 *standby = cy_false;
355
356 return CY_AS_ERROR_SUCCESS;
357}
358
359static void
360cy_as_misc_func_callback(cy_as_device *dev_p,
361 uint8_t context,
362 cy_as_ll_request_response *rqt,
363 cy_as_ll_request_response *resp,
364 cy_as_return_status_t ret);
365
366
367static void
368my_misc_callback(cy_as_device *dev_p, uint8_t context,
369 cy_as_ll_request_response *req_p,
370 cy_as_ll_request_response *resp_p,
371 cy_as_return_status_t ret)
372{
373 (void)resp_p;
374 (void)context;
375 (void)ret;
376
377 switch (cy_as_ll_request_response__get_code(req_p)) {
378 case CY_RQT_INITIALIZATION_COMPLETE:
379 {
380 uint16_t v;
381
382 cy_as_ll_send_status_response(dev_p,
383 CY_RQT_GENERAL_RQT_CONTEXT,
384 CY_AS_ERROR_SUCCESS, 0);
385 cy_as_device_set_firmware_loaded(dev_p);
386
387 if (cy_as_device_is_waking(dev_p)) {
388
389
390
391
392
393
394
395 if (dev_p->misc_event_cb)
396 dev_p->misc_event_cb(
397 (cy_as_device_handle)dev_p,
398 cy_as_event_misc_awake, 0);
399 cy_as_device_clear_waking(dev_p);
400 } else {
401 v = cy_as_ll_request_response__get_word
402 (req_p, 3);
403
404
405
406
407
408 dev_p->media_supported[0] =
409 (uint8_t)(v & 0xFF);
410 dev_p->media_supported[1] =
411 (uint8_t)((v >> 8) & 0xFF);
412
413 v = cy_as_ll_request_response__get_word
414 (req_p, 4);
415
416 dev_p->is_mtp_firmware =
417 (cy_bool)((v >> 8) & 0xFF);
418
419 if (dev_p->misc_event_cb)
420 dev_p->misc_event_cb(
421 (cy_as_device_handle)dev_p,
422 cy_as_event_misc_initialized, 0);
423 }
424
425 v = cy_as_hal_read_register(dev_p->tag,
426 CY_AS_MEM_P0_VM_SET);
427
428 if (v & CY_AS_MEM_P0_VM_SET_CFGMODE)
429 cy_as_hal_print_message(
430 "initialization message "
431 "recieved, but config bit "
432 "still set\n");
433
434 v = cy_as_hal_read_register(dev_p->tag,
435 CY_AS_MEM_RST_CTRL_REG);
436 if ((v & CY_AS_MEM_RST_RSTCMPT) == 0)
437 cy_as_hal_print_message(
438 "initialization message "
439 "recieved, but reset complete "
440 "bit still not set\n");
441 }
442 break;
443
444 case CY_RQT_OUT_OF_SUSPEND:
445 cy_as_ll_send_status_response(dev_p, CY_RQT_GENERAL_RQT_CONTEXT,
446 CY_AS_ERROR_SUCCESS, 0);
447 cy_as_device_clear_suspend_mode(dev_p);
448
449
450
451
452
453 if (dev_p->func_cbs_misc->count > 0) {
454 cy_as_func_c_b_node *node = (cy_as_func_c_b_node *)
455 dev_p->func_cbs_misc->head_p;
456 cy_as_hal_assert(node);
457
458 if (cy_as_funct_c_b_type_get_type(node->data_type) ==
459 CY_FUNCT_CB_MISC_LEAVESUSPEND) {
460 cy_as_hal_assert(node->cb_p != 0);
461
462 node->cb_p((cy_as_device_handle)dev_p,
463 CY_AS_ERROR_SUCCESS, node->client_data,
464 CY_FUNCT_CB_MISC_LEAVESUSPEND, 0);
465 cy_as_remove_c_b_node(dev_p->func_cbs_misc);
466 }
467 }
468
469 if (dev_p->misc_event_cb)
470 dev_p->misc_event_cb((cy_as_device_handle)dev_p,
471 cy_as_event_misc_wakeup, 0);
472 break;
473
474 case CY_RQT_DEBUG_MESSAGE:
475 if ((req_p->data[0] == 0) && (req_p->data[1] == 0) &&
476 (req_p->data[2] == 0)) {
477 if (dev_p->misc_event_cb)
478 dev_p->misc_event_cb((cy_as_device_handle)dev_p,
479 cy_as_event_misc_heart_beat, 0);
480 } else {
481 cy_as_hal_print_message(
482 "**** debug message: %02x "
483 "%02x %02x %02x %02x %02x\n",
484 req_p->data[0] & 0xff,
485 (req_p->data[0] >> 8) & 0xff,
486 req_p->data[1] & 0xff,
487 (req_p->data[1] >> 8) & 0xff,
488 req_p->data[2] & 0xff,
489 (req_p->data[2] >> 8) & 0xff);
490 }
491 break;
492
493 case CY_RQT_WB_DEVICE_MISMATCH:
494 {
495 if (dev_p->misc_event_cb)
496 dev_p->misc_event_cb((cy_as_device_handle)dev_p,
497 cy_as_event_misc_device_mismatch, 0);
498 }
499 break;
500
501 case CY_RQT_BOOTLOAD_NO_FIRMWARE:
502 {
503
504
505 cy_as_hal_print_message("no firmware image found "
506 "during bootload. device not started\n");
507 }
508 break;
509
510 default:
511 cy_as_hal_assert(0);
512 }
513}
514
515static cy_bool
516is_valid_silicon_id(uint16_t v)
517{
518 cy_bool idok = cy_false;
519
520
521
522
523 v = v & CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK;
524
525
526
527
528 if (v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE ||
529 v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE ||
530 v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE)
531 idok = cy_true;
532
533 return idok;
534}
535
536
537
538
539cy_as_return_status_t
540cy_as_misc_configure_device(cy_as_device_handle handle,
541 cy_as_device_config *config_p)
542{
543 cy_as_return_status_t ret;
544 cy_bool standby;
545 cy_as_device *dev_p;
546 uint16_t v;
547 uint16_t fw_present;
548 cy_as_log_debug_message(6, "cy_as_misc_configure_device called");
549
550 dev_p = (cy_as_device *)handle;
551 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
552 return CY_AS_ERROR_INVALID_HANDLE;
553
554
555 cy_as_setup_endian_mode(dev_p);
556
557
558 dev_p->silicon_id = cy_as_hal_read_register(dev_p->tag,
559 CY_AS_MEM_CM_WB_CFG_ID);
560 fw_present = cy_as_hal_read_register(dev_p->tag,
561 CY_AS_MEM_RST_CTRL_REG);
562 if (!(fw_present & CY_AS_MEM_RST_RSTCMPT)) {
563 if (!is_valid_silicon_id(dev_p->silicon_id))
564 return CY_AS_ERROR_NO_ANTIOCH;
565 }
566
567 ret = cy_as_misc_in_standby(handle, &standby);
568 if (ret != CY_AS_ERROR_SUCCESS)
569 return ret;
570 if (ret)
571 return CY_AS_ERROR_IN_STANDBY;
572
573
574 if (cy_as_device_is_astoria_dev(dev_p)) {
575 if (config_p->srammode)
576 v = CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM;
577 else
578 v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM;
579 } else
580 v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM;
581
582
583 if (config_p->sync)
584 v |= CY_AS_MEM_P0_VM_SET_IFMODE;
585 if (config_p->dackmode == cy_as_device_dack_ack)
586 v |= CY_AS_MEM_P0_VM_SET_DACKEOB;
587 if (config_p->drqpol)
588 v |= CY_AS_MEM_P0_VM_SET_DRQPOL;
589 if (config_p->dackpol)
590 v |= CY_AS_MEM_P0_VM_SET_DACKPOL;
591 cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_VM_SET, v);
592
593 if (config_p->crystal)
594 cy_as_device_set_crystal(dev_p);
595 else
596 cy_as_device_set_external_clock(dev_p);
597
598
599 cy_as_ll_register_request_callback(dev_p,
600 CY_RQT_GENERAL_RQT_CONTEXT, my_misc_callback);
601
602
603 cy_as_device_set_dma_running(dev_p);
604 cy_as_device_set_low_level_running(dev_p);
605
606
607 dev_p->use_int_drq = config_p->dmaintr;
608 ret = cy_as_intr_start(dev_p, config_p->dmaintr);
609 if (ret != CY_AS_ERROR_SUCCESS)
610 return ret;
611
612
613 cy_as_device_set_configured(dev_p);
614
615 return CY_AS_ERROR_SUCCESS;
616}
617
618static void
619my_dma_callback(cy_as_device *dev_p,
620 cy_as_end_point_number_t ep,
621 void *mem_p,
622 uint32_t size,
623 cy_as_return_status_t ret
624 )
625{
626 cy_as_dma_end_point *ep_p;
627
628 (void)size;
629
630
631 ep_p = CY_AS_NUM_EP(dev_p, ep);
632
633
634 if (ep_p->queue_p == 0) {
635 cy_as_func_c_b_node *node =
636 (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p;
637
638 cy_as_hal_assert(node);
639
640 if (ret == CY_AS_ERROR_SUCCESS) {
641
642
643
644
645 cy_as_dma_enable_end_point(dev_p,
646 CY_AS_FIRMWARE_ENDPOINT,
647 cy_false, cy_as_direction_in);
648
649
650
651
652
653
654 cy_as_hal_write_register(dev_p->tag,
655 CY_AS_MEM_RST_CTRL_REG, 0x00);
656 }
657
658
659 node->cb_p((cy_as_device_handle)dev_p, ret, node->client_data,
660 node->data_type, node->data);
661 cy_as_remove_c_b_node(dev_p->func_cbs_misc);
662 } else {
663
664
665
666 uint32_t state = cy_as_hal_disable_interrupts();
667 cy_as_hal_c_b_free(mem_p);
668 cy_as_hal_enable_interrupts(state);
669 }
670}
671
672cy_as_return_status_t
673cy_as_misc_download_firmware(cy_as_device_handle handle,
674 const void *mem_p,
675 uint16_t size,
676 cy_as_function_callback cb,
677 uint32_t client)
678{
679 uint8_t *header;
680 cy_as_return_status_t ret;
681 cy_bool standby;
682 cy_as_device *dev_p;
683 cy_as_dma_callback dmacb = 0;
684 uint32_t state;
685
686 cy_as_log_debug_message(6, "cy_as_misc_download_firmware called");
687
688
689 dev_p = (cy_as_device *)handle;
690 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
691 return CY_AS_ERROR_INVALID_HANDLE;
692
693
694
695
696
697 if (!cy_as_device_is_configured(dev_p))
698 return CY_AS_ERROR_NOT_CONFIGURED;
699
700
701
702
703 ret = cy_as_misc_in_standby(dev_p, &standby);
704 if (ret != CY_AS_ERROR_SUCCESS)
705 return ret;
706
707 if (standby)
708 return CY_AS_ERROR_IN_STANDBY;
709
710 if (cy_as_device_is_in_suspend_mode(dev_p))
711 return CY_AS_ERROR_IN_SUSPEND;
712
713
714
715
716 if ((cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_VM_SET) &
717 CY_AS_MEM_P0_VM_SET_CFGMODE) == 0)
718 return CY_AS_ERROR_NOT_IN_CONFIG_MODE;
719
720
721 if (size > CY_AS_MAXIMUM_FIRMWARE_SIZE)
722 return CY_AS_ERROR_INVALID_SIZE;
723
724
725 if (size & 0x01)
726 return CY_AS_ERROR_ALIGNMENT_ERROR;
727
728
729
730
731
732 state = cy_as_hal_disable_interrupts();
733 header = (uint8_t *)cy_as_hal_c_b_alloc(4);
734 cy_as_hal_enable_interrupts(state);
735 if (header == NULL)
736 return CY_AS_ERROR_OUT_OF_MEMORY;
737
738 header[0] = 0x00;
739 header[1] = 0x00;
740 header[2] = (uint8_t)(size & 0xff);
741 header[3] = (uint8_t)((size >> 8) & 0xff);
742
743
744 ret = cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT,
745 cy_true, cy_as_direction_in);
746 if (ret != CY_AS_ERROR_SUCCESS)
747 return ret;
748
749
750
751
752
753 cy_as_dma_set_max_dma_size(dev_p, CY_AS_FIRMWARE_ENDPOINT, 64);
754
755 if (cb)
756 dmacb = my_dma_callback;
757
758 ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT, header,
759 4, cy_false, cy_false, dmacb);
760 if (ret != CY_AS_ERROR_SUCCESS)
761 return ret;
762
763
764
765
766 ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT,
767 (void *)mem_p, size, cy_false, cy_false, dmacb);
768 if (ret != CY_AS_ERROR_SUCCESS)
769 return ret;
770
771 if (cb) {
772 cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data(
773 cb, client, CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE, 0);
774
775 if (cbnode == 0)
776 return CY_AS_ERROR_OUT_OF_MEMORY;
777 else
778 cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode);
779
780 ret = cy_as_dma_kick_start(dev_p, CY_AS_FIRMWARE_ENDPOINT);
781 if (ret != CY_AS_ERROR_SUCCESS)
782 return ret;
783 } else {
784 ret = cy_as_dma_drain_queue(dev_p,
785 CY_AS_FIRMWARE_ENDPOINT, cy_true);
786
787
788 cy_as_hal_c_b_free(header);
789
790 if (ret != CY_AS_ERROR_SUCCESS)
791 return ret;
792
793
794
795
796
797 cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT,
798 cy_false, cy_as_direction_in);
799
800
801
802
803
804
805 cy_as_hal_write_register(dev_p->tag,
806 CY_AS_MEM_RST_CTRL_REG, 0x00);
807 }
808
809
810
811
812
813
814 return CY_AS_ERROR_SUCCESS;
815}
816
817
818static cy_as_return_status_t
819my_handle_response_get_firmware_version(cy_as_device *dev_p,
820 cy_as_ll_request_response *req_p,
821 cy_as_ll_request_response *reply_p,
822 cy_as_get_firmware_version_data *data_p)
823{
824
825 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
826 uint16_t val;
827
828 if (cy_as_ll_request_response__get_code(reply_p)
829 != CY_RESP_FIRMWARE_VERSION) {
830 ret = CY_AS_ERROR_INVALID_RESPONSE;
831 goto destroy;
832 }
833
834 data_p->major = cy_as_ll_request_response__get_word(reply_p, 0);
835 data_p->minor = cy_as_ll_request_response__get_word(reply_p, 1);
836 data_p->build = cy_as_ll_request_response__get_word(reply_p, 2);
837 val = cy_as_ll_request_response__get_word(reply_p, 3);
838 data_p->media_type = (uint8_t)(((val >> 8) & 0xFF) | (val & 0xFF));
839 val = cy_as_ll_request_response__get_word(reply_p, 4);
840 data_p->is_debug_mode = (cy_bool)(val & 0xFF);
841
842destroy:
843 cy_as_ll_destroy_request(dev_p, req_p);
844 cy_as_ll_destroy_response(dev_p, reply_p);
845
846 return ret;
847}
848
849cy_as_return_status_t
850cy_as_misc_get_firmware_version(cy_as_device_handle handle,
851 cy_as_get_firmware_version_data *data,
852 cy_as_function_callback cb,
853 uint32_t client)
854{
855 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
856 cy_bool standby;
857 cy_as_ll_request_response *req_p, *reply_p;
858
859 cy_as_device *dev_p;
860
861 (void)client;
862
863 cy_as_log_debug_message(6, "cy_as_misc_get_firmware_version called");
864
865
866 dev_p = (cy_as_device *)handle;
867 cy_as_check_device_ready(dev_p);
868
869
870
871
872 ret = cy_as_misc_in_standby(dev_p, &standby);
873 if (ret != CY_AS_ERROR_SUCCESS)
874 return ret;
875 if (standby)
876 return CY_AS_ERROR_IN_STANDBY;
877
878
879 if (cy_as_device_is_in_suspend_mode(dev_p))
880 return CY_AS_ERROR_IN_SUSPEND;
881
882
883 req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_FIRMWARE_VERSION,
884 CY_RQT_GENERAL_RQT_CONTEXT, 0);
885 if (req_p == 0)
886 return CY_AS_ERROR_OUT_OF_MEMORY;
887
888
889
890
891
892 reply_p = cy_as_ll_create_response(dev_p, 5);
893 if (reply_p == 0) {
894 cy_as_ll_destroy_request(dev_p, req_p);
895 return CY_AS_ERROR_OUT_OF_MEMORY;
896 }
897
898 if (cb == 0) {
899 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
900 if (ret != CY_AS_ERROR_SUCCESS)
901 goto destroy;
902
903
904
905 ret = my_handle_response_get_firmware_version(dev_p,
906 req_p, reply_p, data);
907 return ret;
908 } else {
909
910 ret = cy_as_misc_send_request(dev_p, cb, client,
911 CY_FUNCT_CB_MISC_GETFIRMWAREVERSION, data,
912 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
913 req_p, reply_p, cy_as_misc_func_callback);
914
915 if (ret != CY_AS_ERROR_SUCCESS)
916 goto destroy;
917
918
919
920 return ret;
921 }
922
923destroy:
924 cy_as_ll_destroy_request(dev_p, req_p);
925 cy_as_ll_destroy_response(dev_p, reply_p);
926
927 return ret;
928}
929static cy_as_return_status_t
930my_handle_response_read_m_c_u_register(cy_as_device *dev_p,
931 cy_as_ll_request_response *req_p,
932 cy_as_ll_request_response *reply_p,
933 uint8_t *data_p)
934{
935
936 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
937
938 if (cy_as_ll_request_response__get_code(reply_p)
939 != CY_RESP_MCU_REGISTER_DATA) {
940 ret = CY_AS_ERROR_INVALID_RESPONSE;
941 goto destroy;
942 }
943
944 *data_p = (uint8_t)
945 (cy_as_ll_request_response__get_word(reply_p, 0));
946
947destroy:
948 cy_as_ll_destroy_request(dev_p, req_p);
949 cy_as_ll_destroy_response(dev_p, reply_p);
950
951 return ret;
952}
953
954static cy_as_return_status_t
955my_handle_response_get_gpio_value(cy_as_device *dev_p,
956 cy_as_ll_request_response *req_p,
957 cy_as_ll_request_response *reply_p,
958 uint8_t *data_p)
959{
960
961 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
962
963 if (cy_as_ll_request_response__get_code(reply_p)
964 != CY_RESP_GPIO_STATE) {
965 ret = CY_AS_ERROR_INVALID_RESPONSE;
966 } else
967 *data_p = (uint8_t)
968 (cy_as_ll_request_response__get_word(reply_p, 0));
969
970 cy_as_ll_destroy_request(dev_p, req_p);
971 cy_as_ll_destroy_response(dev_p, reply_p);
972
973 return ret;
974}
975
976
977cy_as_return_status_t cy_as_misc_set_sd_power_polarity(
978 cy_as_device_handle handle,
979 cy_as_misc_signal_polarity polarity,
980 cy_as_function_callback cb,
981 uint32_t client)
982{
983 cy_as_ll_request_response *req_p, *reply_p;
984 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
985 cy_as_device *dev_p = (cy_as_device *)handle;
986
987 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
988 return CY_AS_ERROR_INVALID_HANDLE;
989
990 if (!cy_as_device_is_configured(dev_p))
991 return CY_AS_ERROR_NOT_CONFIGURED;
992
993 if (!cy_as_device_is_firmware_loaded(dev_p))
994 return CY_AS_ERROR_NO_FIRMWARE;
995
996 if (cy_as_device_is_in_suspend_mode(dev_p))
997 return CY_AS_ERROR_IN_SUSPEND;
998
999 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDPOLARITY,
1000 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1001 if (req_p == 0)
1002 return CY_AS_ERROR_OUT_OF_MEMORY;
1003
1004 cy_as_ll_request_response__set_word(req_p, 0,
1005 (uint16_t)polarity);
1006
1007
1008
1009
1010
1011 reply_p = cy_as_ll_create_response(dev_p, 1);
1012 if (reply_p == 0) {
1013 cy_as_ll_destroy_request(dev_p, req_p);
1014 return CY_AS_ERROR_OUT_OF_MEMORY;
1015 }
1016
1017 if (cb == 0) {
1018 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1019 if (ret != CY_AS_ERROR_SUCCESS)
1020 goto destroy;
1021
1022 return (my_handle_response_no_data(dev_p, req_p, reply_p));
1023 } else {
1024 ret = cy_as_misc_send_request(dev_p, cb, client,
1025 CY_FUNCT_CB_MISC_SETSDPOLARITY, 0, dev_p->func_cbs_misc,
1026 CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
1027 cy_as_misc_func_callback);
1028
1029 if (ret != CY_AS_ERROR_SUCCESS)
1030 goto destroy;
1031
1032
1033
1034 return ret;
1035 }
1036
1037destroy:
1038 cy_as_ll_destroy_request(dev_p, req_p);
1039 cy_as_ll_destroy_response(dev_p, reply_p);
1040 return ret;
1041}
1042
1043
1044cy_as_return_status_t
1045cy_as_misc_read_m_c_u_register(cy_as_device_handle handle,
1046 uint16_t address,
1047 uint8_t *value,
1048 cy_as_function_callback cb,
1049 uint32_t client)
1050{
1051 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1052 cy_as_ll_request_response *req_p, *reply_p;
1053
1054 cy_as_device *dev_p;
1055
1056 cy_as_log_debug_message(6, "cy_as_misc_read_m_c_u_register called");
1057
1058 dev_p = (cy_as_device *)handle;
1059 cy_as_check_device_ready(dev_p);
1060
1061
1062 if (cy_as_device_is_nand_storage_supported(dev_p))
1063 return CY_AS_ERROR_NOT_SUPPORTED;
1064
1065
1066 if (cy_as_device_is_in_suspend_mode(dev_p))
1067 return CY_AS_ERROR_IN_SUSPEND;
1068
1069
1070 req_p = cy_as_ll_create_request(dev_p, CY_RQT_READ_MCU_REGISTER,
1071 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1072 if (req_p == 0)
1073 return CY_AS_ERROR_OUT_OF_MEMORY;
1074
1075 cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address);
1076
1077
1078
1079 reply_p = cy_as_ll_create_response(dev_p, 1);
1080 if (reply_p == 0) {
1081 cy_as_ll_destroy_request(dev_p, req_p);
1082 return CY_AS_ERROR_OUT_OF_MEMORY;
1083 }
1084
1085 if (cb == 0) {
1086 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1087 if (ret != CY_AS_ERROR_SUCCESS)
1088 goto destroy;
1089
1090 if (cy_as_ll_request_response__get_code(reply_p) !=
1091 CY_RESP_MCU_REGISTER_DATA) {
1092 ret = CY_AS_ERROR_INVALID_RESPONSE;
1093 goto destroy;
1094 }
1095
1096 *value = (uint8_t)(cy_as_ll_request_response__get_word
1097 (reply_p, 0));
1098 } else {
1099
1100 ret = cy_as_misc_send_request(dev_p, cb, client,
1101 CY_FUNCT_CB_MISC_READMCUREGISTER, value,
1102 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
1103 req_p, reply_p, cy_as_misc_func_callback);
1104
1105 if (ret != CY_AS_ERROR_SUCCESS)
1106 goto destroy;
1107
1108
1109
1110 return ret;
1111 }
1112destroy:
1113 cy_as_ll_destroy_request(dev_p, req_p);
1114 cy_as_ll_destroy_response(dev_p, reply_p);
1115
1116 return ret;
1117}
1118
1119
1120cy_as_return_status_t
1121cy_as_misc_write_m_c_u_register(cy_as_device_handle handle,
1122 uint16_t address,
1123 uint8_t mask,
1124 uint8_t value,
1125 cy_as_function_callback cb,
1126 uint32_t client)
1127{
1128 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1129 cy_as_ll_request_response *req_p, *reply_p;
1130 cy_as_device *dev_p;
1131
1132 cy_as_log_debug_message(6, "cy_as_misc_write_m_c_u_register called");
1133
1134 dev_p = (cy_as_device *)handle;
1135 cy_as_check_device_ready(dev_p);
1136
1137
1138 if (cy_as_device_is_nand_storage_supported(dev_p))
1139 return CY_AS_ERROR_NOT_SUPPORTED;
1140
1141
1142 if (cy_as_device_is_in_suspend_mode(dev_p))
1143 return CY_AS_ERROR_IN_SUSPEND;
1144
1145
1146 req_p = cy_as_ll_create_request(dev_p, CY_RQT_WRITE_MCU_REGISTER,
1147 CY_RQT_GENERAL_RQT_CONTEXT, 2);
1148 if (req_p == 0)
1149 return CY_AS_ERROR_OUT_OF_MEMORY;
1150
1151 cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address);
1152 cy_as_ll_request_response__set_word(req_p, 1,
1153 (uint16_t)((mask << 8) | value));
1154
1155
1156
1157
1158
1159 reply_p = cy_as_ll_create_response(dev_p, 1);
1160 if (reply_p == 0) {
1161 cy_as_ll_destroy_request(dev_p, req_p);
1162 return CY_AS_ERROR_OUT_OF_MEMORY;
1163 }
1164
1165 if (cb == 0) {
1166 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1167 if (ret != CY_AS_ERROR_SUCCESS)
1168 goto destroy;
1169
1170 if (cy_as_ll_request_response__get_code(reply_p) !=
1171 CY_RESP_SUCCESS_FAILURE) {
1172 ret = CY_AS_ERROR_INVALID_RESPONSE;
1173 goto destroy;
1174 }
1175
1176 ret = cy_as_ll_request_response__get_word(reply_p, 0);
1177 } else {
1178 ret = cy_as_misc_send_request(dev_p, cb, client,
1179 CY_FUNCT_CB_MISC_WRITEMCUREGISTER, 0,
1180 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
1181 req_p, reply_p, cy_as_misc_func_callback);
1182
1183 if (ret != CY_AS_ERROR_SUCCESS)
1184 goto destroy;
1185
1186
1187
1188
1189
1190 return ret;
1191 }
1192
1193destroy:
1194 cy_as_ll_destroy_request(dev_p, req_p);
1195 cy_as_ll_destroy_response(dev_p, reply_p);
1196
1197 return ret;
1198}
1199
1200cy_as_return_status_t
1201my_handle_response_reset(cy_as_device *dev_p,
1202 cy_as_ll_request_response *req_p,
1203 cy_as_ll_request_response *reply_p,
1204 cy_as_reset_type type)
1205{
1206 uint16_t v;
1207
1208 (void)req_p;
1209 (void)reply_p;
1210
1211
1212
1213
1214
1215
1216
1217 if (cy_as_device_is_in_suspend_mode(dev_p)) {
1218 v = cy_as_hal_read_register(dev_p->tag,
1219 CY_AS_MEM_CM_WB_CFG_ID);
1220 cy_as_hal_sleep(1);
1221 }
1222
1223 if (type == cy_as_reset_hard) {
1224 cy_as_misc_cancel_ex_requests(dev_p);
1225 cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG,
1226 CY_AS_MEM_RST_CTRL_REG_HARD);
1227 cy_as_device_set_unconfigured(dev_p);
1228 cy_as_device_set_firmware_not_loaded(dev_p);
1229 cy_as_device_set_dma_stopped(dev_p);
1230 cy_as_device_set_low_level_stopped(dev_p);
1231 cy_as_device_set_intr_stopped(dev_p);
1232 cy_as_device_clear_suspend_mode(dev_p);
1233 cy_as_usb_cleanup(dev_p);
1234 cy_as_storage_cleanup(dev_p);
1235
1236
1237
1238
1239
1240 cy_as_hal_sleep(100);
1241 }
1242
1243 cy_as_device_clear_reset_pending(dev_p);
1244
1245 return CY_AS_ERROR_SUCCESS;
1246}
1247
1248cy_as_return_status_t
1249cy_as_misc_reset(cy_as_device_handle handle,
1250 cy_as_reset_type type,
1251 cy_bool flush,
1252 cy_as_function_callback cb,
1253 uint32_t client)
1254{
1255 cy_as_device *dev_p;
1256 cy_as_end_point_number_t i;
1257 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1258 (void)client;
1259 (void)cb;
1260
1261 cy_as_log_debug_message(6, "cy_as_misc_reset_e_x called");
1262
1263
1264 dev_p = (cy_as_device *)handle;
1265 cy_as_check_device_ready(dev_p);
1266
1267
1268
1269
1270
1271 if (type == cy_as_reset_soft)
1272 return CY_AS_ERROR_NOT_YET_SUPPORTED;
1273
1274 cy_as_device_set_reset_pending(dev_p);
1275
1276 if (flush) {
1277
1278 if ((dev_p->storage_cb || dev_p->storage_cb_ms) &&
1279 cy_as_hal_is_polling())
1280 return CY_AS_ERROR_ASYNC_PENDING;
1281
1282
1283
1284
1285 for (i = 0; i < 15; i++)
1286 cy_as_dma_enable_end_point(dev_p, i, cy_false,
1287 cy_as_direction_dont_change);
1288
1289
1290
1291
1292
1293
1294
1295
1296 if (cy_as_device_is_in_suspend_mode(dev_p)) {
1297 for (i = 0; i < 15; i++)
1298 cy_as_dma_cancel(dev_p, i,
1299 CY_AS_ERROR_CANCELED);
1300 } else {
1301 for (i = 0; i < 15; i++) {
1302 if ((i == CY_AS_P2S_WRITE_ENDPOINT) ||
1303 (i == CY_AS_P2S_READ_ENDPOINT))
1304 cy_as_dma_drain_queue(dev_p, i,
1305 cy_false);
1306 else
1307 cy_as_dma_drain_queue(dev_p, i,
1308 cy_true);
1309 }
1310 }
1311 } else {
1312
1313
1314
1315 if (cy_as_device_is_storage_async_pending(dev_p)) {
1316 for (i = 0; i < 15; i++)
1317 cy_as_dma_cancel(dev_p, i,
1318 CY_AS_ERROR_CANCELED);
1319 }
1320 }
1321
1322 ret = my_handle_response_reset(dev_p, 0, 0, type);
1323
1324 if (cb)
1325
1326
1327
1328 cb((cy_as_device_handle)dev_p, ret, client,
1329 CY_FUNCT_CB_MISC_RESET, 0);
1330
1331
1332
1333
1334
1335 cy_as_hal_init_dev_registers(dev_p->tag, cy_false);
1336
1337 return ret;
1338}
1339
1340static cy_as_return_status_t
1341get_unallocated_resource(cy_as_device *dev_p, cy_as_resource_type resource)
1342{
1343 uint8_t shift = 0;
1344 uint16_t v;
1345 cy_as_return_status_t ret = CY_AS_ERROR_NOT_ACQUIRED;
1346
1347 switch (resource) {
1348 case cy_as_bus_u_s_b:
1349 shift = 4;
1350 break;
1351 case cy_as_bus_1:
1352 shift = 0;
1353 break;
1354 case cy_as_bus_0:
1355 shift = 2;
1356 break;
1357 default:
1358 cy_as_hal_assert(cy_false);
1359 break;
1360 }
1361
1362
1363 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE);
1364 v = (v >> shift) & 0x03;
1365
1366 if (v == 0x03) {
1367 ret = CY_AS_ERROR_RESOURCE_ALREADY_OWNED;
1368 } else if ((v & 0x01) == 0) {
1369
1370 cy_as_hal_write_register(dev_p->tag,
1371 CY_AS_MEM_P0_RSE_MASK, (0x03 << shift));
1372 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK);
1373 cy_as_hal_write_register(dev_p->tag,
1374 CY_AS_MEM_P0_RSE_ALLOCATE, (0x01 << shift));
1375 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK);
1376
1377 v = cy_as_hal_read_register(dev_p->tag,
1378 CY_AS_MEM_P0_RSE_ALLOCATE);
1379 v = (v >> shift) & 0x03;
1380 if (v == 0x03)
1381 ret = CY_AS_ERROR_SUCCESS;
1382 }
1383
1384 return ret;
1385}
1386
1387static cy_as_return_status_t
1388my_handle_response_acquire_resource(cy_as_device *dev_p,
1389 cy_as_ll_request_response *req_p,
1390 cy_as_ll_request_response *reply_p,
1391 cy_as_resource_type *resource)
1392{
1393 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1394
1395 if (cy_as_ll_request_response__get_code(reply_p) !=
1396 CY_RESP_SUCCESS_FAILURE) {
1397 ret = CY_AS_ERROR_INVALID_RESPONSE;
1398 goto destroy;
1399 }
1400
1401 if (ret == CY_AS_ERROR_SUCCESS) {
1402 ret = get_unallocated_resource(dev_p, *resource);
1403 if (ret != CY_AS_ERROR_NOT_ACQUIRED)
1404 ret = CY_AS_ERROR_SUCCESS;
1405 }
1406
1407destroy:
1408 cy_as_ll_destroy_request(dev_p, req_p);
1409 cy_as_ll_destroy_response(dev_p, reply_p);
1410
1411 return ret;
1412}
1413
1414cy_as_return_status_t
1415cy_as_misc_acquire_resource(cy_as_device_handle handle,
1416 cy_as_resource_type *resource,
1417 cy_bool force,
1418 cy_as_function_callback cb,
1419 uint32_t client)
1420{
1421 cy_as_ll_request_response *req_p, *reply_p;
1422 cy_as_return_status_t ret;
1423
1424 cy_as_device *dev_p;
1425
1426 (void)client;
1427
1428 cy_as_log_debug_message(6, "cy_as_misc_acquire_resource called");
1429
1430 if (*resource != cy_as_bus_u_s_b && *resource !=
1431 cy_as_bus_0 && *resource != cy_as_bus_1)
1432 return CY_AS_ERROR_INVALID_RESOURCE;
1433
1434
1435
1436 dev_p = (cy_as_device *)handle;
1437 cy_as_check_device_ready(dev_p);
1438
1439 if (cy_as_device_is_in_suspend_mode(dev_p))
1440 return CY_AS_ERROR_IN_SUSPEND;
1441
1442
1443 ret = get_unallocated_resource(dev_p, *resource);
1444
1445
1446
1447
1448
1449 if ((ret == CY_AS_ERROR_SUCCESS) && (cb != 0))
1450 cb(handle, ret, client,
1451 CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource);
1452
1453 if (ret != CY_AS_ERROR_NOT_ACQUIRED)
1454 return ret;
1455
1456 if (!force)
1457 return CY_AS_ERROR_NOT_ACQUIRED;
1458
1459
1460 req_p = cy_as_ll_create_request(dev_p, CY_RQT_ACQUIRE_RESOURCE,
1461 CY_RQT_RESOURCE_RQT_CONTEXT, 1);
1462 if (req_p == 0)
1463 return CY_AS_ERROR_OUT_OF_MEMORY;
1464
1465 cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)(*resource));
1466
1467 reply_p = cy_as_ll_create_response(dev_p, 1);
1468 if (reply_p == 0) {
1469 cy_as_ll_destroy_request(dev_p, req_p);
1470 return CY_AS_ERROR_OUT_OF_MEMORY;
1471 }
1472
1473 if (cb == 0) {
1474 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1475 if (ret != CY_AS_ERROR_SUCCESS)
1476 goto destroy;
1477
1478 if (cy_as_ll_request_response__get_code(reply_p) !=
1479 CY_RESP_SUCCESS_FAILURE) {
1480 ret = CY_AS_ERROR_INVALID_RESPONSE;
1481 goto destroy;
1482 }
1483
1484 ret = cy_as_ll_request_response__get_word(reply_p, 0);
1485 } else {
1486 ret = cy_as_misc_send_request(dev_p, cb, client,
1487 CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource,
1488 dev_p->func_cbs_res, CY_AS_REQUEST_RESPONSE_EX,
1489 req_p, reply_p, cy_as_misc_func_callback);
1490
1491 if (ret != CY_AS_ERROR_SUCCESS)
1492 goto destroy;
1493
1494
1495
1496 return ret;
1497 }
1498
1499destroy:
1500 cy_as_ll_destroy_request(dev_p, req_p);
1501 cy_as_ll_destroy_response(dev_p, reply_p);
1502
1503 if (ret == CY_AS_ERROR_SUCCESS) {
1504 ret = get_unallocated_resource(dev_p, *resource);
1505 if (ret != CY_AS_ERROR_NOT_ACQUIRED)
1506 ret = CY_AS_ERROR_SUCCESS;
1507 }
1508
1509 return ret;
1510}
1511cy_as_return_status_t
1512cy_as_misc_release_resource(cy_as_device_handle handle,
1513 cy_as_resource_type resource)
1514{
1515 uint8_t shift = 0;
1516 uint16_t v;
1517
1518 cy_as_device *dev_p;
1519
1520 cy_as_log_debug_message(6, "cy_as_misc_release_resource called");
1521
1522
1523 dev_p = (cy_as_device *)handle;
1524 cy_as_check_device_ready(dev_p);
1525
1526 if (cy_as_device_is_in_suspend_mode(dev_p))
1527 return CY_AS_ERROR_IN_SUSPEND;
1528
1529 if (resource != cy_as_bus_u_s_b && resource !=
1530 cy_as_bus_0 && resource != cy_as_bus_1)
1531 return CY_AS_ERROR_INVALID_RESOURCE;
1532
1533 switch (resource) {
1534 case cy_as_bus_u_s_b:
1535 shift = 4;
1536 break;
1537 case cy_as_bus_1:
1538 shift = 0;
1539 break;
1540 case cy_as_bus_0:
1541 shift = 2;
1542 break;
1543 default:
1544 cy_as_hal_assert(cy_false);
1545 break;
1546 }
1547
1548
1549 v = (cy_as_hal_read_register(dev_p->tag,
1550 CY_AS_MEM_P0_RSE_ALLOCATE) >> shift) & 0x03;
1551 if (v == 0 || v == 1 || v == 2)
1552 return CY_AS_ERROR_RESOURCE_NOT_OWNED;
1553
1554 cy_as_hal_write_register(dev_p->tag,
1555 CY_AS_MEM_P0_RSE_MASK, (0x03 << shift));
1556 cy_as_hal_write_register(dev_p->tag,
1557 CY_AS_MEM_P0_RSE_ALLOCATE, (0x02 << shift));
1558 cy_as_hal_write_register(dev_p->tag,
1559 CY_AS_MEM_P0_RSE_MASK, 0);
1560
1561 return CY_AS_ERROR_SUCCESS;
1562}
1563
1564cy_as_return_status_t
1565cy_as_misc_set_trace_level(cy_as_device_handle handle,
1566 uint8_t level,
1567 cy_as_bus_number_t bus,
1568 uint32_t device,
1569 uint32_t unit,
1570 cy_as_function_callback cb,
1571 uint32_t client)
1572{
1573 cy_as_ll_request_response *req_p, *reply_p;
1574 cy_as_return_status_t ret;
1575 cy_as_device *dev_p;
1576
1577 cy_as_log_debug_message(6, "cy_as_misc_set_trace_level called");
1578
1579
1580 dev_p = (cy_as_device *)handle;
1581 cy_as_check_device_ready(dev_p);
1582
1583 if (cy_as_device_is_in_suspend_mode(dev_p))
1584 return CY_AS_ERROR_IN_SUSPEND;
1585
1586 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
1587 return CY_AS_ERROR_NO_SUCH_BUS;
1588
1589 if (device >= CY_AS_MAX_STORAGE_DEVICES)
1590 return CY_AS_ERROR_NO_SUCH_DEVICE;
1591
1592 if (unit > 255)
1593 return CY_AS_ERROR_NO_SUCH_UNIT;
1594
1595 if (level >= CYAS_FW_TRACE_MAX_LEVEL)
1596 return CY_AS_ERROR_INVALID_TRACE_LEVEL;
1597
1598
1599 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_TRACE_LEVEL,
1600 CY_RQT_GENERAL_RQT_CONTEXT, 2);
1601 if (req_p == 0)
1602 return CY_AS_ERROR_OUT_OF_MEMORY;
1603
1604 cy_as_ll_request_response__set_word(req_p, 0,
1605 (uint16_t)level);
1606 cy_as_ll_request_response__set_word(req_p, 1,
1607 (uint16_t)((bus << 12) | (device << 8) | (unit)));
1608
1609
1610
1611
1612
1613 reply_p = cy_as_ll_create_response(dev_p, 2);
1614 if (reply_p == 0) {
1615 cy_as_ll_destroy_request(dev_p, req_p);
1616 return CY_AS_ERROR_OUT_OF_MEMORY;
1617 }
1618
1619 if (cb == 0) {
1620 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1621 if (ret != CY_AS_ERROR_SUCCESS)
1622 goto destroy;
1623
1624 if (cy_as_ll_request_response__get_code(reply_p) !=
1625 CY_RESP_SUCCESS_FAILURE) {
1626 ret = CY_AS_ERROR_NOT_SUPPORTED;
1627 goto destroy;
1628 }
1629
1630 ret = cy_as_ll_request_response__get_word(reply_p, 0);
1631 } else {
1632
1633 ret = cy_as_misc_send_request(dev_p, cb, client,
1634 CY_FUNCT_CB_MISC_SETTRACELEVEL, 0, dev_p->func_cbs_misc,
1635 CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
1636 cy_as_misc_func_callback);
1637
1638 if (ret != CY_AS_ERROR_SUCCESS)
1639 goto destroy;
1640
1641
1642
1643 return ret;
1644 }
1645
1646destroy:
1647 cy_as_ll_destroy_request(dev_p, req_p);
1648 cy_as_ll_destroy_response(dev_p, reply_p);
1649
1650 return ret;
1651}
1652
1653cy_as_return_status_t
1654cy_as_misc_heart_beat_control(cy_as_device_handle handle,
1655 cy_bool enable,
1656 cy_as_function_callback cb,
1657 uint32_t client)
1658{
1659 cy_as_ll_request_response *req_p, *reply_p;
1660 cy_as_return_status_t ret;
1661 cy_as_device *dev_p;
1662
1663 cy_as_log_debug_message(6, "cy_as_misc_heart_beat_control called");
1664
1665
1666 dev_p = (cy_as_device *)handle;
1667 cy_as_check_device_ready(dev_p);
1668
1669 if (cy_as_device_is_in_suspend_mode(dev_p))
1670 return CY_AS_ERROR_IN_SUSPEND;
1671
1672
1673 req_p = cy_as_ll_create_request(dev_p, CY_RQT_CONTROL_ANTIOCH_HEARTBEAT,
1674 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1675 if (req_p == 0)
1676 return CY_AS_ERROR_OUT_OF_MEMORY;
1677
1678 cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)enable);
1679
1680
1681
1682 reply_p = cy_as_ll_create_response(dev_p, 1);
1683 if (reply_p == 0) {
1684 cy_as_ll_destroy_request(dev_p, req_p);
1685 return CY_AS_ERROR_OUT_OF_MEMORY;
1686 }
1687
1688 if (cb == 0) {
1689 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1690 if (ret != CY_AS_ERROR_SUCCESS)
1691 goto destroy;
1692
1693 if (cy_as_ll_request_response__get_code(reply_p) !=
1694 CY_RESP_SUCCESS_FAILURE) {
1695 ret = CY_AS_ERROR_INVALID_RESPONSE;
1696 goto destroy;
1697 }
1698
1699 ret = cy_as_ll_request_response__get_word(reply_p, 0);
1700 } else {
1701
1702 ret = cy_as_misc_send_request(dev_p, cb, client,
1703 CY_FUNCT_CB_MISC_HEARTBEATCONTROL, 0,
1704 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
1705 req_p, reply_p, cy_as_misc_func_callback);
1706
1707 if (ret != CY_AS_ERROR_SUCCESS)
1708 goto destroy;
1709
1710
1711
1712 return ret;
1713 }
1714
1715destroy:
1716 cy_as_ll_destroy_request(dev_p, req_p);
1717 cy_as_ll_destroy_response(dev_p, reply_p);
1718
1719 return ret;
1720}
1721
1722static cy_as_return_status_t
1723my_set_sd_clock_freq(
1724 cy_as_device *dev_p,
1725 uint8_t card_type,
1726 uint8_t setting,
1727 cy_as_function_callback cb,
1728 uint32_t client)
1729{
1730 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1731 cy_as_ll_request_response *req_p, *reply_p;
1732
1733 if (cy_as_device_is_in_callback(dev_p) && (cb == 0))
1734 return CY_AS_ERROR_INVALID_IN_CALLBACK;
1735
1736 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_SD_CLOCK_FREQ,
1737 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1738 if (req_p == 0)
1739 return CY_AS_ERROR_OUT_OF_MEMORY;
1740
1741 cy_as_ll_request_response__set_word(req_p, 0,
1742 (uint16_t)((card_type << 8) | setting));
1743
1744
1745 reply_p = cy_as_ll_create_response(dev_p, 1);
1746 if (reply_p == 0) {
1747 cy_as_ll_destroy_request(dev_p, req_p);
1748 return CY_AS_ERROR_OUT_OF_MEMORY;
1749 }
1750
1751 if (cb == 0) {
1752 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1753 if (ret != CY_AS_ERROR_SUCCESS)
1754 goto destroy;
1755
1756 if (cy_as_ll_request_response__get_code(reply_p) !=
1757 CY_RESP_SUCCESS_FAILURE) {
1758 ret = CY_AS_ERROR_INVALID_RESPONSE;
1759 goto destroy;
1760 }
1761
1762 ret = cy_as_ll_request_response__get_word(reply_p, 0);
1763 } else {
1764 ret = cy_as_misc_send_request(dev_p, cb, client,
1765 CY_FUNCT_CB_MISC_SETSDFREQ, 0, dev_p->func_cbs_misc,
1766 CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
1767 cy_as_misc_func_callback);
1768
1769 if (ret != CY_AS_ERROR_SUCCESS)
1770 goto destroy;
1771
1772
1773
1774 return ret;
1775 }
1776
1777destroy:
1778 cy_as_ll_destroy_request(dev_p, req_p);
1779 cy_as_ll_destroy_response(dev_p, reply_p);
1780
1781 return ret;
1782}
1783
1784cy_as_return_status_t
1785cy_as_misc_set_low_speed_sd_freq(
1786 cy_as_device_handle handle,
1787 cy_as_low_speed_sd_freq setting,
1788 cy_as_function_callback cb,
1789 uint32_t client)
1790{
1791 cy_as_device *dev_p;
1792
1793 cy_as_log_debug_message(6, "cy_as_misc_set_low_speed_sd_freq called");
1794
1795
1796 dev_p = (cy_as_device *)handle;
1797 cy_as_check_device_ready(dev_p);
1798
1799 if (cy_as_device_is_in_suspend_mode(dev_p))
1800 return CY_AS_ERROR_IN_SUSPEND;
1801
1802 if ((setting != CY_AS_SD_DEFAULT_FREQ) &&
1803 (setting != CY_AS_SD_RATED_FREQ))
1804 return CY_AS_ERROR_INVALID_PARAMETER;
1805
1806 return my_set_sd_clock_freq(dev_p, 0, (uint8_t)setting, cb, client);
1807}
1808
1809cy_as_return_status_t
1810cy_as_misc_set_high_speed_sd_freq(
1811 cy_as_device_handle handle,
1812 cy_as_high_speed_sd_freq setting,
1813 cy_as_function_callback cb,
1814 uint32_t client)
1815{
1816 cy_as_device *dev_p;
1817
1818 cy_as_log_debug_message(6, "cy_as_misc_set_high_speed_sd_freq called");
1819
1820
1821 dev_p = (cy_as_device *)handle;
1822 cy_as_check_device_ready(dev_p);
1823
1824 if (cy_as_device_is_in_suspend_mode(dev_p))
1825 return CY_AS_ERROR_IN_SUSPEND;
1826
1827 if ((setting != CY_AS_HS_SD_FREQ_24) &&
1828 (setting != CY_AS_HS_SD_FREQ_48))
1829 return CY_AS_ERROR_INVALID_PARAMETER;
1830
1831 return my_set_sd_clock_freq(dev_p, 1, (uint8_t)setting, cb, client);
1832}
1833
1834cy_as_return_status_t
1835cy_as_misc_get_gpio_value(cy_as_device_handle handle,
1836 cy_as_misc_gpio pin,
1837 uint8_t *value,
1838 cy_as_function_callback cb,
1839 uint32_t client)
1840{
1841 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1842 cy_as_ll_request_response *req_p, *reply_p;
1843 cy_as_device *dev_p;
1844 uint16_t v;
1845
1846 cy_as_log_debug_message(6, "cy_as_misc_get_gpio_value called");
1847
1848
1849 dev_p = (cy_as_device *)handle;
1850 cy_as_check_device_ready(dev_p);
1851
1852
1853
1854 if (pin == cy_as_misc_gpio_U_valid) {
1855 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE);
1856 *value = (uint8_t)(v & CY_AS_MEM_PMU_UPDATE_UVALID);
1857
1858 if (cb != 0)
1859 cb(dev_p, ret, client,
1860 CY_FUNCT_CB_MISC_GETGPIOVALUE, value);
1861
1862 return ret;
1863 }
1864
1865
1866 if (cy_as_device_is_nand_storage_supported(dev_p))
1867 return CY_AS_ERROR_NOT_SUPPORTED;
1868
1869 if (cy_as_device_is_in_suspend_mode(dev_p))
1870 return CY_AS_ERROR_IN_SUSPEND;
1871
1872
1873 if ((pin != cy_as_misc_gpio_1) && (pin != cy_as_misc_gpio_0))
1874 return CY_AS_ERROR_INVALID_PARAMETER;
1875
1876 req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_GPIO_STATE,
1877 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1878 if (req_p == 0)
1879 return CY_AS_ERROR_OUT_OF_MEMORY;
1880
1881 cy_as_ll_request_response__set_word(req_p, 0, ((uint8_t)pin << 8));
1882
1883
1884 reply_p = cy_as_ll_create_response(dev_p, 1);
1885 if (reply_p == 0) {
1886 cy_as_ll_destroy_request(dev_p, req_p);
1887 return CY_AS_ERROR_OUT_OF_MEMORY;
1888 }
1889
1890 if (cb == 0) {
1891 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1892 if (ret != CY_AS_ERROR_SUCCESS)
1893 goto destroy;
1894
1895 if (cy_as_ll_request_response__get_code(reply_p) !=
1896 CY_RESP_GPIO_STATE) {
1897 ret = CY_AS_ERROR_INVALID_RESPONSE;
1898 goto destroy;
1899 }
1900
1901 *value = (uint8_t)
1902 cy_as_ll_request_response__get_word(reply_p, 0);
1903 } else {
1904
1905 ret = cy_as_misc_send_request(dev_p, cb, client,
1906 CY_FUNCT_CB_MISC_GETGPIOVALUE, value,
1907 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
1908 req_p, reply_p, cy_as_misc_func_callback);
1909
1910 if (ret != CY_AS_ERROR_SUCCESS)
1911 goto destroy;
1912
1913
1914
1915 return ret;
1916 }
1917
1918destroy:
1919 cy_as_ll_destroy_request(dev_p, req_p);
1920 cy_as_ll_destroy_response(dev_p, reply_p);
1921
1922 return ret;
1923}
1924
1925
1926cy_as_return_status_t
1927cy_as_misc_set_gpio_value(cy_as_device_handle handle,
1928 cy_as_misc_gpio pin,
1929 uint8_t value,
1930 cy_as_function_callback cb,
1931 uint32_t client)
1932{
1933 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1934 cy_as_ll_request_response *req_p, *reply_p;
1935 cy_as_device *dev_p;
1936 uint16_t v;
1937
1938 cy_as_log_debug_message(6, "cy_as_misc_set_gpio_value called");
1939
1940
1941 dev_p = (cy_as_device *)handle;
1942 cy_as_check_device_ready(dev_p);
1943
1944
1945
1946 if (pin == cy_as_misc_gpio_U_valid) {
1947 v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE);
1948 if (value)
1949 cy_as_hal_write_register(dev_p->tag,
1950 CY_AS_MEM_PMU_UPDATE,
1951 (v | CY_AS_MEM_PMU_UPDATE_UVALID));
1952 else
1953 cy_as_hal_write_register(dev_p->tag,
1954 CY_AS_MEM_PMU_UPDATE,
1955 (v & ~CY_AS_MEM_PMU_UPDATE_UVALID));
1956
1957 if (cb != 0)
1958 cb(dev_p, ret, client,
1959 CY_FUNCT_CB_MISC_SETGPIOVALUE, 0);
1960 return ret;
1961 }
1962
1963
1964 if (cy_as_device_is_nand_storage_supported(dev_p))
1965 return CY_AS_ERROR_NOT_SUPPORTED;
1966
1967 if (cy_as_device_is_in_suspend_mode(dev_p))
1968 return CY_AS_ERROR_IN_SUSPEND;
1969
1970
1971 if ((pin < cy_as_misc_gpio_0) || (pin > cy_as_misc_gpio_U_valid))
1972 return CY_AS_ERROR_INVALID_PARAMETER;
1973
1974
1975 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_GPIO_STATE,
1976 CY_RQT_GENERAL_RQT_CONTEXT, 1);
1977 if (req_p == 0)
1978 return CY_AS_ERROR_OUT_OF_MEMORY;
1979
1980 v = (uint16_t)(((uint8_t)pin << 8) | (value > 0));
1981 cy_as_ll_request_response__set_word(req_p, 0, v);
1982
1983
1984 reply_p = cy_as_ll_create_response(dev_p, 1);
1985 if (reply_p == 0) {
1986 cy_as_ll_destroy_request(dev_p, req_p);
1987 return CY_AS_ERROR_OUT_OF_MEMORY;
1988 }
1989
1990 if (cb == 0) {
1991 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1992 if (ret != CY_AS_ERROR_SUCCESS)
1993 goto destroy;
1994
1995 if (cy_as_ll_request_response__get_code(reply_p) !=
1996 CY_RESP_SUCCESS_FAILURE) {
1997 ret = CY_AS_ERROR_INVALID_RESPONSE;
1998 goto destroy;
1999 }
2000
2001 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2002 } else {
2003
2004 ret = cy_as_misc_send_request(dev_p, cb, client,
2005 CY_FUNCT_CB_MISC_SETGPIOVALUE, 0,
2006 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
2007 req_p, reply_p, cy_as_misc_func_callback);
2008
2009 if (ret != CY_AS_ERROR_SUCCESS)
2010 goto destroy;
2011
2012
2013
2014 return ret;
2015 }
2016
2017destroy:
2018 cy_as_ll_destroy_request(dev_p, req_p);
2019 cy_as_ll_destroy_response(dev_p, reply_p);
2020
2021 return ret;
2022}
2023
2024static cy_as_return_status_t
2025my_enter_standby(cy_as_device *dev_p, cy_bool pin)
2026{
2027 cy_as_misc_cancel_ex_requests(dev_p);
2028
2029
2030
2031 cy_as_hal_read_regs_before_standby(dev_p->tag);
2032
2033 if (pin) {
2034 if (cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false))
2035 cy_as_device_set_pin_standby(dev_p);
2036 else
2037 return CY_AS_ERROR_SETTING_WAKEUP_PIN;
2038 } else {
2039
2040
2041
2042 cy_as_hal_write_register(dev_p->tag,
2043 CY_AS_MEM_PWR_MAGT_STAT, 0x02);
2044 cy_as_device_set_register_standby(dev_p);
2045 }
2046
2047
2048
2049
2050
2051
2052 cy_as_device_set_firmware_not_loaded(dev_p);
2053
2054
2055
2056
2057
2058 dev_p->stby_int_mask = cy_as_hal_disable_interrupts();
2059
2060 return CY_AS_ERROR_SUCCESS;
2061}
2062
2063static cy_as_return_status_t
2064my_handle_response_enter_standby(cy_as_device *dev_p,
2065 cy_as_ll_request_response *req_p,
2066 cy_as_ll_request_response *reply_p,
2067 cy_bool pin)
2068{
2069 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2070
2071 if (cy_as_ll_request_response__get_code(reply_p) !=
2072 CY_RESP_SUCCESS_FAILURE) {
2073 ret = CY_AS_ERROR_INVALID_RESPONSE;
2074 goto destroy;
2075 }
2076
2077 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2078
2079destroy:
2080 cy_as_ll_destroy_request(dev_p, req_p);
2081 cy_as_ll_destroy_response(dev_p, reply_p);
2082
2083 if (ret != CY_AS_ERROR_SUCCESS)
2084 return ret;
2085
2086 ret = my_enter_standby(dev_p, pin);
2087
2088 return ret;
2089}
2090
2091cy_as_return_status_t
2092cy_as_misc_enter_standby(cy_as_device_handle handle,
2093 cy_bool pin,
2094 cy_as_function_callback cb,
2095 uint32_t client)
2096{
2097 cy_as_device *dev_p;
2098 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2099 cy_as_ll_request_response *req_p, *reply_p;
2100 cy_bool standby;
2101
2102 cy_as_log_debug_message(6, "cy_as_misc_enter_standby called");
2103
2104
2105 dev_p = (cy_as_device *)handle;
2106 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2107 return CY_AS_ERROR_INVALID_HANDLE;
2108
2109
2110
2111
2112
2113 ret = cy_as_misc_in_standby(handle, &standby);
2114 if (ret != CY_AS_ERROR_SUCCESS)
2115 return ret;
2116
2117 if (standby == cy_true)
2118 return CY_AS_ERROR_ALREADY_STANDBY;
2119
2120
2121
2122
2123
2124
2125 if (cy_as_device_is_in_suspend_mode(dev_p))
2126 cy_as_misc_leave_suspend(dev_p, 0, 0);
2127
2128 if (dev_p->usb_count) {
2129
2130
2131
2132
2133
2134 return CY_AS_ERROR_USB_RUNNING;
2135 }
2136
2137
2138
2139
2140
2141
2142 if (dev_p->storage_count) {
2143
2144
2145
2146
2147 if (cy_as_device_is_storage_async_pending(dev_p)) {
2148
2149 if (cy_as_hal_is_polling())
2150 return CY_AS_ERROR_ASYNC_PENDING;
2151
2152 cy_as_dma_drain_queue(dev_p,
2153 CY_AS_P2S_READ_ENDPOINT, cy_false);
2154 cy_as_dma_drain_queue(dev_p,
2155 CY_AS_P2S_WRITE_ENDPOINT, cy_false);
2156
2157
2158
2159
2160
2161 if (cy_as_device_is_storage_async_pending(dev_p))
2162 return CY_AS_ERROR_ASYNC_PENDING;
2163 }
2164
2165 req_p = cy_as_ll_create_request(dev_p,
2166 CY_RQT_PREPARE_FOR_STANDBY,
2167 CY_RQT_GENERAL_RQT_CONTEXT, 1);
2168 if (req_p == 0)
2169 return CY_AS_ERROR_OUT_OF_MEMORY;
2170
2171 reply_p = cy_as_ll_create_response(dev_p, 1);
2172 if (reply_p == 0) {
2173 cy_as_ll_destroy_request(dev_p, req_p);
2174 return CY_AS_ERROR_OUT_OF_MEMORY;
2175 }
2176
2177 if (!cb) {
2178 ret = cy_as_ll_send_request_wait_reply(dev_p,
2179 req_p, reply_p);
2180 if (ret != CY_AS_ERROR_SUCCESS)
2181 goto destroy;
2182
2183
2184
2185 return my_handle_response_enter_standby(dev_p,
2186 req_p, reply_p, pin);
2187
2188 } else {
2189 ret = cy_as_misc_send_request(dev_p, cb, client,
2190 CY_FUNCT_CB_MISC_ENTERSTANDBY, (void *)pin,
2191 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
2192 req_p, reply_p, cy_as_misc_func_callback);
2193
2194 if (ret != CY_AS_ERROR_SUCCESS)
2195 goto destroy;
2196
2197
2198
2199 return ret;
2200 }
2201destroy:
2202 cy_as_ll_destroy_request(dev_p, req_p);
2203 cy_as_ll_destroy_response(dev_p, reply_p);
2204 } else {
2205 ret = my_enter_standby(dev_p, pin);
2206 if (cb)
2207
2208
2209
2210 cb((cy_as_device_handle)dev_p, ret, client,
2211 CY_FUNCT_CB_MISC_ENTERSTANDBY, 0);
2212 }
2213
2214 return ret;
2215}
2216
2217cy_as_return_status_t
2218cy_as_misc_enter_standby_e_x_u(cy_as_device_handle handle,
2219 cy_bool pin,
2220 cy_bool uvalid_special,
2221 cy_as_function_callback cb,
2222 uint32_t client)
2223{
2224 cy_as_device *dev_p;
2225
2226 dev_p = (cy_as_device *)handle;
2227 if (uvalid_special)
2228 cy_as_hal_write_register(dev_p->tag, 0xc5, 0x4);
2229
2230 return cy_as_misc_enter_standby(handle, pin, cb, client);
2231}
2232
2233cy_as_return_status_t
2234cy_as_misc_leave_standby(cy_as_device_handle handle,
2235 cy_as_resource_type resource)
2236{
2237 cy_as_device *dev_p;
2238 uint16_t v;
2239 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2240 uint32_t count = 8;
2241 uint8_t retry = 1;
2242
2243 cy_as_log_debug_message(6, "cy_as_misc_leave_standby called");
2244 (void)resource;
2245
2246
2247 dev_p = (cy_as_device *)handle;
2248 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2249 return CY_AS_ERROR_INVALID_HANDLE;
2250
2251 if (cy_as_device_is_register_standby(dev_p)) {
2252
2253
2254
2255
2256 cy_as_device_set_waking(dev_p);
2257
2258
2259
2260
2261
2262
2263 v = cy_as_hal_read_register(dev_p->tag,
2264 CY_AS_MEM_CM_WB_CFG_ID);
2265
2266 do {
2267
2268
2269
2270
2271
2272
2273 if (cy_as_device_is_crystal(dev_p))
2274 cy_as_hal_sleep(
2275 CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL);
2276 else
2277 cy_as_hal_sleep(
2278 CY_AS_LEAVE_STANDBY_DELAY_CLOCK);
2279 v = cy_as_hal_read_register(dev_p->tag,
2280 CY_AS_MEM_CM_WB_CFG_ID);
2281
2282
2283
2284
2285
2286
2287 if (!is_valid_silicon_id(v)) {
2288 if (cy_as_hal_sync_device_clocks(dev_p->tag) !=
2289 cy_true) {
2290 cy_as_hal_enable_interrupts(
2291 dev_p->stby_int_mask);
2292 return CY_AS_ERROR_TIMEOUT;
2293 }
2294 }
2295 } while (!is_valid_silicon_id(v) && count-- > 0);
2296
2297
2298
2299
2300
2301 if (count == 0) {
2302 cy_as_hal_enable_interrupts(
2303 dev_p->stby_int_mask);
2304 return CY_AS_ERROR_TIMEOUT;
2305 }
2306
2307
2308
2309
2310
2311
2312
2313 cy_as_device_clear_register_standby(dev_p);
2314
2315
2316
2317
2318
2319 cy_as_hal_init_dev_registers(dev_p->tag, cy_true);
2320 } else if (cy_as_device_is_pin_standby(dev_p)) {
2321
2322
2323
2324
2325 cy_as_device_set_waking(dev_p);
2326
2327try_wakeup_again:
2328
2329
2330
2331
2332 if (!cy_as_hal_set_wakeup_pin(dev_p->tag, cy_true)) {
2333 cy_as_hal_enable_interrupts(dev_p->stby_int_mask);
2334 return CY_AS_ERROR_SETTING_WAKEUP_PIN;
2335 }
2336
2337
2338
2339
2340
2341
2342
2343 if (cy_as_device_is_crystal(dev_p))
2344 cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL);
2345 else
2346 cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK);
2347
2348
2349
2350
2351
2352 cy_as_hal_init_dev_registers(dev_p->tag, cy_true);
2353
2354
2355
2356
2357
2358
2359
2360 cy_as_device_clear_pin_standby(dev_p);
2361 } else {
2362 return CY_AS_ERROR_NOT_IN_STANDBY;
2363 }
2364
2365
2366
2367
2368 cy_as_hal_enable_interrupts(dev_p->stby_int_mask);
2369
2370
2371
2372
2373
2374
2375 v = 0x03;
2376 count = 0x08;
2377 while ((v & 0x03) && (count)) {
2378 cy_as_hal_write_register(dev_p->tag,
2379 CY_AS_MEM_RST_CTRL_REG, 0x00);
2380 v = cy_as_hal_read_register(dev_p->tag,
2381 CY_AS_MEM_RST_CTRL_REG);
2382 count--;
2383 }
2384
2385 if (v & 0x03) {
2386 cy_as_hal_print_message("failed to clear antioch reset\n");
2387 return CY_AS_ERROR_TIMEOUT;
2388 }
2389
2390
2391
2392
2393
2394
2395
2396 if (retry) {
2397 count = 10;
2398 while (count) {
2399
2400
2401 if (cy_as_device_is_firmware_loaded(dev_p))
2402 break;
2403
2404
2405
2406
2407
2408 v = cy_as_hal_read_register(dev_p->tag,
2409 CY_AS_MEM_P0_INTR_REG);
2410 if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
2411 break;
2412
2413 cy_as_hal_sleep(10);
2414 count--;
2415 }
2416
2417 if (!count) {
2418 retry = 0;
2419 dev_p->stby_int_mask = cy_as_hal_disable_interrupts();
2420 cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false);
2421 cy_as_hal_sleep(10);
2422 goto try_wakeup_again;
2423 }
2424 }
2425
2426 return ret;
2427}
2428
2429cy_as_return_status_t
2430cy_as_misc_register_callback(
2431
2432 cy_as_device_handle handle,
2433
2434 cy_as_misc_event_callback callback
2435 )
2436{
2437 cy_as_device *dev_p;
2438
2439 cy_as_log_debug_message(6, "cy_as_misc_register_callback called");
2440
2441
2442 dev_p = (cy_as_device *)handle;
2443 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2444 return CY_AS_ERROR_INVALID_HANDLE;
2445
2446 dev_p->misc_event_cb = callback;
2447 return CY_AS_ERROR_SUCCESS;
2448}
2449
2450cy_as_return_status_t
2451cy_as_misc_storage_changed(cy_as_device_handle handle,
2452 cy_as_function_callback cb,
2453 uint32_t client)
2454{
2455 cy_as_device *dev_p;
2456 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2457 cy_bool standby;
2458 cy_as_ll_request_response *req_p, *reply_p;
2459
2460 cy_as_log_debug_message(6, "cy_as_misc_storage_changed called");
2461
2462
2463 dev_p = (cy_as_device *)handle;
2464 cy_as_check_device_ready(dev_p);
2465
2466
2467
2468
2469 ret = cy_as_misc_in_standby(dev_p, &standby);
2470 if (ret != CY_AS_ERROR_SUCCESS)
2471 return ret;
2472
2473 if (standby)
2474 return CY_AS_ERROR_IN_STANDBY;
2475
2476
2477
2478
2479 if (cy_as_device_is_in_suspend_mode(dev_p))
2480 return CY_AS_ERROR_IN_SUSPEND;
2481
2482
2483 req_p = cy_as_ll_create_request(dev_p, CY_RQT_STORAGE_MEDIA_CHANGED,
2484 CY_RQT_GENERAL_RQT_CONTEXT, 0);
2485 if (req_p == 0)
2486 return CY_AS_ERROR_OUT_OF_MEMORY;
2487
2488
2489
2490 reply_p = cy_as_ll_create_response(dev_p, 1);
2491 if (reply_p == 0) {
2492 cy_as_ll_destroy_request(dev_p, req_p);
2493 return CY_AS_ERROR_OUT_OF_MEMORY;
2494 }
2495
2496 if (cb == 0) {
2497 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2498 if (ret != CY_AS_ERROR_SUCCESS)
2499 goto destroy;
2500
2501 if (cy_as_ll_request_response__get_code(reply_p) !=
2502 CY_RESP_SUCCESS_FAILURE) {
2503 ret = CY_AS_ERROR_INVALID_RESPONSE;
2504 goto destroy;
2505 }
2506
2507 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2508 } else {
2509
2510 ret = cy_as_misc_send_request(dev_p, cb, client,
2511 CY_FUNCT_CB_MISC_STORAGECHANGED, 0,
2512 dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
2513 req_p, reply_p, cy_as_misc_func_callback);
2514
2515 if (ret != CY_AS_ERROR_SUCCESS)
2516 goto destroy;
2517
2518
2519
2520 return ret;
2521 }
2522
2523destroy:
2524 cy_as_ll_destroy_request(dev_p, req_p);
2525 cy_as_ll_destroy_response(dev_p, reply_p);
2526
2527 return ret;
2528}
2529
2530
2531cy_as_return_status_t
2532cy_as_misc_enter_suspend(
2533 cy_as_device_handle handle,
2534 cy_bool usb_wakeup_en,
2535 cy_bool gpio_wakeup_en,
2536 cy_as_function_callback cb,
2537 uint32_t client)
2538{
2539 cy_as_device *dev_p;
2540 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2541 cy_bool standby;
2542 cy_as_ll_request_response *req_p, *reply_p;
2543 uint16_t value;
2544 uint32_t int_state;
2545
2546 cy_as_log_debug_message(6, "cy_as_misc_enter_suspend called");
2547
2548
2549
2550
2551 dev_p = (cy_as_device *)handle;
2552 cy_as_check_device_ready(dev_p);
2553
2554
2555
2556
2557 cy_as_misc_in_standby(dev_p, &standby);
2558 if (standby)
2559 return CY_AS_ERROR_IN_STANDBY;
2560
2561
2562
2563
2564 if (cy_as_device_is_in_suspend_mode(dev_p))
2565 return CY_AS_ERROR_IN_SUSPEND;
2566
2567
2568
2569
2570 if ((cy_as_device_is_usb_connected(dev_p)) && (dev_p->usb_last_event
2571 != cy_as_event_usb_suspend))
2572 return CY_AS_ERROR_USB_CONNECTED;
2573
2574
2575
2576
2577 int_state = cy_as_hal_disable_interrupts();
2578 if ((dev_p->func_cbs_misc->count) || (dev_p->func_cbs_res->count) ||
2579 (dev_p->func_cbs_stor->count) || (dev_p->func_cbs_usb->count)) {
2580 cy_as_hal_enable_interrupts(int_state);
2581 return CY_AS_ERROR_ASYNC_PENDING;
2582 }
2583 cy_as_hal_enable_interrupts(int_state);
2584
2585
2586 req_p = cy_as_ll_create_request(dev_p, CY_RQT_ENTER_SUSPEND_MODE,
2587 CY_RQT_GENERAL_RQT_CONTEXT, 1);
2588 if (req_p == 0)
2589 return CY_AS_ERROR_OUT_OF_MEMORY;
2590
2591
2592
2593 reply_p = cy_as_ll_create_response(dev_p, 1);
2594 if (reply_p == 0) {
2595 cy_as_ll_destroy_request(dev_p, req_p);
2596 return CY_AS_ERROR_OUT_OF_MEMORY;
2597 }
2598
2599
2600 value = 0x0001;
2601 if (usb_wakeup_en)
2602 value |= 0x04;
2603 if (gpio_wakeup_en)
2604 value |= 0x02;
2605 cy_as_ll_request_response__set_word(req_p, 0, value);
2606
2607 if (cb != 0) {
2608
2609 ret = cy_as_misc_send_request(dev_p, cb, client,
2610 CY_FUNCT_CB_MISC_ENTERSUSPEND,
2611 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
2612 req_p, reply_p,
2613 cy_as_misc_func_callback);
2614
2615 if (ret != CY_AS_ERROR_SUCCESS)
2616 goto destroy;
2617
2618 return CY_AS_ERROR_SUCCESS;
2619 } else {
2620 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2621 if (cy_as_ll_request_response__get_code(reply_p) !=
2622 CY_RESP_SUCCESS_FAILURE)
2623 ret = CY_AS_ERROR_INVALID_RESPONSE;
2624 else
2625 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2626 }
2627
2628destroy:
2629 if (ret == CY_AS_ERROR_SUCCESS)
2630 cy_as_device_set_suspend_mode(dev_p);
2631
2632 cy_as_ll_destroy_request(dev_p, req_p);
2633 cy_as_ll_destroy_response(dev_p, reply_p);
2634
2635 return ret;
2636}
2637
2638cy_as_return_status_t
2639cy_as_misc_leave_suspend(
2640 cy_as_device_handle handle,
2641 cy_as_function_callback cb,
2642 uint32_t client)
2643{
2644 cy_as_device *dev_p;
2645 uint16_t v, count;
2646 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2647
2648 cy_as_log_debug_message(6, "cy_as_misc_leave_suspend called");
2649
2650
2651 dev_p = (cy_as_device *)handle;
2652 cy_as_check_device_ready(dev_p);
2653
2654
2655 if (cy_as_device_is_in_suspend_mode(dev_p)) {
2656 if (cb) {
2657 cy_as_func_c_b_node *cbnode =
2658 cy_as_create_func_c_b_node_data(cb, client,
2659 CY_FUNCT_CB_MISC_LEAVESUSPEND, 0);
2660 if (cbnode == 0)
2661 return CY_AS_ERROR_OUT_OF_MEMORY;
2662
2663 cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode);
2664 }
2665
2666
2667
2668
2669
2670
2671 count = 8;
2672
2673 v = cy_as_hal_read_register(dev_p->tag,
2674 CY_AS_MEM_CM_WB_CFG_ID);
2675
2676 while (!is_valid_silicon_id(v) && count-- > 0) {
2677 cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK);
2678 v = cy_as_hal_read_register(dev_p->tag,
2679 CY_AS_MEM_CM_WB_CFG_ID);
2680 }
2681
2682
2683
2684
2685
2686 if (count == 0)
2687 return CY_AS_ERROR_TIMEOUT;
2688 } else
2689 return CY_AS_ERROR_NOT_IN_SUSPEND;
2690
2691 if (cb == 0) {
2692
2693
2694
2695 count = 20;
2696 while ((cy_as_device_is_in_suspend_mode(dev_p))
2697 && (count--)) {
2698 cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK);
2699 }
2700
2701 if (cy_as_device_is_in_suspend_mode(dev_p))
2702 ret = CY_AS_ERROR_TIMEOUT;
2703 }
2704
2705 return ret;
2706}
2707
2708cy_as_return_status_t
2709cy_as_misc_reserve_l_n_a_boot_area(cy_as_device_handle handle,
2710 uint8_t numzones,
2711 cy_as_function_callback cb,
2712 uint32_t client)
2713{
2714 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2715 cy_bool standby;
2716 cy_as_ll_request_response *req_p, *reply_p;
2717
2718 cy_as_device *dev_p;
2719
2720 (void)client;
2721
2722 cy_as_log_debug_message(6, "cy_as_misc_switch_pnand_mode called");
2723
2724
2725 dev_p = (cy_as_device *)handle;
2726 cy_as_check_device_ready(dev_p);
2727
2728
2729
2730
2731 ret = cy_as_misc_in_standby(dev_p, &standby);
2732 if (ret != CY_AS_ERROR_SUCCESS)
2733 return ret;
2734 if (standby)
2735 return CY_AS_ERROR_IN_STANDBY;
2736
2737
2738 if (cy_as_device_is_in_suspend_mode(dev_p))
2739 return CY_AS_ERROR_IN_SUSPEND;
2740
2741
2742 req_p = cy_as_ll_create_request(dev_p,
2743 CY_RQT_RESERVE_LNA_BOOT_AREA,
2744 CY_RQT_GENERAL_RQT_CONTEXT, 1);
2745 if (req_p == 0)
2746 return CY_AS_ERROR_OUT_OF_MEMORY;
2747 cy_as_ll_request_response__set_word(req_p,
2748 0, (uint16_t)numzones);
2749
2750
2751
2752 reply_p = cy_as_ll_create_response(dev_p, 1);
2753 if (reply_p == 0) {
2754 cy_as_ll_destroy_request(dev_p, req_p);
2755 return CY_AS_ERROR_OUT_OF_MEMORY;
2756 }
2757
2758 if (cb == 0) {
2759 ret = cy_as_ll_send_request_wait_reply(dev_p,
2760 req_p, reply_p);
2761 if (ret != CY_AS_ERROR_SUCCESS)
2762 goto destroy;
2763
2764 if (cy_as_ll_request_response__get_code(reply_p) !=
2765 CY_RESP_SUCCESS_FAILURE) {
2766 ret = CY_AS_ERROR_INVALID_RESPONSE;
2767 goto destroy;
2768 }
2769
2770 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2771 } else {
2772
2773 ret = cy_as_misc_send_request(dev_p, cb, client,
2774 CY_FUNCT_CB_MISC_RESERVELNABOOTAREA,
2775 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
2776 req_p, reply_p, cy_as_misc_func_callback);
2777
2778 if (ret != CY_AS_ERROR_SUCCESS)
2779 goto destroy;
2780
2781
2782
2783 return ret;
2784 }
2785
2786destroy:
2787 cy_as_ll_destroy_request(dev_p, req_p);
2788 cy_as_ll_destroy_response(dev_p, reply_p);
2789
2790 return ret;
2791}
2792
2793cy_as_func_c_b_node*
2794cy_as_create_func_c_b_node_data(cy_as_function_callback cb,
2795 uint32_t client,
2796 cy_as_funct_c_b_type type,
2797 void *data)
2798{
2799 uint32_t state = cy_as_hal_disable_interrupts();
2800 cy_as_func_c_b_node *node = cy_as_hal_c_b_alloc(
2801 sizeof(cy_as_func_c_b_node));
2802 cy_as_hal_enable_interrupts(state);
2803 if (node != 0) {
2804 node->node_type = CYAS_FUNC_CB;
2805 node->cb_p = cb;
2806 node->client_data = client;
2807 node->data_type = type;
2808 if (data != 0)
2809 node->data_type |= CY_FUNCT_CB_DATA;
2810 else
2811 node->data_type |= CY_FUNCT_CB_NODATA;
2812 node->data = data;
2813 node->next_p = 0;
2814 }
2815 return node;
2816}
2817
2818cy_as_func_c_b_node*
2819cy_as_create_func_c_b_node(cy_as_function_callback cb,
2820 uint32_t client)
2821{
2822 return cy_as_create_func_c_b_node_data(cb, client,
2823 CY_FUNCT_CB_NODATA, 0);
2824}
2825
2826void
2827cy_as_destroy_func_c_b_node(cy_as_func_c_b_node *node)
2828{
2829 uint32_t state;
2830
2831 node->node_type = CYAS_INVALID;
2832 state = cy_as_hal_disable_interrupts();
2833 cy_as_hal_c_b_free(node);
2834 cy_as_hal_enable_interrupts(state);
2835}
2836
2837cy_as_usb_func_c_b_node*
2838cy_as_create_usb_func_c_b_node(
2839 cy_as_usb_function_callback cb, uint32_t client)
2840{
2841 uint32_t state = cy_as_hal_disable_interrupts();
2842 cy_as_usb_func_c_b_node *node = cy_as_hal_c_b_alloc(
2843 sizeof(cy_as_usb_func_c_b_node));
2844 cy_as_hal_enable_interrupts(state);
2845 if (node != 0) {
2846 node->type = CYAS_USB_FUNC_CB;
2847 node->cb_p = cb;
2848 node->client_data = client;
2849 node->next_p = 0;
2850 }
2851 return node;
2852}
2853
2854void
2855cy_as_destroy_usb_func_c_b_node(cy_as_usb_func_c_b_node *node)
2856{
2857 uint32_t state;
2858
2859 node->type = CYAS_INVALID;
2860 state = cy_as_hal_disable_interrupts();
2861 cy_as_hal_c_b_free(node);
2862 cy_as_hal_enable_interrupts(state);
2863}
2864
2865cy_as_usb_io_c_b_node*
2866cy_as_create_usb_io_c_b_node(cy_as_usb_io_callback cb)
2867{
2868 uint32_t state = cy_as_hal_disable_interrupts();
2869 cy_as_usb_io_c_b_node *node = cy_as_hal_c_b_alloc(
2870 sizeof(cy_as_usb_io_c_b_node));
2871 cy_as_hal_enable_interrupts(state);
2872 if (node != 0) {
2873 node->type = CYAS_USB_IO_CB;
2874 node->cb_p = cb;
2875 node->next_p = 0;
2876 }
2877 return node;
2878}
2879
2880void
2881cy_as_destroy_usb_io_c_b_node(cy_as_usb_io_c_b_node *node)
2882{
2883 uint32_t state;
2884
2885 node->type = CYAS_INVALID;
2886
2887 state = cy_as_hal_disable_interrupts();
2888 cy_as_hal_c_b_free(node);
2889 cy_as_hal_enable_interrupts(state);
2890}
2891
2892cy_as_storage_io_c_b_node*
2893cy_as_create_storage_io_c_b_node(cy_as_storage_callback cb,
2894 cy_as_media_type media, uint32_t device_index,
2895 uint32_t unit, uint32_t block_addr, cy_as_oper_type oper,
2896 cy_as_ll_request_response *req_p,
2897 cy_as_ll_request_response *reply_p)
2898{
2899 uint32_t state = cy_as_hal_disable_interrupts();
2900 cy_as_storage_io_c_b_node *node = cy_as_hal_c_b_alloc(
2901 sizeof(cy_as_storage_io_c_b_node));
2902 cy_as_hal_enable_interrupts(state);
2903 if (node != 0) {
2904 node->type = CYAS_STORAGE_IO_CB;
2905 node->cb_p = cb;
2906 node->media = media;
2907 node->device_index = device_index;
2908 node->unit = unit;
2909 node->block_addr = block_addr;
2910 node->oper = oper;
2911 node->req_p = req_p;
2912 node->reply_p = reply_p;
2913 node->next_p = 0;
2914 }
2915 return node;
2916}
2917
2918void
2919cy_as_destroy_storage_io_c_b_node(cy_as_storage_io_c_b_node *node)
2920{
2921 uint32_t state;
2922 node->type = CYAS_INVALID;
2923 state = cy_as_hal_disable_interrupts();
2924 cy_as_hal_c_b_free(node);
2925 cy_as_hal_enable_interrupts(state);
2926}
2927
2928cy_as_c_b_queue *
2929cy_as_create_c_b_queue(cy_as_c_b_node_type type)
2930{
2931 uint32_t state = cy_as_hal_disable_interrupts();
2932 cy_as_c_b_queue *queue = cy_as_hal_c_b_alloc(
2933 sizeof(cy_as_c_b_queue));
2934 cy_as_hal_enable_interrupts(state);
2935 if (queue) {
2936 queue->type = type;
2937 queue->head_p = 0;
2938 queue->tail_p = 0;
2939 queue->count = 0;
2940 }
2941
2942 return queue;
2943}
2944
2945void
2946cy_as_destroy_c_b_queue(cy_as_c_b_queue *queue)
2947{
2948 uint32_t state;
2949 queue->type = CYAS_INVALID;
2950 queue->head_p = 0;
2951 queue->tail_p = 0;
2952 queue->count = 0;
2953 state = cy_as_hal_disable_interrupts();
2954 cy_as_hal_c_b_free(queue);
2955 cy_as_hal_enable_interrupts(state);
2956}
2957
2958
2959
2960void
2961cy_as_insert_c_b_node(cy_as_c_b_queue *queue_p, void*cbnode)
2962{
2963 uint32_t int_state;
2964
2965 int_state = cy_as_hal_disable_interrupts();
2966
2967 cy_as_hal_assert(queue_p != 0);
2968
2969 switch (queue_p->type) {
2970 case CYAS_USB_FUNC_CB:
2971 {
2972 cy_as_usb_func_c_b_node *node =
2973 (cy_as_usb_func_c_b_node *)cbnode;
2974 cy_as_usb_func_c_b_node *tail =
2975 (cy_as_usb_func_c_b_node *)queue_p->tail_p;
2976
2977 cy_as_hal_assert(node->type == CYAS_USB_FUNC_CB);
2978 cy_as_hal_assert(tail == 0 ||
2979 tail->type == CYAS_USB_FUNC_CB);
2980 if (queue_p->head_p == 0)
2981 queue_p->head_p = node;
2982 else
2983 tail->next_p = node;
2984
2985 queue_p->tail_p = node;
2986 }
2987 break;
2988
2989 case CYAS_USB_IO_CB:
2990 {
2991 cy_as_usb_io_c_b_node *node =
2992 (cy_as_usb_io_c_b_node *)cbnode;
2993 cy_as_usb_io_c_b_node *tail =
2994 (cy_as_usb_io_c_b_node *)queue_p->tail_p;
2995
2996 cy_as_hal_assert(node->type == CYAS_USB_IO_CB);
2997 cy_as_hal_assert(tail == 0 ||
2998 tail->type == CYAS_USB_IO_CB);
2999 if (queue_p->head_p == 0)
3000 queue_p->head_p = node;
3001 else
3002 tail->next_p = node;
3003
3004 queue_p->tail_p = node;
3005 }
3006 break;
3007
3008 case CYAS_STORAGE_IO_CB:
3009 {
3010 cy_as_storage_io_c_b_node *node =
3011 (cy_as_storage_io_c_b_node *)cbnode;
3012 cy_as_storage_io_c_b_node *tail =
3013 (cy_as_storage_io_c_b_node *)queue_p->tail_p;
3014
3015 cy_as_hal_assert(node->type == CYAS_STORAGE_IO_CB);
3016 cy_as_hal_assert(tail == 0 ||
3017 tail->type == CYAS_STORAGE_IO_CB);
3018 if (queue_p->head_p == 0)
3019 queue_p->head_p = node;
3020 else
3021 tail->next_p = node;
3022
3023 queue_p->tail_p = node;
3024 }
3025 break;
3026
3027 case CYAS_FUNC_CB:
3028 {
3029 cy_as_func_c_b_node *node =
3030 (cy_as_func_c_b_node *)cbnode;
3031 cy_as_func_c_b_node *tail =
3032 (cy_as_func_c_b_node *)queue_p->tail_p;
3033
3034 cy_as_hal_assert(node->node_type == CYAS_FUNC_CB);
3035 cy_as_hal_assert(tail == 0 ||
3036 tail->node_type == CYAS_FUNC_CB);
3037 if (queue_p->head_p == 0)
3038 queue_p->head_p = node;
3039 else
3040 tail->next_p = node;
3041
3042 queue_p->tail_p = node;
3043 }
3044 break;
3045
3046 default:
3047 cy_as_hal_assert(cy_false);
3048 break;
3049 }
3050
3051 queue_p->count++;
3052
3053 cy_as_hal_enable_interrupts(int_state);
3054}
3055
3056
3057void
3058cy_as_remove_c_b_tail_node(cy_as_c_b_queue *queue_p)
3059{
3060 uint32_t int_state;
3061
3062 int_state = cy_as_hal_disable_interrupts();
3063
3064 if (queue_p->count > 0) {
3065
3066
3067
3068
3069
3070
3071 switch (queue_p->type) {
3072 case CYAS_FUNC_CB:
3073 {
3074 cy_as_func_c_b_node *node =
3075 (cy_as_func_c_b_node *)
3076 queue_p->head_p;
3077 cy_as_func_c_b_node *tail =
3078 (cy_as_func_c_b_node *)
3079 queue_p->tail_p;
3080 if (node != tail) {
3081 while (node->next_p != tail)
3082 node = node->next_p;
3083 node->next_p = 0;
3084 queue_p->tail_p = node;
3085 }
3086 cy_as_destroy_func_c_b_node(tail);
3087 }
3088 break;
3089
3090 case CYAS_USB_FUNC_CB:
3091 {
3092 cy_as_usb_func_c_b_node *node =
3093 (cy_as_usb_func_c_b_node *)
3094 queue_p->head_p;
3095 cy_as_usb_func_c_b_node *tail =
3096 (cy_as_usb_func_c_b_node *)
3097 queue_p->tail_p;
3098 if (node != tail) {
3099 while (node->next_p != tail)
3100 node = node->next_p;
3101 node->next_p = 0;
3102 queue_p->tail_p = node;
3103 }
3104
3105 cy_as_destroy_usb_func_c_b_node(tail);
3106 }
3107 break;
3108
3109 case CYAS_USB_IO_CB:
3110 {
3111 cy_as_usb_io_c_b_node *node =
3112 (cy_as_usb_io_c_b_node *)
3113 queue_p->head_p;
3114 cy_as_usb_io_c_b_node *tail =
3115 (cy_as_usb_io_c_b_node *)
3116 queue_p->tail_p;
3117 if (node != tail) {
3118 while (node->next_p != tail)
3119 node = node->next_p;
3120 node->next_p = 0;
3121 queue_p->tail_p = node;
3122 }
3123 cy_as_destroy_usb_io_c_b_node(tail);
3124 }
3125 break;
3126
3127 case CYAS_STORAGE_IO_CB:
3128 {
3129 cy_as_storage_io_c_b_node *node =
3130 (cy_as_storage_io_c_b_node *)
3131 queue_p->head_p;
3132 cy_as_storage_io_c_b_node *tail =
3133 (cy_as_storage_io_c_b_node *)
3134 queue_p->tail_p;
3135 if (node != tail) {
3136 while (node->next_p != tail)
3137 node = node->next_p;
3138 node->next_p = 0;
3139 queue_p->tail_p = node;
3140 }
3141 cy_as_destroy_storage_io_c_b_node(tail);
3142 }
3143 break;
3144
3145 default:
3146 cy_as_hal_assert(cy_false);
3147 }
3148
3149 queue_p->count--;
3150 if (queue_p->count == 0) {
3151 queue_p->head_p = 0;
3152 queue_p->tail_p = 0;
3153 }
3154 }
3155
3156 cy_as_hal_enable_interrupts(int_state);
3157}
3158
3159
3160void
3161cy_as_remove_c_b_node(cy_as_c_b_queue *queue_p)
3162{
3163 uint32_t int_state;
3164
3165 int_state = cy_as_hal_disable_interrupts();
3166
3167 cy_as_hal_assert(queue_p->count >= 0);
3168 if (queue_p->count > 0) {
3169 if (queue_p->type == CYAS_USB_FUNC_CB) {
3170 cy_as_usb_func_c_b_node *node =
3171 (cy_as_usb_func_c_b_node *)
3172 queue_p->head_p;
3173 queue_p->head_p = node->next_p;
3174 cy_as_destroy_usb_func_c_b_node(node);
3175 } else if (queue_p->type == CYAS_USB_IO_CB) {
3176 cy_as_usb_io_c_b_node *node =
3177 (cy_as_usb_io_c_b_node *)
3178 queue_p->head_p;
3179 queue_p->head_p = node->next_p;
3180 cy_as_destroy_usb_io_c_b_node(node);
3181 } else if (queue_p->type == CYAS_STORAGE_IO_CB) {
3182 cy_as_storage_io_c_b_node *node =
3183 (cy_as_storage_io_c_b_node *)
3184 queue_p->head_p;
3185 queue_p->head_p = node->next_p;
3186 cy_as_destroy_storage_io_c_b_node(node);
3187 } else if (queue_p->type == CYAS_FUNC_CB) {
3188 cy_as_func_c_b_node *node =
3189 (cy_as_func_c_b_node *)
3190 queue_p->head_p;
3191 queue_p->head_p = node->next_p;
3192 cy_as_destroy_func_c_b_node(node);
3193 } else {
3194 cy_as_hal_assert(cy_false);
3195 }
3196
3197 queue_p->count--;
3198 if (queue_p->count == 0) {
3199 queue_p->head_p = 0;
3200 queue_p->tail_p = 0;
3201 }
3202 }
3203
3204 cy_as_hal_enable_interrupts(int_state);
3205}
3206
3207void my_print_func_c_b_node(cy_as_func_c_b_node *node)
3208{
3209 cy_as_funct_c_b_type type =
3210 cy_as_funct_c_b_type_get_type(node->data_type);
3211 cy_as_hal_print_message("[cd:%2u dt:%2u cb:0x%08x "
3212 "d:0x%08x nt:%1i]", node->client_data, type,
3213 (uint32_t)node->cb_p, (uint32_t)node->data,
3214 node->node_type);
3215}
3216
3217void my_print_c_b_queue(cy_as_c_b_queue *queue_p)
3218{
3219 uint32_t i = 0;
3220
3221 cy_as_hal_print_message("| count: %u type: ", queue_p->count);
3222
3223 if (queue_p->type == CYAS_USB_FUNC_CB) {
3224 cy_as_hal_print_message("USB_FUNC_CB\n");
3225 } else if (queue_p->type == CYAS_USB_IO_CB) {
3226 cy_as_hal_print_message("USB_IO_CB\n");
3227 } else if (queue_p->type == CYAS_STORAGE_IO_CB) {
3228 cy_as_hal_print_message("STORAGE_IO_CB\n");
3229 } else if (queue_p->type == CYAS_FUNC_CB) {
3230 cy_as_func_c_b_node *node = queue_p->head_p;
3231 cy_as_hal_print_message("FUNC_CB\n");
3232 if (queue_p->count > 0) {
3233 cy_as_hal_print_message("| head->");
3234
3235 for (i = 0; i < queue_p->count; i++) {
3236 if (node) {
3237 cy_as_hal_print_message("->");
3238 my_print_func_c_b_node(node);
3239 node = node->next_p;
3240 } else
3241 cy_as_hal_print_message("->[NULL]\n");
3242 }
3243
3244 cy_as_hal_print_message("\n| tail->");
3245 my_print_func_c_b_node(queue_p->tail_p);
3246 cy_as_hal_print_message("\n");
3247 }
3248 } else {
3249 cy_as_hal_print_message("INVALID\n");
3250 }
3251
3252 cy_as_hal_print_message("|----------\n");
3253}
3254
3255
3256
3257void
3258cy_as_clear_c_b_queue(cy_as_c_b_queue *queue_p)
3259{
3260 uint32_t int_state = cy_as_hal_disable_interrupts();
3261
3262 while (queue_p->count != 0)
3263 cy_as_remove_c_b_node(queue_p);
3264
3265 cy_as_hal_enable_interrupts(int_state);
3266}
3267
3268cy_as_return_status_t
3269cy_as_misc_send_request(cy_as_device *dev_p,
3270 cy_as_function_callback cb,
3271 uint32_t client,
3272 cy_as_funct_c_b_type type,
3273 void *data,
3274 cy_as_c_b_queue *queue,
3275 uint16_t req_type,
3276 cy_as_ll_request_response *req_p,
3277 cy_as_ll_request_response *reply_p,
3278 cy_as_response_callback rcb)
3279{
3280
3281 cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data(cb,
3282 client, type, data);
3283 cy_as_return_status_t ret;
3284
3285 if (cbnode == 0)
3286 return CY_AS_ERROR_OUT_OF_MEMORY;
3287 else
3288 cy_as_insert_c_b_node(queue, cbnode);
3289
3290 req_p->flags |= req_type;
3291
3292 ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_false, rcb);
3293 if (ret != CY_AS_ERROR_SUCCESS)
3294 cy_as_remove_c_b_tail_node(queue);
3295
3296 return ret;
3297}
3298
3299void
3300cy_as_misc_cancel_ex_requests(cy_as_device *dev_p)
3301{
3302 int i;
3303 for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++)
3304 cy_as_ll_remove_all_requests(dev_p, dev_p->context[i]);
3305}
3306
3307
3308static void
3309cy_as_misc_func_callback(cy_as_device *dev_p,
3310 uint8_t context,
3311 cy_as_ll_request_response *rqt,
3312 cy_as_ll_request_response *resp,
3313 cy_as_return_status_t stat)
3314{
3315 cy_as_func_c_b_node *node = NULL;
3316 cy_as_return_status_t ret;
3317
3318 cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX)
3319 == CY_AS_REQUEST_RESPONSE_EX;
3320 cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS)
3321 == CY_AS_REQUEST_RESPONSE_MS;
3322 uint8_t code;
3323 uint32_t type;
3324 uint8_t cntxt;
3325
3326 cy_as_hal_assert(ex_request || ms_request);
3327 (void) ex_request;
3328 (void) ms_request;
3329 (void)context;
3330
3331 cntxt = cy_as_ll_request_response__get_context(rqt);
3332 code = cy_as_ll_request_response__get_code(rqt);
3333
3334 switch (cntxt) {
3335 case CY_RQT_GENERAL_RQT_CONTEXT:
3336 cy_as_hal_assert(dev_p->func_cbs_misc->count != 0);
3337 cy_as_hal_assert(dev_p->func_cbs_misc->type == CYAS_FUNC_CB);
3338 node = (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p;
3339 type = cy_as_funct_c_b_type_get_type(node->data_type);
3340
3341 switch (code) {
3342 case CY_RQT_GET_FIRMWARE_VERSION:
3343 cy_as_hal_assert(node->data != 0);
3344 cy_as_hal_assert(type ==
3345 CY_FUNCT_CB_MISC_GETFIRMWAREVERSION);
3346 ret = my_handle_response_get_firmware_version(dev_p,
3347 rqt, resp,
3348 (cy_as_get_firmware_version_data *)node->data);
3349 break;
3350 case CY_RQT_READ_MCU_REGISTER:
3351 cy_as_hal_assert(node->data != 0);
3352 cy_as_hal_assert(type ==
3353 CY_FUNCT_CB_MISC_READMCUREGISTER);
3354 ret = my_handle_response_read_m_c_u_register(dev_p, rqt,
3355 resp, (uint8_t *)node->data);
3356 break;
3357 case CY_RQT_GET_GPIO_STATE:
3358 cy_as_hal_assert(node->data != 0);
3359 cy_as_hal_assert(type ==
3360 CY_FUNCT_CB_MISC_GETGPIOVALUE);
3361 ret = my_handle_response_get_gpio_value(dev_p, rqt,
3362 resp, (uint8_t *)node->data);
3363 break;
3364 case CY_RQT_SET_SD_CLOCK_FREQ:
3365 cy_as_hal_assert(type == CY_FUNCT_CB_MISC_SETSDFREQ);
3366 ret = my_handle_response_no_data(dev_p, rqt, resp);
3367 break;
3368 case CY_RQT_CONTROL_ANTIOCH_HEARTBEAT:
3369 cy_as_hal_assert(type ==
3370 CY_FUNCT_CB_MISC_HEARTBEATCONTROL);
3371 ret = my_handle_response_no_data(dev_p, rqt, resp);
3372 break;
3373 case CY_RQT_WRITE_MCU_REGISTER:
3374 cy_as_hal_assert(type ==
3375 CY_FUNCT_CB_MISC_WRITEMCUREGISTER);
3376 ret = my_handle_response_no_data(dev_p, rqt, resp);
3377 break;
3378 case CY_RQT_STORAGE_MEDIA_CHANGED:
3379 cy_as_hal_assert(type ==
3380 CY_FUNCT_CB_MISC_STORAGECHANGED);
3381 ret = my_handle_response_no_data(dev_p, rqt, resp);
3382 break;
3383 case CY_RQT_SET_GPIO_STATE:
3384 cy_as_hal_assert(type ==
3385 CY_FUNCT_CB_MISC_SETGPIOVALUE);
3386 ret = my_handle_response_no_data(dev_p, rqt, resp);
3387 break;
3388 case CY_RQT_SET_TRACE_LEVEL:
3389 cy_as_hal_assert(type ==
3390 CY_FUNCT_CB_MISC_SETTRACELEVEL);
3391 ret = my_handle_response_no_data(dev_p, rqt, resp);
3392 if (ret == CY_AS_ERROR_INVALID_RESPONSE)
3393 ret = CY_AS_ERROR_NOT_SUPPORTED;
3394 break;
3395 case CY_RQT_PREPARE_FOR_STANDBY:
3396 cy_as_hal_assert(type ==
3397 CY_FUNCT_CB_MISC_ENTERSTANDBY);
3398 ret = my_handle_response_enter_standby(dev_p, rqt, resp,
3399 (cy_bool)node->data);
3400 break;
3401 case CY_RQT_ENTER_SUSPEND_MODE:
3402 cy_as_hal_assert(type ==
3403 CY_FUNCT_CB_MISC_ENTERSUSPEND);
3404 ret = my_handle_response_no_data(dev_p, rqt, resp);
3405 if (ret == CY_AS_ERROR_SUCCESS)
3406 cy_as_device_set_suspend_mode(dev_p);
3407
3408 break;
3409 case CY_RQT_RESERVE_LNA_BOOT_AREA:
3410 cy_as_hal_assert(type ==
3411 CY_FUNCT_CB_MISC_RESERVELNABOOTAREA);
3412 ret = my_handle_response_no_data(dev_p, rqt, resp);
3413 break;
3414 case CY_RQT_SDPOLARITY:
3415 cy_as_hal_assert(type ==
3416 CY_FUNCT_CB_MISC_SETSDPOLARITY);
3417 ret = my_handle_response_no_data(dev_p, rqt, resp);
3418 break;
3419 default:
3420 ret = CY_AS_ERROR_INVALID_RESPONSE;
3421 cy_as_hal_assert(cy_false);
3422 break;
3423 }
3424 break;
3425
3426 case CY_RQT_RESOURCE_RQT_CONTEXT:
3427 cy_as_hal_assert(dev_p->func_cbs_res->count != 0);
3428 cy_as_hal_assert(dev_p->func_cbs_res->type == CYAS_FUNC_CB);
3429 node = (cy_as_func_c_b_node *)dev_p->func_cbs_res->head_p;
3430 type = cy_as_funct_c_b_type_get_type(node->data_type);
3431
3432 switch (code) {
3433 case CY_RQT_ACQUIRE_RESOURCE:
3434
3435
3436 cy_as_hal_assert(type ==
3437 CY_FUNCT_CB_MISC_ACQUIRERESOURCE);
3438 ret = my_handle_response_acquire_resource(dev_p, rqt,
3439 resp, (cy_as_resource_type *)node->data);
3440 break;
3441 default:
3442 ret = CY_AS_ERROR_INVALID_RESPONSE;
3443 cy_as_hal_assert(cy_false);
3444 break;
3445 }
3446 break;
3447
3448 default:
3449 ret = CY_AS_ERROR_INVALID_RESPONSE;
3450 cy_as_hal_assert(cy_false);
3451 break;
3452 }
3453
3454
3455
3456
3457
3458
3459 if (stat == CY_AS_ERROR_SUCCESS)
3460 stat = ret;
3461
3462
3463 node->cb_p((cy_as_device_handle)dev_p, stat, node->client_data,
3464 node->data_type, node->data);
3465 if (cntxt == CY_RQT_GENERAL_RQT_CONTEXT)
3466 cy_as_remove_c_b_node(dev_p->func_cbs_misc);
3467 else
3468 cy_as_remove_c_b_node(dev_p->func_cbs_res);
3469
3470}
3471
3472
3473
3474
3475