AG903ライブラリリファレンス
内容インデックスホーム
前へ上へ次へ
dmacmgr.c

DMAC Manager

DMAC Manager Layer.

none

AXELL CORPORATION

2017_02_22 初版 

2017_05_29 [#1348]DMAC動作状態の判別方法を修正 

2017_10_26 Ver2.0 

2019_03_08 [SDK2.2] ディスクリプタによるDMA転送の不具合を修正 (#2446) 

2019_12_27 [SDK3.0] DMACマネージャの割り込みクリア順序を修正 (#2589) 

2025_03_06 [SDK3.7] DMACに割り込みコールバックバックを解除する関数を追加 (#5756) 

2025_03_06 [SDK3.7] DMACマネージャで管理外チャンネルの割り込みをクリアする不具合を修正 (#5763)

1: 14: 15: 19: 20: 21: #include "AG903_common.h" 22: #include "AG903_regmap.h" 23: 24: #include "dmac/dmacprm.h" 25: #include "dmac/dmacmgr.h" 26: #include "int/intmgr.h" 27: 28: 29: typedef struct _AG903_DMACMgrAddrTable 30: { 31: uint32_t current; 32: uint32_t next; 33: } AG903_DMACMgrAddrTable; 34: 35: 36: typedef struct _AG903_DMACMgrHandleStat 37: { 38: void *cb_term; 39: void *cb_abt; 40: void *cb_wdt; 41: void *cb_error; 42: 43: 46: AG903_DMACMgrAddrTable term_addr_table[AG903_DMAC_DESC_LINK_MAX]; 47: uint32_t term_addr_table_num; 48: 49: uint8_t unit_id; 50: uint8_t term_count; 51: uint8_t reserve[2]; 52: 53: } AG903_DMACMgrHandleStat; 54: 55: static AG903_DMACMgrHandleStat handle_list[AG903_DMAC_UNIT_NUM]; 56: static _Bool handle_used_flag[AG903_DMAC_UNIT_NUM] = {false}; 57: 58: #define LOCAL_DESC_MEM_ADDR (0xFD100000) 59: 60: #define CH_REG_SIZE (0x20) 61: 62: static int8_t dmac_int_init_flag = false; 63: 64: 65: static int32_t dmac_int_dmactc_hdrid = 0; 66: 67: static int8_t ldd_flag[AG903_DMAC_LDD_ENTRY_NUM] = {0}; 68: 69: static int8_t rdd_flag[AG903_DMAC_RDD_ENTRY_NUM] = {0}; 70: static uint8_t* rdd_data = NULL; 71: 72: #define TOTAL_ENTRY_NUM (AG903_DMAC_LDD_ENTRY_NUM+AG903_DMAC_RDD_ENTRY_NUM) 73: 74: #define AG903_DMAC_CONFIG_TCMASK (1<<0) 75: 76: static _Bool initdesc = false; 77: 78: static void write_desc(AG903_DMACMgrDesc *from, AG903_DMACMgrDesc *next, void *to, int is_reg); 79: static int32_t remove_desc_entry(int seq_id); 80: static uint8_t DMACMgr_CheckEnable(uint32_t unit); 81: static void DMACMgrTermIntHandler(uint32_t term); 82: static void DMACMgrErrIntHandler(uint32_t abt, uint32_t err); 83: 84: 87: static void DMACMgrDmactcIntHandler() 88: { 89: uint32_t term, abt, wdt, err; 90: 91: AG903_DMACPrmGetTIMECOUNT_STATUS(&term); 92: AG903_DMACPrmGetERR_ABORT_STATUS(&err, &wdt, &abt); 93: 94: if(0 != term) { 95: DMACMgrTermIntHandler(term); 96: } 97: if((0 != abt) || (0 != err)) { 98: DMACMgrErrIntHandler(abt, err); 99: } 100: if(0 != wdt) { 101: 102: 103: } 104: 105: return; 106: } 107: 108: 111: static void DMACMgrTermIntHandler(uint32_t term) 112: { 113: AG903_DMACMgrHandleStat *handle; 114: AG903_DMACMgrDesc *desc = NULL; 115: AG903_DMACMgrDesc *next = NULL; 116: uint32_t desc_save_mem; 117: int loop; 118: uint8_t end = false; 119: 120: for(loop=0; loop<AG903_DMAC_UNIT_NUM; loop++) { 121: if(0 == term) { 122: break; 123: } 124: if(term & (0x1<<loop)) { 125: if(true == handle_used_flag[loop]) { 126: 127: AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(0x1<<loop); 128: 129: handle = &handle_list[loop]; 130: if(handle->cb_term != NULL) { 131: void (*cb_term)(AG903_DMACMgrHandle*, AG903_DMACMgrDesc**, uint8_t*) = 132: (void(*)(AG903_DMACMgrHandle*, AG903_DMACMgrDesc**, uint8_t*))handle->cb_term; 133: if(0 >= handle->term_addr_table_num) { 134: cb_term((AG903_DMACMgrHandle*)handle, NULL, NULL); 135: } 136: else { 137: cb_term((AG903_DMACMgrHandle*)handle, &desc, &end); 138: if(NULL != desc) { 139: if(true == end) { 140: next = NULL; 141: } 142: else { 143: next = (AG903_DMACMgrDesc*)handle->term_addr_table[handle->term_count].next; 144: } 145: desc_save_mem = handle->term_addr_table[handle->term_count].current; 146: write_desc(desc, next, (void*)desc_save_mem, 0); 147: } 148: else { 149: 150: if(true == end) { 151: desc_save_mem = handle->term_addr_table[handle->term_count].current; 152: *(uint32_t*)(((uint32_t)desc_save_mem)+0x8) = 0; 153: } 154: } 155: handle->term_count = ((handle->term_count+1) % handle->term_addr_table_num); 156: } 157: } 158: } 159: else { 160: 161: } 162: term &= ~(0x1<<loop); 163: } 164: 165: } 166: 167: return; 168: } 169: 170: 173: static void DMACMgrErrIntHandler(uint32_t abt, uint32_t err) 174: { 175: AG903_DMACMgrHandleStat *handle; 176: int loop; 177: 178: 182: for(loop=0; loop<AG903_DMAC_UNIT_NUM; loop++) { 183: if(0 == abt) { 184: break; 185: } 186: if(abt & (0x1<<loop)) { 187: if(true == handle_used_flag[loop]) { 188: handle = &handle_list[loop]; 189: if(NULL != handle_list[loop].cb_abt) { 190: void (*cb_abt)(AG903_DMACMgrHandle*) = (void(*)(AG903_DMACMgrHandle*))handle->cb_abt; 191: cb_abt((AG903_DMACMgrHandle*)handle); 192: } 193: AG903_DMACMgrClearInt((AG903_DMACMgrHandle*)handle, AG903_DMAC_INTSTS_ABORT); 194: } 195: else { 196: 197: } 198: abt &= ~(0x1<<loop); 199: } 200: } 201: 202: for(loop=0; loop<AG903_DMAC_UNIT_NUM; loop++) { 203: if(0 == err) { 204: break; 205: } 206: if(err & (0x1<<loop)) { 207: if(true == handle_used_flag[loop]) { 208: handle = &handle_list[loop]; 209: if(NULL != handle_list[loop].cb_error) { 210: void (*cb_error)(AG903_DMACMgrHandle*) = (void(*)(AG903_DMACMgrHandle*))handle->cb_error; 211: cb_error((AG903_DMACMgrHandle*)handle); 212: } 213: AG903_DMACMgrClearInt((AG903_DMACMgrHandle*)handle, AG903_DMAC_INTSTS_ERROR); 214: } 215: else { 216: 217: } 218: err &= ~(0x1<<loop); 219: } 220: } 221: 222: return; 223: } 224: 225: 235: int32_t AG903_DMACMgrGetHandle(int ch, AG903_DMACMgrHandle **handle) 236: { 237: if(ch < 0 || AG903_DMAC_UNIT_NUM <= ch || NULL == handle) 238: { 239: return -AG903_EINVAL; 240: } 241: 242: if(handle_used_flag[ch] == true) 243: { 244: return -AG903_EBUSY; 245: } 246: 247: 248: uint32_t chpos = 1 << ch; 249: AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(chpos); 250: AG903_DMACPrmSetERR_ABORT_INT_CLEAR(chpos, chpos, chpos); 251: 252: (*handle) = (AG903_DMACMgrHandle*)&handle_list[ch]; 253: handle_used_flag[ch] = true; 254: 255: handle_list[ch].unit_id = ch; 256: 257: handle_list[ch].cb_term = NULL; 258: handle_list[ch].cb_error = NULL; 259: handle_list[ch].cb_abt = NULL; 260: handle_list[ch].cb_wdt = NULL; 261: 262: return AG903_ENONE; 263: } 264: 265: 277: int32_t AG903_DMACMgrReleaseHandle(AG903_DMACMgrHandle *handle) 278: { 279: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 280: uint8_t enable; 281: 282: 283: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 284: { 285: return -AG903_EINVAL; 286: } 287: 288: 289: enable = DMACMgr_CheckEnable(unit); 290: if(true == enable) { 291: return -AG903_EBUSY; 292: } 293: 294: remove_desc_entry(unit); 295: handle_used_flag[unit] = false; 296: 297: return AG903_ENONE; 298: } 299: 300: 309: int32_t AG903_DMACMgrGetIntStatus(AG903_DMACMgrHandle *handle, uint32_t *status) 310: { 311: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 312: uint32_t term, abt, wdt, error; 313: 314: 315: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle || NULL == status) 316: { 317: return -AG903_EINVAL; 318: } 319: 320: AG903_DMACPrmGetTIMECOUNT_STATUS(&term); 321: AG903_DMACPrmGetERR_ABORT_STATUS(&error, &wdt, &abt); 322: term = (term >> unit) & 0x01; 323: error = (error >> unit) & 0x01; 324: wdt = (wdt >> unit) & 0x01; 325: abt = (abt >> unit) & 0x01; 326: 327: (*status) = (uint32_t)term; 328: (*status) |= (uint32_t)(abt<<1); 329: (*status) |= (uint32_t)(wdt<<2); 330: (*status) |= (uint32_t)(error<<3); 331: 332: return AG903_ENONE; 333: } 334: 335: 344: int32_t AG903_DMACMgrClearInt(AG903_DMACMgrHandle *handle, uint32_t clrbit) 345: { 346: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 347: uint8_t term, abt, wdt, error; 348: 349: 350: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 351: { 352: return -AG903_EINVAL; 353: } 354: 355: term = 0; 356: abt = 0; 357: wdt = 0; 358: error = 0; 359: if(AG903_DMAC_INTSTS_TERM&clrbit) { 360: term =1; 361: } 362: if(AG903_DMAC_INTSTS_ABORT&clrbit) { 363: abt=1; 364: } 365: if(AG903_DMAC_INTSTS_WDT&clrbit) { 366: wdt=1; 367: } 368: if(AG903_DMAC_INTSTS_ERROR&clrbit) { 369: error=1; 370: } 371: AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(term<<unit); 372: AG903_DMACPrmSetERR_ABORT_INT_CLEAR(error<<unit, wdt<<unit, abt<<unit); 373: 374: return AG903_ENONE; 375: } 376: 377: 396: int32_t AG903_DMACMgrSetIntCallback(AG903_DMACMgrHandle *handle, 397: void (*cb_term)(AG903_DMACMgrHandle*, AG903_DMACMgrDesc**, uint8_t*), 398: void (*cb_abt)(AG903_DMACMgrHandle*), 399: void (*cb_error)(AG903_DMACMgrHandle*)) 400: { 401: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 402: AG903_INTMgrHdrPrm inthdr; 403: 404: 405: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 406: { 407: return -AG903_EINVAL; 408: } 409: 410: 411: if(dmac_int_init_flag == false) 412: { 413: inthdr.atr = AG903_INT_HLNG; 414: inthdr.intno = AG903_IRQ26_DMAC; 415: inthdr.func = (void*)DMACMgrDmactcIntHandler; 416: dmac_int_dmactc_hdrid = AG903_INTMgrSetHandler(&inthdr); 417: if(0 >= dmac_int_dmactc_hdrid) 418: { 419: return -AG903_EFAULT; 420: } 421: dmac_int_init_flag = true; 422: } 423: 424: handle_list[unit].cb_term = (void*)cb_term; 425: handle_list[unit].cb_abt = (void*)cb_abt; 426: handle_list[unit].cb_error = (void*)cb_error; 427: 428: AG903_INTMgrEnableInt(AG903_IRQ26_DMAC); 429: 430: return AG903_ENONE; 431: } 432: 433: 451: int32_t AG903_DMACMgrUnsetIntCallback(AG903_DMACMgrHandle *handle) 452: { 453: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 454: int32_t retval; 455: 456: 457: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 458: { 459: return -AG903_EINVAL; 460: } 461: 462: 463: if(dmac_int_init_flag == false || dmac_int_dmactc_hdrid <= 0) 464: { 465: return -AG903_EPERM; 466: } 467: 468: retval = AG903_INTMgrDeleteHandler(dmac_int_dmactc_hdrid); 469: if(retval < 0) 470: { 471: return -AG903_EFAULT; 472: } 473: 474: dmac_int_init_flag = false; 475: dmac_int_dmactc_hdrid = 0; 476: 477: return AG903_ENONE; 478: } 479: 480: 489: int32_t AG903_DMACMgrEnable(AG903_DMACMgrHandle *handle) 490: { 491: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 492: uint8_t enable; 493: 494: 495: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 496: { 497: return -AG903_EINVAL; 498: } 499: 500: 501: enable = DMACMgr_CheckEnable(unit); 502: if(true == enable) { 503: return -AG903_EBUSY; 504: } 505: 506: 510: handle_list[unit].term_count = 0; 511: 512: DMACPrmParamCTRL ctrl; 513: AG903_DMACPrmGetCTRL_REG(unit, &ctrl); 514: ctrl.ChEn = 1; 515: AG903_DMACPrmSetCTRL_REG(unit, &ctrl); 516: 517: return AG903_ENONE; 518: } 519: 520: 529: int32_t AG903_DMACMgrAbort(AG903_DMACMgrHandle *handle) 530: { 531: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 532: uint8_t enable; 533: 534: 535: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 536: { 537: return -AG903_EINVAL; 538: } 539: 540: 541: enable = DMACMgr_CheckEnable(unit); 542: if(false == enable) { 543: return -AG903_EPERM; 544: } 545: 546: AG903_DMACPrmSetCHANNEL_ENABLE(~(1 << unit)); 547: 548: return AG903_ENONE; 549: } 550: 551: 560: int32_t AG903_DMACMgrSetSyncPeripheral(int port, int val) 561: { 562: 563: if(0 > port || port >= AG903_DMAC_PORT_NUM) 564: { 565: return -AG903_EINVAL; 566: } 567: 568: if(!(val == 0 || val == 1)) 569: { 570: return -AG903_EINVAL; 571: } 572: 573: uint32_t reg; 574: AG903_DMACPrmGetSYNC_PERI_IF(&reg); 575: if (val == 0) 576: reg &= ~(1 << port); 577: else 578: reg |= (1 << port); 579: AG903_DMACPrmSetSYNC_PERI_IF(reg); 580: 581: return AG903_ENONE; 582: } 583: 584: 593: int32_t AG903_DMACMgrSetWatchdog(int val) 594: { 595: if(0 > val || val > 0xFFFF) 596: { 597: return -AG903_EINVAL; 598: } 599: 600: AG903_DMACPrmSetWATCHDOG_TIMER(val); 601: 602: return AG903_ENONE; 603: } 604: 605: 613: int32_t AG903_DMACMgrSetConstantValue(uint32_t val) 614: { 615: AG903_DMACPrmSetCONSTANT_VALUE_WRITE_ONLY(val); 616: 617: return AG903_ENONE; 618: } 619: 620: 628: int32_t AG903_DMACMgrSetEvent(int id) 629: { 630: if(0 > id || AG903_DMAC_EVENT_NUM <= id) 631: { 632: return -AG903_EINVAL; 633: } 634: 635: AG903_DMACPrmSetGLOBAL_EVENT(1 << id, 0); 636: 637: return AG903_ENONE; 638: } 639: 640: 648: int32_t AG903_DMACMgrClearEvent(int id) 649: { 650: if(0 > id || AG903_DMAC_EVENT_NUM <= id) 651: { 652: return -AG903_EINVAL; 653: } 654: 655: AG903_DMACPrmSetGLOBAL_EVENT(0, 1 << id); 656: 657: return AG903_ENONE; 658: } 659: 660: 669: int32_t AG903_DMACMgrGetEvent(int id, uint8_t *val) 670: { 671: if(0 > id || AG903_DMAC_EVENT_NUM <= id || NULL == val) 672: { 673: return -AG903_EINVAL; 674: } 675: 676: uint32_t reg; 677: AG903_DMACPrmGetGLOBAL_EVENT(&reg); 678: *val = (reg >> id) & 0x01; 679: 680: return AG903_ENONE; 681: } 682: 683: 692: int32_t AG903_DMACMgrGetStatus(AG903_DMACMgrHandle *handle, AG903_DMACMgrStatus *status) 693: { 694: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 695: 696: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle || NULL == status) 697: { 698: return -AG903_EINVAL; 699: } 700: 701: status->enable = DMACMgr_CheckEnable(unit); 702: 703: return AG903_ENONE; 704: } 705: 706: 710: static uint8_t DMACMgr_CheckEnable(uint32_t unit) 711: { 712: uint8_t retval = false; 713: DMACPrmParamCTRL ctrl; 714: 715: AG903_DMACPrmGetCTRL_REG(unit, &ctrl); 716: if(0 != ctrl.ChEn) { 717: retval = true; 718: } 719: 720: return retval; 721: } 722: 723: 724: 725: 726: 732: static int get_free_desc_index(int seq_id) 733: { 734: int i; 735: 736: 740: if(seq_id == 0) seq_id = TOTAL_ENTRY_NUM; 741: 742: 743: for(i = 0 ; i < AG903_DMAC_LDD_ENTRY_NUM ; i++) 744: { 745: if(ldd_flag[i] == 0) 746: { 747: ldd_flag[i] = seq_id; 748: return i; 749: } 750: } 751: 752: 753: if(NULL != rdd_data) 754: { 755: for(i = AG903_DMAC_LDD_ENTRY_NUM ; i < AG903_DMAC_RDD_ENTRY_NUM+AG903_DMAC_LDD_ENTRY_NUM ; i++) 756: { 757: if(rdd_flag[i-AG903_DMAC_LDD_ENTRY_NUM] == 0) 758: { 759: rdd_flag[i-AG903_DMAC_LDD_ENTRY_NUM] = seq_id; 760: return i; 761: } 762: } 763: } 764: 765: 766: return -1; 767: } 768: 769: 773: static int32_t remove_desc_entry(int seq_id) 774: { 775: int i; 776: 777: if(seq_id == 0) seq_id = TOTAL_ENTRY_NUM; 778: 779: 780: for(i = 0 ; i < AG903_DMAC_LDD_ENTRY_NUM ; i++) 781: { 782: if(ldd_flag[i] == seq_id) 783: { 784: ldd_flag[i] = 0; 785: } 786: } 787: 788: 789: for(i = AG903_DMAC_LDD_ENTRY_NUM ; i < AG903_DMAC_RDD_ENTRY_NUM+AG903_DMAC_LDD_ENTRY_NUM ; i++) 790: { 791: if(rdd_flag[i-AG903_DMAC_LDD_ENTRY_NUM] == seq_id) 792: { 793: rdd_flag[i-AG903_DMAC_LDD_ENTRY_NUM] = 0; 794: } 795: } 796: 797: return AG903_ENONE; 798: } 799: 800: 805: static AG903_DMACMgrDesc* desc_index_to_addr(int index) 806: { 807: if(index < AG903_DMAC_LDD_ENTRY_NUM) 808: { 809: return (AG903_DMACMgrDesc*)(LOCAL_DESC_MEM_ADDR + (index * CH_REG_SIZE)); 810: }else 811: { 812: return (AG903_DMACMgrDesc*)(rdd_data+((index-AG903_DMAC_LDD_ENTRY_NUM)*CH_REG_SIZE)); 813: } 814: } 815: 816: 821: static void* get_desc_reg_addr(int unit) 822: { 823: return (void*)(AG903_DMAC_BASE + 0x100 + (unit*AG903_DMAC_DESC_SIZE)); 824: } 825: 826: 832: static AG903_DMACMgrDesc* get_free_desc(int seq_id) 833: { 834: int index = get_free_desc_index(seq_id); 835: if(index == -1) 836: { 837: return NULL; 838: } 839: 840: 841: return desc_index_to_addr(index); 842: } 843: 844: 851: static void write_desc(AG903_DMACMgrDesc *from, AG903_DMACMgrDesc *next, void *to, int is_reg) 852: { 853: if(is_reg == 1) 854: { 855: *(uint32_t*)(((uint32_t)to) + 0x0) = from->Ctrl.val; 856: *(uint32_t*)(((uint32_t)to) + 0x8) = from->SrcAddr; 857: *(uint32_t*)(((uint32_t)to) + 0xc) = from->DstAddr; 858: *(uint32_t*)(((uint32_t)to) + 0x10) = (uint32_t)next; 859: *(uint32_t*)(((uint32_t)to) + 0x14) = from->Trns.val; 860: *(uint32_t*)(((uint32_t)to) + 0x18) = from->Stride.val; 861: }else 862: { 863: *(uint32_t*)(((uint32_t)to) + 0x0) = from->SrcAddr; 864: *(uint32_t*)(((uint32_t)to) + 0x4) = from->DstAddr; 865: *(uint32_t*)(((uint32_t)to) + 0x8) = (uint32_t)next; 866: *(uint32_t*)(((uint32_t)to) + 0xc) = from->Ctrl.val; 867: *(uint32_t*)(((uint32_t)to) + 0x10) = from->Trns.val; 868: *(uint32_t*)(((uint32_t)to) + 0x14) = from->Stride.val; 869: } 870: } 871: 872: 873: 879: static int set_desc_entry(AG903_DMACMgrHandleStat *handle, AG903_DMACMgrDesc *desc_list, int list_num) 880: { 881: int i; 882: uint32_t loop; 883: DMACPrmParamCFG cfg; 884: AG903_DMACMgrDesc *desc = desc_list; 885: 886: 895: 896: struct 897: { 898: 899: AG903_DMACMgrDesc *src; 900: 901: 902: AG903_DMACMgrDesc *dst; 903: } desc_copy_entry[TOTAL_ENTRY_NUM]; 904: int desc_copy_entry_num = 0; 905: 906: 907: uint8_t ll_circ = false; 908: uint32_t unit = (handle - handle_list); 909: 910: 911: AG903_DMACMgrDesc *desc_save_mem = get_free_desc(unit); 912: if(desc_save_mem == NULL) 913: { 914: return -AG903_ENOBUFS; 915: } 916: 917: 918: AG903_DMACMgrDesc first_desc; 919: 920: first_desc.SrcAddr = 0; 921: first_desc.DstAddr = 0; 922: first_desc.next = 0; 923: first_desc.Ctrl.val = 0; 924: first_desc.Ctrl.st.TCMsk = 1; 925: first_desc.Trns.val = 0; 926: first_desc.Stride.val = 0; 927: write_desc(&first_desc, desc_save_mem, get_desc_reg_addr(unit), 1); 928: 929: 930: handle->term_count = 0; 931: handle->term_addr_table_num = 0; 932: AG903_DMACPrmGetCFG_REG(unit, &cfg); 933: 934: for(loop=0; loop<AG903_DMAC_DESC_LINK_MAX; loop++) 935: { 936: 937: AG903_DMACMgrDesc *next_desc_save_mem = NULL; 938: 939: if(desc->next != NULL) 940: { 941: 942: for(i = 0 ; i < desc_copy_entry_num ; i++) 943: { 944: if(desc_copy_entry[i].src == desc->next) 945: { 946: next_desc_save_mem = desc_copy_entry[i].dst; 947: ll_circ = true; 948: } 949: } 950: 951: 952: if(ll_circ != true) 953: { 954: next_desc_save_mem = get_free_desc(unit); 955: 956: 957: if(next_desc_save_mem == NULL) 958: { 959: remove_desc_entry(unit); 960: return -AG903_ENOBUFS; 961: } 962: } 963: } 964: 965: 966: write_desc(desc, next_desc_save_mem, (void*)desc_save_mem, 0); 967: 968: if(true == ll_circ) 969: { 970: handle->term_addr_table[handle->term_addr_table_num].current = (uint32_t)desc_save_mem; 971: handle->term_addr_table[handle->term_addr_table_num].next = (uint32_t)next_desc_save_mem; 972: handle->term_addr_table_num++; 973: } 974: 975: desc_copy_entry[desc_copy_entry_num].src = desc; 976: desc_copy_entry[desc_copy_entry_num].dst = desc_save_mem; 977: desc_save_mem = next_desc_save_mem; 978: desc_copy_entry_num++; 979: 980: 986: if(desc->next == NULL || ll_circ == true || list_num == 0) 987: { 988: break; 989: } 990: 991: list_num--; 992: desc = desc->next; 993: } 994: if(AG903_DMAC_DESC_LINK_MAX <= loop) 995: { 996: return -AG903_EINVAL; 997: } 998: 999: return AG903_ENONE; 1000: } 1001: 1002: 1003: 1016: int32_t AG903_DMACMgrSetSimpleTrnsDesc(AG903_DMACMgrHandle *handle, void *from, 1017: uint32_t from_size, void *to) 1018: { 1019: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 1020: AG903_DMACMgrDesc dmac_desc; 1021: DMACPrmParamCFG cfg = {0}; 1022: uint8_t enable; 1023: 1024: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle || 1025: NULL == from || NULL == to || 0 == from_size || AG903_DMAC_1DTRANS_MAX < from_size) 1026: { 1027: return -AG903_EINVAL; 1028: } 1029: 1030: 1031: enable = DMACMgr_CheckEnable(unit); 1032: if(true == enable) { 1033: return -AG903_EBUSY; 1034: } 1035: 1036: cfg.ChPri = 1; 1037: AG903_DMACPrmSetCFG_REG(unit, &cfg); 1038: 1039: dmac_desc.SrcAddr = (uint32_t)from; 1040: dmac_desc.DstAddr = (uint32_t)to; 1041: dmac_desc.next = 0; 1042: dmac_desc.Ctrl.val = 0; 1043: dmac_desc.Trns.val = 0; 1044: dmac_desc.Trns.d1.TCnt = from_size; 1045: dmac_desc.Stride.val = 0; 1046: 1047: 1048: write_desc(&dmac_desc, NULL, get_desc_reg_addr(unit), 1); 1049: 1050: return AG903_ENONE; 1051: } 1052: 1053: 1076: int32_t AG903_DMACMgrSetDescList(AG903_DMACMgrHandle *handle, AG903_DMACMgrConfig *config, 1077: AG903_DMACMgrDesc *desc_list, int list_num) 1078: { 1079: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 1080: uint8_t enable; 1081: 1082: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle || 1083: NULL == config || NULL == desc_list || 0 == list_num) 1084: { 1085: return -AG903_EINVAL; 1086: } 1087: 1088: 1089: enable = DMACMgr_CheckEnable(unit); 1090: if(true == enable) { 1091: return -AG903_EBUSY; 1092: } 1093: 1094: if(false == initdesc) { 1095: initdesc = true; 1096: AG903_DMACPrmSetLOCAL_DESC_MEM_BASE(LOCAL_DESC_MEM_ADDR); 1097: } 1098: DMACPrmParamCFG cfg = { 1099: .TCIntMsk = config->st.TCIntMsk, 1100: .ErrIntMsk = config->st.ErrIntMsk, 1101: .AbtIntMsk = config->st.AbtIntMsk, 1102: .SrcRS = config->st.SrcRS, 1103: .SrcHEn = config->st.SrcHEn, 1104: .DstRS = config->st.DstRS, 1105: .DstHEn = config->st.DstHEn, 1106: .LLPCnt = config->st.LLPCnt, 1107: .ChGntWin = config->st.ChGntWin, 1108: .ChPri = config->st.ChPri, 1109: .WOMode = config->st.WOMode, 1110: .UnalignMode = config->st.UnalignMode, 1111: }; 1112: AG903_DMACPrmSetCFG_REG(unit, &cfg); 1113: 1114: return set_desc_entry((AG903_DMACMgrHandleStat*)handle, desc_list, list_num); 1115: } 1116: 1117: 1127: int32_t AG903_DMACMgrRemoveDescList(AG903_DMACMgrHandle *handle) 1128: { 1129: uint32_t unit = ((AG903_DMACMgrHandleStat*)handle - handle_list); 1130: 1131: 1132: if(unit >= AG903_DMAC_UNIT_NUM || &handle_list[unit] != (AG903_DMACMgrHandleStat*)handle) 1133: { 1134: return -AG903_EINVAL; 1135: } 1136: 1137: return remove_desc_entry(unit); 1138: } 1139: 1140: 1156: int32_t AG903_DMACMgrSetRemoteDescAddr(void *addr) 1157: { 1158: int32_t retval = AG903_ENONE; 1159: uint32_t loop; 1160: uint8_t enable; 1161: 1162: if(NULL == addr) 1163: { 1164: return -AG903_EINVAL; 1165: } 1166: if(NULL != rdd_data) 1167: { 1168: return -AG903_EPERM; 1169: } 1170: 1171: for(loop=0; loop<AG903_DMAC_UNIT_NUM; loop++) 1172: { 1173: enable = DMACMgr_CheckEnable(loop); 1174: if(true == enable) { 1175: retval = -AG903_EBUSY; 1176: break; 1177: } 1178: } 1179: if(AG903_ENONE == retval) 1180: { 1181: rdd_data = (uint8_t*)addr; 1182: } 1183: 1184: return retval; 1185: } 1186: 1187: 1197: int32_t AG903_DMACMgrClearRemoteDescAddr(void) 1198: { 1199: int32_t retval = AG903_ENONE; 1200: uint32_t loop; 1201: uint8_t enable; 1202: 1203: for(loop=0; loop<AG903_DMAC_UNIT_NUM; loop++) 1204: { 1205: enable = DMACMgr_CheckEnable(loop); 1206: if(true == enable) { 1207: retval = -AG903_EBUSY; 1208: break; 1209: } 1210: } 1211: if(AG903_ENONE == retval) 1212: { 1213: rdd_data = NULL; 1214: } 1215: 1216: return retval; 1217: }
 
名前 
説明 
 
DMAC転送Abort 
 
イベントクリア 
 
割り込みステータスクリア 
 
リモードディスクリプタ領域アドレスクリア 
 
DMAC転送許可(開始) 
 
イベント状態取得 
 
DMACハンドル取得 
 
割り込みステータス取得 
 
DMACの状態を取得する 
 
DMACハンドル解放 
 
ディスクリプタ破棄 
 
WriteOnlyModeの固定値設定 
 
ディスクリプタ設定 
 
イベント設定 
 
コールバック登録 
 
リモードディスクリプタ領域アドレス指定 
 
簡易転送用ディスクリプタ設定 
 
ペリフェラル同期設定 
 
ウォッチドッグ設定 
 
コールバック解除 
名前 
説明 
ConfigレジスタのTCIintMaskビット 
 
名前 
説明 
 
ディスクリプタアドレス 
 
ハンドル情報 
 
ディスクリプタアドレス 
 
ハンドル情報 
Copyright (c) 2017-2025 Axell Corporation. All rights reserved.