|
10 | 10 | #define FLASH_REGION_SIZE (FLASH_SIZE >> 4) |
11 | 11 | #define FLASH_ROW_SIZE (FLASH_PAGE_SIZE << 2) |
12 | 12 |
|
| 13 | +#define PORT_PMUX_COUNT 16 |
| 14 | +#define PORT_PINCFG_COUNT 32 |
| 15 | + |
13 | 16 | #define ARM_SERCOM_SLEEP 4 |
14 | 17 |
|
15 | 18 | static uint32_t bitreverse(uint32_t x, uint8_t bits) { |
@@ -495,9 +498,9 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { |
495 | 498 | case PORT_WRCONFIG_OFFSET >> 2: |
496 | 499 | return PORT_WRCONFIG_RESETVALUE; |
497 | 500 | default: |
498 | | - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { |
| 501 | + if (addr - (uint32_t)(PORT + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { |
499 | 502 | return PORT_PMUX_RESETVALUE; |
500 | | - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { |
| 503 | + } else if (addr - (uint32_t)(PORT + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { |
501 | 504 | return PORT_PINCFG_RESETVALUE; |
502 | 505 | } |
503 | 506 | break; |
@@ -689,9 +692,9 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { |
689 | 692 | case PORT_WRCONFIG_OFFSET >> 2: |
690 | 693 | return PORT_WRCONFIG_RESETVALUE; |
691 | 694 | default: |
692 | | - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { |
| 695 | + if (addr - (uint32_t)(PORT_IOBUS + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { |
693 | 696 | return PORT_PMUX_RESETVALUE; |
694 | | - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { |
| 697 | + } else if (addr - (uint32_t)(PORT_IOBUS + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { |
695 | 698 | return PORT_PINCFG_RESETVALUE; |
696 | 699 | } |
697 | 700 | break; |
@@ -730,52 +733,57 @@ uint32_t arm_mem_load_word(arm_t *arm, uint32_t addr) { |
730 | 733 | } else if (unlikely(addr < SysTick_BASE)) { |
731 | 734 | } else if (unlikely(addr < NVIC_BASE)) { |
732 | 735 | arm_systick_t *systick = &arm->cpu.systick; |
733 | | - if (addr == (uint32_t)&SysTick->CTRL) { |
734 | | - val = systick->ctrl; |
735 | | - systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; |
736 | | - return val; |
737 | | - } else if (addr == (uint32_t)&SysTick->LOAD) { |
738 | | - return systick->load; |
739 | | - } else if (addr == (uint32_t)&SysTick->VAL) { |
740 | | - return systick->val; |
741 | | - } else if (addr == (uint32_t)&SysTick->CALIB) { |
| 736 | + switch (addr - SysTick_BASE) { |
| 737 | + case 0x000: // CTRL |
| 738 | + val = systick->ctrl; |
| 739 | + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; |
| 740 | + return val; |
| 741 | + case 0x004: // LOAD |
| 742 | + return systick->load; |
| 743 | + case 0x008: // VAL |
| 744 | + return systick->val; |
| 745 | + case 0x00C: // CALIB |
| 746 | + break; |
| 747 | + default: |
| 748 | + break; |
742 | 749 | } |
743 | 750 | } else if (unlikely(addr < SCB_BASE)) { |
744 | 751 | arm_nvic_t *nvic = &arm->cpu.nvic; |
745 | | - if (addr == (uint32_t)&NVIC->ISER[0] || |
746 | | - addr == (uint32_t)&NVIC->ICER[0]) { |
| 752 | + if (addr == NVIC_BASE + 0x000 || // ISER[0] |
| 753 | + addr == NVIC_BASE + 0x080) { // ICER[0] |
747 | 754 | return nvic->ier; |
748 | | - } else if (addr == (uint32_t)&NVIC->ISPR[0] || |
749 | | - addr == (uint32_t)&NVIC->ICPR[0]) { |
| 755 | + } else if (addr == NVIC_BASE + 0x100 || // ISPR[0] |
| 756 | + addr == NVIC_BASE + 0x180) { // ICPR[0] |
750 | 757 | return nvic->ipr; |
751 | | - } else if (addr >= (uint32_t)&NVIC->IP[0] && |
752 | | - addr <= (uint32_t)&NVIC->IP[7]) { |
| 758 | + } else if (addr >= NVIC_BASE + 0x300 && |
| 759 | + addr < NVIC_BASE + 0x320) { // IP[0] - IP[7] |
753 | 760 | return nvic->ip[addr >> 2 & 7]; |
754 | 761 | } |
755 | 762 | } else { |
756 | 763 | arm_scb_t *scb = &arm->cpu.scb; |
757 | | - if (addr == (uint32_t)&SCB->CPUID) { |
758 | | - return 'A' << SCB_CPUID_IMPLEMENTER_Pos | |
759 | | - 0 << SCB_CPUID_VARIANT_Pos | |
760 | | - 12 << SCB_CPUID_ARCHITECTURE_Pos | |
761 | | - 28 << SCB_CPUID_PARTNO_Pos | |
762 | | - 6 << SCB_CPUID_REVISION_Pos; |
763 | | - } else if (addr == (uint32_t)&SCB->ICSR) { |
764 | | - return scb->icsr; |
765 | | - } else if (addr == (uint32_t)&SCB->VTOR) { |
766 | | - return scb->vtor; |
767 | | - } else if (addr == (uint32_t)&SCB->AIRCR) { |
768 | | - return 0; |
769 | | - } else if (addr == (uint32_t)&SCB->CCR) { |
770 | | - return SCB_CCR_STKALIGN_Msk | |
771 | | - SCB_CCR_UNALIGN_TRP_Msk; |
772 | | - } else if (addr == (uint32_t)&SCB->SHP[0]) { |
773 | | - return scb->shp[0]; |
774 | | - } else if (addr == (uint32_t)&SCB->SHP[1]) { |
775 | | - return scb->shp[1]; |
776 | | - } else if (addr == (uint32_t)&SCB->SHCSR) { |
777 | | - return (scb->icsr & SCB_ICSR_PENDSVSET_Msk) >> |
778 | | - SCB_ICSR_PENDSVSET_Pos << SCB_SHCSR_SVCALLPENDED_Pos; |
| 764 | + switch (addr - SCB_BASE) { |
| 765 | + case 0x000: // CPUID |
| 766 | + return 'A' << SCB_CPUID_IMPLEMENTER_Pos | |
| 767 | + 0 << SCB_CPUID_VARIANT_Pos | |
| 768 | + 12 << SCB_CPUID_ARCHITECTURE_Pos | |
| 769 | + 28 << SCB_CPUID_PARTNO_Pos | |
| 770 | + 6 << SCB_CPUID_REVISION_Pos; |
| 771 | + case 0x004: // ICSR |
| 772 | + return scb->icsr; |
| 773 | + case 0x008: // VTOR |
| 774 | + return scb->vtor; |
| 775 | + case 0x00C: // AIRCR |
| 776 | + return 0; |
| 777 | + case 0x014: // CCR |
| 778 | + return SCB_CCR_STKALIGN_Msk | |
| 779 | + SCB_CCR_UNALIGN_TRP_Msk; |
| 780 | + case 0x01C: // SHP[0] |
| 781 | + return scb->shp[0]; |
| 782 | + case 0x020: // SHP[1] |
| 783 | + return scb->shp[1]; |
| 784 | + case 0x024: // SHCSR |
| 785 | + return (scb->icsr & SCB_ICSR_PENDSVSET_Msk) >> |
| 786 | + SCB_ICSR_PENDSVSET_Pos << SCB_SHCSR_SVCALLPENDED_Pos; |
779 | 787 | } |
780 | 788 | } |
781 | 789 | if (arm->debug) { |
@@ -1053,9 +1061,9 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t |
1053 | 1061 | case PORT_WRCONFIG_OFFSET >> 2: |
1054 | 1062 | return; |
1055 | 1063 | default: |
1056 | | - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { |
| 1064 | + if (addr - (uint32_t)(PORT + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { |
1057 | 1065 | return; |
1058 | | - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { |
| 1066 | + } else if (addr - (uint32_t)(PORT + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { |
1059 | 1067 | return; |
1060 | 1068 | } |
1061 | 1069 | break; |
@@ -1091,7 +1099,7 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t |
1091 | 1099 | } |
1092 | 1100 | } else { // SBMATRIX |
1093 | 1101 | switch (addr) { |
1094 | | - case (uint32_t)®_SBMATRIX_SFR4: |
| 1102 | + case (uint32_t)REG_SBMATRIX_SFR4: |
1095 | 1103 | return; |
1096 | 1104 | } |
1097 | 1105 | } |
@@ -1332,9 +1340,9 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t |
1332 | 1340 | case PORT_WRCONFIG_OFFSET >> 2: |
1333 | 1341 | return; |
1334 | 1342 | default: |
1335 | | - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { |
| 1343 | + if (addr - (uint32_t)(PORT_IOBUS + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { |
1336 | 1344 | return; |
1337 | | - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { |
| 1345 | + } else if (addr - (uint32_t)(PORT_IOBUS + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { |
1338 | 1346 | return; |
1339 | 1347 | } |
1340 | 1348 | break; |
@@ -1372,71 +1380,80 @@ void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr) { |
1372 | 1380 | } else if (unlikely(addr < SysTick_BASE)) { |
1373 | 1381 | } else if (unlikely(addr < NVIC_BASE)) { |
1374 | 1382 | arm_systick_t *systick = &arm->cpu.systick; |
1375 | | - if (addr == (uint32_t)&SysTick->CTRL) { |
1376 | | - systick->ctrl = (systick->ctrl & SysTick_CTRL_COUNTFLAG_Msk) | |
1377 | | - (val & (SysTick_CTRL_CLKSOURCE_Msk | |
1378 | | - SysTick_CTRL_TICKINT_Msk | |
1379 | | - SysTick_CTRL_ENABLE_Msk)); |
1380 | | - return; |
1381 | | - } else if (addr == (uint32_t)&SysTick->LOAD) { |
1382 | | - systick->load = val & SysTick_LOAD_RELOAD_Msk; |
1383 | | - return; |
1384 | | - } else if (addr == (uint32_t)&SysTick->VAL) { |
1385 | | - systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; |
1386 | | - systick->val = 0; |
1387 | | - return; |
1388 | | - } else if (addr == (uint32_t)&SysTick->CALIB) { |
| 1383 | + switch (addr - SysTick_BASE) { |
| 1384 | + case 0x000: // CTRL |
| 1385 | + systick->ctrl = (systick->ctrl & SysTick_CTRL_COUNTFLAG_Msk) | |
| 1386 | + (val & (SysTick_CTRL_CLKSOURCE_Msk | |
| 1387 | + SysTick_CTRL_TICKINT_Msk | |
| 1388 | + SysTick_CTRL_ENABLE_Msk)); |
| 1389 | + return; |
| 1390 | + case 0x004: // LOAD |
| 1391 | + systick->load = val & SysTick_LOAD_RELOAD_Msk; |
| 1392 | + return; |
| 1393 | + case 0x008: // VAL |
| 1394 | + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; |
| 1395 | + systick->val = 0; |
| 1396 | + return; |
| 1397 | + case 0x00C: // CALIB |
| 1398 | + break; |
| 1399 | + default: |
| 1400 | + break; |
1389 | 1401 | } |
1390 | 1402 | } else if (unlikely(addr < SCB_BASE)) { |
1391 | 1403 | arm_nvic_t *nvic = &arm->cpu.nvic; |
1392 | | - if (addr == (uint32_t)&NVIC->ISER[0]) { |
| 1404 | + if (addr == NVIC_BASE + 0x000) { // ISER[0] |
1393 | 1405 | nvic->ier |= val; |
1394 | 1406 | return; |
1395 | | - } else if (addr == (uint32_t)&NVIC->ICER[0]) { |
| 1407 | + } else if (addr == NVIC_BASE + 0x080) { // ICER[0] |
1396 | 1408 | nvic->ier &= ~val; |
1397 | 1409 | return; |
1398 | | - } else if (addr == (uint32_t)&NVIC->ISPR[0]) { |
| 1410 | + } else if (addr == NVIC_BASE + 0x100) { // ISPR[0] |
1399 | 1411 | nvic->ipr |= val; |
1400 | 1412 | return; |
1401 | | - } else if (addr == (uint32_t)&NVIC->ICPR[0]) { |
| 1413 | + } else if (addr == NVIC_BASE + 0x180) { // ICPR[0] |
1402 | 1414 | nvic->ipr &= ~val; |
1403 | 1415 | return; |
1404 | | - } else if (addr >= (uint32_t)&NVIC->IP[0] && addr <= (uint32_t)&NVIC->IP[7]) { |
| 1416 | + } else if (addr >= NVIC_BASE + 0x300 && |
| 1417 | + addr < NVIC_BASE + 0x320) { // IP[0] - IP[7] |
1405 | 1418 | nvic->ip[addr >> 2 & 7] = val & UINT32_C(0xC0C0C0C0); |
1406 | 1419 | return; |
1407 | 1420 | } |
1408 | 1421 | } else { |
1409 | 1422 | arm_scb_t *scb = &arm->cpu.scb; |
1410 | | - if (addr == (uint32_t)&SCB->ICSR) { |
1411 | | - if (val & SCB_ICSR_NMIPENDSET_Msk) { |
1412 | | - scb->icsr |= SCB_ICSR_NMIPENDSET_Msk; |
1413 | | - } |
1414 | | - if (val & SCB_ICSR_PENDSVSET_Msk) { |
1415 | | - scb->icsr |= SCB_ICSR_PENDSVSET_Msk; |
1416 | | - } else if (val & SCB_ICSR_PENDSVCLR_Msk) { |
1417 | | - scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; |
1418 | | - } |
1419 | | - if (val & SCB_ICSR_PENDSTSET_Msk) { |
1420 | | - scb->icsr |= SCB_ICSR_PENDSTSET_Msk; |
1421 | | - } else if (val & SCB_ICSR_PENDSTCLR_Msk) { |
1422 | | - scb->icsr &= ~SCB_ICSR_PENDSTSET_Msk; |
1423 | | - } |
1424 | | - return; |
1425 | | - } else if (addr == (uint32_t)&SCB->VTOR) { |
1426 | | - scb->vtor = val & SCB_VTOR_TBLOFF_Msk; |
1427 | | - return; |
1428 | | - } else if (addr == (uint32_t)&SCB->SHP[0]) { |
1429 | | - scb->shp[0] = val & UINT32_C(0xC0000000); |
1430 | | - return; |
1431 | | - } else if (addr == (uint32_t)&SCB->SHP[1]) { |
1432 | | - scb->shp[1] = val & UINT32_C(0xC0C00000); |
1433 | | - return; |
1434 | | - } else if (addr == (uint32_t)&SCB->SHCSR) { |
1435 | | - if (val & SCB_SHCSR_SVCALLPENDED_Msk) { |
1436 | | - scb->icsr |= SCB_ICSR_PENDSVSET_Msk; |
1437 | | - } else { |
1438 | | - scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; |
1439 | | - } |
| 1423 | + switch (addr - SCB_BASE) { |
| 1424 | + case 0x004: // ICSR |
| 1425 | + if (val & SCB_ICSR_NMIPENDSET_Msk) { |
| 1426 | + scb->icsr |= SCB_ICSR_NMIPENDSET_Msk; |
| 1427 | + } |
| 1428 | + if (val & SCB_ICSR_PENDSVSET_Msk) { |
| 1429 | + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; |
| 1430 | + } else if (val & SCB_ICSR_PENDSVCLR_Msk) { |
| 1431 | + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; |
| 1432 | + } |
| 1433 | + if (val & SCB_ICSR_PENDSTSET_Msk) { |
| 1434 | + scb->icsr |= SCB_ICSR_PENDSTSET_Msk; |
| 1435 | + } else if (val & SCB_ICSR_PENDSTCLR_Msk) { |
| 1436 | + scb->icsr &= ~SCB_ICSR_PENDSTSET_Msk; |
| 1437 | + } |
| 1438 | + return; |
| 1439 | + case 0x008: // VTOR |
| 1440 | + scb->vtor = val & SCB_VTOR_TBLOFF_Msk; |
| 1441 | + return; |
| 1442 | + case 0x01C: // SHP[0] |
| 1443 | + scb->shp[0] = val & UINT32_C(0xC0000000); |
| 1444 | + return; |
| 1445 | + case 0x020: // SHP[1] |
| 1446 | + scb->shp[1] = val & UINT32_C(0xC0C00000); |
| 1447 | + return; |
| 1448 | + case 0x024: // SHCSR |
| 1449 | + if (val & SCB_SHCSR_SVCALLPENDED_Msk) { |
| 1450 | + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; |
| 1451 | + } else { |
| 1452 | + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; |
| 1453 | + } |
| 1454 | + return; |
| 1455 | + default: |
| 1456 | + break; |
1440 | 1457 | } |
1441 | 1458 | } |
1442 | 1459 | if (arm->debug) { |
|
0 commit comments