From 0a05723502b0b051b3d4e82beb91e27552af2bd0 Mon Sep 17 00:00:00 2001 From: Janos Magasrevy Date: Fri, 28 Feb 2020 16:29:38 -0500 Subject: [PATCH] Initial commit --- 78K0/IAR/cpu.h | 479 ++++ 78K0R/IAR/cpu.h | 479 ++++ ARC/EM6/MetaWare/cpu.h | 607 +++++ ARC/EM6/MetaWare/cpu_a.s | 259 ++ ARC/EM6/MetaWare/cpu_c.c | 390 +++ ARM-Cortex-A/ARMv7-A/ARM/cpu.h | 538 ++++ ARM-Cortex-A/ARMv7-A/ARM/cpu_a.s | 257 ++ ARM-Cortex-A/ARMv7-A/CCS/cpu.h | 504 ++++ ARM-Cortex-A/ARMv7-A/CCS/cpu_a.asm | 222 ++ ARM-Cortex-A/ARMv7-A/GNU/cpu.h | 506 ++++ ARM-Cortex-A/ARMv7-A/GNU/cpu_a.S | 223 ++ ARM-Cortex-A/ARMv7-A/IAR/cpu.h | 514 ++++ ARM-Cortex-A/ARMv7-A/IAR/cpu_a.asm | 217 ++ ARM-Cortex-A/ARMv8-A/ARM/cpu.h | 530 ++++ ARM-Cortex-A/ARMv8-A/ARM/cpu_a.s | 262 ++ ARM-Cortex-A/ARMv8-A/GNU/cpu.h | 543 ++++ ARM-Cortex-A/ARMv8-A/GNU/cpu_a.S | 244 ++ ARM-Cortex-M/ARMv6-M/ARM/cpu.h | 655 +++++ ARM-Cortex-M/ARMv6-M/ARM/cpu_a.asm | 143 ++ ARM-Cortex-M/ARMv6-M/GNU/cpu.h | 655 +++++ ARM-Cortex-M/ARMv6-M/GNU/cpu_a.s | 148 ++ ARM-Cortex-M/ARMv6-M/IAR/cpu.h | 657 +++++ ARM-Cortex-M/ARMv6-M/IAR/cpu_a.asm | 142 ++ ARM-Cortex-M/ARMv6-M/cpu_c.c | 695 +++++ ARM-Cortex-M/ARMv7-M/ARM/cpu.h | 762 ++++++ ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm | 287 +++ ARM-Cortex-M/ARMv7-M/CCS/cpu.h | 762 ++++++ ARM-Cortex-M/ARMv7-M/CCS/cpu_a.asm | 302 +++ ARM-Cortex-M/ARMv7-M/GNU/cpu.h | 762 ++++++ ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s | 295 +++ ARM-Cortex-M/ARMv7-M/IAR/cpu.h | 764 ++++++ ARM-Cortex-M/ARMv7-M/IAR/cpu_a.asm | 286 +++ ARM-Cortex-M/ARMv7-M/cpu_c.c | 772 ++++++ ARM-Cortex-R/ARMv7-R/ARM/cpu.h | 538 ++++ ARM-Cortex-R/ARMv7-R/ARM/cpu_a.s | 257 ++ ARM-Cortex-R/ARMv7-R/CCS/cpu.h | 551 ++++ ARM-Cortex-R/ARMv7-R/CCS/cpu_a.asm | 229 ++ ARM-Cortex-R/ARMv7-R/GNU/cpu.h | 506 ++++ ARM-Cortex-R/ARMv7-R/GNU/cpu_a.S | 223 ++ ARM-Cortex-R/ARMv7-R/IAR/cpu.h | 543 ++++ ARM-Cortex-R/ARMv7-R/IAR/cpu_a.asm | 235 ++ ARM/GNU/cpu.h | 526 ++++ ARM/GNU/cpu_a.s | 181 ++ ARM/IAR/cpu.h | 606 +++++ ARM/IAR/cpu_a.s | 182 ++ ARM/IAR/cpu_c.c | 146 ++ ARM/RealView/cpu.h | 607 +++++ ARM/RealView/cpu_a.s | 185 ++ ARM/RealView/cpu_c.c | 152 ++ AVR/ATmega128/IAR/cpu.h | 491 ++++ AVR/ATmega128/IAR/cpu_a.s90 | 88 + AVR/ATmega256/IAR/cpu.h | 491 ++++ AVR/ATmega256/IAR/cpu_a.s90 | 88 + AVR/ATxmega128/GNU/cpu.h | 491 ++++ AVR/ATxmega128/GNU/cpu_a.s | 85 + AVR/ATxmega128/IAR/cpu.h | 493 ++++ AVR/ATxmega128/IAR/cpu_a.s90 | 113 + AVR32/AP7000/GNU/cpu.h | 513 ++++ AVR32/AP7000/GNU/cpu_a.s | 267 ++ AVR32/AP7000/IAR/cpu.h | 508 ++++ AVR32/AP7000/IAR/cpu_a.asm | 269 ++ AVR32/UC3/AtmelStudio6/cpu.h | 515 ++++ AVR32/UC3/AtmelStudio6/cpu_a.S | 327 +++ AVR32/UC3/GNU/cpu.h | 515 ++++ AVR32/UC3/GNU/cpu_a.s | 327 +++ AVR32/UC3/IAR/cpu.h | 515 ++++ AVR32/UC3/IAR/cpu_a.asm | 329 +++ BSP/Template/bsp_cpu.c | 302 +++ Blackfin/VDSP++/cpu.h | 493 ++++ Blackfin/VDSP++/cpu_a.asm | 114 + C28x/CCS/cpu.h | 577 +++++ C28x/CCS/cpu_a.asm | 268 ++ C28x/CCS/cpu_c.c | 257 ++ Cache/ARC/EM6/cpu_cache_em6.c | 240 ++ .../IAR/cpu_cache_armv5_generic_l1_a.s | 128 + .../cpu_cache_armv5_generic_l1.c | 79 + .../ARM/cpu_cache_armv7_generic_l1_a.s | 154 ++ .../GNU/cpu_cache_armv7_generic_l1_a.S | 141 ++ .../IAR/cpu_cache_armv7_generic_l1_a.s | 140 + .../cpu_cache_armv7_generic_l1.c | 82 + .../cpu_cache_armv7_generic_l1_l2c310_l2_a.s | 175 ++ .../cpu_cache_armv7_generic_l1_l2c310_l2_a.S | 163 ++ .../cpu_cache_armv7_generic_l1_l2c310_l2_a.s | 169 ++ .../cpu_cache_armv7_generic_l1_l2c310_l2.c | 88 + .../cpu_cache_armv7m_generic_l1.c | 203 ++ Cache/Freescale/Kinetis/cpu_cache_kinetis.c | 338 +++ .../GNU/cpu_cache_powerpc_e200z4204n3_a.S | 190 ++ .../cpu_cache_powerpc_e200z4204n3.c | 83 + Cache/NiosII/cpu_cache_niosII.c | 160 ++ Cfg/Template/cpu_cfg.h | 254 ++ .../Generic/CW_For_Microcontrollers/cpu.h | 493 ++++ .../Generic/CW_For_Microcontrollers/cpu_a.asm | 132 + .../Generic/CW_For_Microcontrollers/cpu_c.c | 116 + ColdFire/Generic/Codewarrior/cpu.h | 500 ++++ ColdFire/Generic/Codewarrior/cpu_a.asm | 130 + ColdFire/Generic/Codewarrior/cpu_c.c | 117 + ColdFire/Generic/IAR/cpu.h | 493 ++++ ColdFire/Generic/IAR/cpu_a.asm | 124 + ColdFire/Generic/IAR/cpu_c.c | 116 + EnSilica/eSi-3250/EDS/cpu.h | 541 ++++ EnSilica/eSi-3250/EDS/cpu_a.S | 379 +++ EnSilica/eSi-3250/EDS/cpu_c.c | 174 ++ FR/Softune/cpu.h | 469 ++++ FR/Softune/cpu_a.asm | 81 + H8-300L/Normal/HEW/cpu.h | 474 ++++ H8-300L/Normal/IAR/cpu.h | 482 ++++ H8S/Adv/HEW/cpu.h | 479 ++++ H8S/Adv/IAR/cpu.h | 474 ++++ H8SX/Adv/HEW/cpu.h | 479 ++++ H8SX/Adv/IAR/cpu.h | 475 ++++ LatticeMico32/GNU/cpu.h | 469 ++++ LatticeMico32/GNU/cpu_a.s | 94 + M14K/CodeSourcery/cpu.h | 473 ++++ M14K/CodeSourcery/cpu_a.s | 103 + M16C/HEW/cpu.h | 472 ++++ M16C/HEW/cpu_a.a30 | 112 + M16C/IAR/cpu.h | 477 ++++ M16C/IAR/cpu_a.s34 | 111 + M32C/HEW/cpu.h | 472 ++++ M32C/HEW/cpu_a.a30 | 112 + M32C/IAR/cpu.h | 477 ++++ M32C/IAR/cpu_a.s48 | 111 + MC9S08/NonPaged/Codewarrior/cpu.h | 475 ++++ MC9S08/NonPaged/Codewarrior/cpu_a.s | 67 + MC9S08/Paged/Codewarrior/cpu.h | 475 ++++ MC9S08/Paged/Codewarrior/cpu_a.s | 67 + MC9S12/Codewarrior/NonPaged/cpu.h | 475 ++++ MC9S12/Codewarrior/NonPaged/cpu_a.s | 74 + MC9S12/Codewarrior/cpu.h | 473 ++++ MC9S12/Codewarrior/cpu_a.s | 72 + MC9S12X/Codewarrior/cpu.h | 474 ++++ MC9S12X/Codewarrior/cpu_a.s | 72 + MCF5272/GNU/cpu.h | 469 ++++ MCF5272/GNU/cpu_a.s | 80 + MIPS32-4K/MPLAB-PIC32-GCC/cpu.h | 515 ++++ MIPS32-4K/MPLAB-PIC32-GCC/cpu_a.s | 142 ++ MPC55xx-VLE/CodeWarrior/cpu.h | 504 ++++ MPC55xx-VLE/CodeWarrior/cpu_a.s | 380 +++ MPC55xx/CodeWarrior/cpu.h | 504 ++++ MPC55xx/CodeWarrior/cpu_a.s | 380 +++ MPC56xx-VLE/CodeWarrior/cpu.h | 504 ++++ MPC56xx-VLE/CodeWarrior/cpu_a.s | 380 +++ MPC56xx/CodeWarrior/cpu.h | 502 ++++ MPC56xx/CodeWarrior/cpu_a.s | 380 +++ MPC57xx-VLE/GNU/cpu.h | 495 ++++ MPC57xx-VLE/GNU/cpu_a.S | 113 + MPC8349E/CodeWarrior/cpu.h | 480 ++++ MPC8349E/CodeWarrior/cpu_a.s | 183 ++ MSP430X/CCS/cpu.h | 473 ++++ MSP430X/CCS/cpu_a.s43 | 100 + MSP430X/IAR/cpu.h | 473 ++++ MSP430X/IAR/cpu_a.s43 | 95 + MicroBlaze/GNU/cpu.h | 496 ++++ MicroBlaze/GNU/cpu_a.S | 162 ++ MicroBlaze/GNU/cpu_c.c | 97 + NiosII/GNU/cpu.h | 470 ++++ NiosII/GNU/cpu_c.c | 87 + PIC24FJ128/C30/cpu.h | 470 ++++ PIC24FJ128/DSPICC/cpu.h | 469 ++++ PIC24FJ128/ICCDSPIC/cpu.h | 470 ++++ PIC30F6014/C30/cpu.h | 470 ++++ PIC33FJ256/C30/cpu.h | 470 ++++ PIC33FJ256/DSPICC/cpu.h | 469 ++++ PIC33FJ256/ICCDSPIC/cpu.h | 470 ++++ PPC405/GNU/cpu.h | 469 ++++ PPC405/GNU/cpu_a.s | 131 + Posix/GNU/cpu.h | 535 ++++ Posix/GNU/cpu_c.c | 885 +++++++ R32C/HEW/cpu.h | 490 ++++ R32C/HEW/cpu_a.a30 | 112 + R32C/IAR/cpu.h | 490 ++++ R32C/IAR/cpu_a.s53 | 103 + RISC-V/GCC/cpu.h | 525 ++++ RISC-V/GCC/cpu_a.S | 123 + RL78/GNURL78/cpu.h | 484 ++++ RL78/GNURL78/cpu_c.c | 58 + RL78/IAR/cpu.h | 497 ++++ RX/GNURX/cpu.h | 525 ++++ RX/GNURX/cpu_a.s | 76 + RX/IAR/cpu.h | 520 ++++ RX/RXC/cpu.h | 518 ++++ RX610/GNURX/cpu.h | 507 ++++ RX610/GNURX/cpu_a.s | 61 + RX610/IAR/cpu.h | 505 ++++ RX610/RXC/cpu.h | 503 ++++ SH-2/HEW/cpu.h | 474 ++++ Template/cpu.h | 552 ++++ Template/cpu_a.asm | 377 +++ V850E2M/CubeSuite+/cpu.h | 490 ++++ V850E2M/CubeSuite+/cpu_a.asm | 131 + V850E2M/IAR/cpu.h | 491 ++++ V850E2M/IAR/cpu_a.s85 | 131 + V850E2S/IAR/cpu.h | 491 ++++ V850E2S/IAR/cpu_a.s85 | 132 + V850ES/CubeSuite/cpu.h | 491 ++++ V850ES/CubeSuite/cpu_a.s | 127 + V850ES/IAR/cpu.h | 491 ++++ V850ES/IAR/cpu_a.s85 | 133 + V850ES/PM+/cpu.h | 491 ++++ V850ES/PM+/cpu_a.s | 128 + Win32/Visual_Studio/cpu.h | 509 ++++ Win32/Visual_Studio/cpu_c.c | 516 ++++ cpu_cache.h | 135 + cpu_core.c | 2254 +++++++++++++++++ cpu_core.h | 1031 ++++++++ cpu_def.h | 212 ++ license.txt | 29 + readme.md | 5 + 208 files changed, 74376 insertions(+) create mode 100644 78K0/IAR/cpu.h create mode 100644 78K0R/IAR/cpu.h create mode 100644 ARC/EM6/MetaWare/cpu.h create mode 100644 ARC/EM6/MetaWare/cpu_a.s create mode 100644 ARC/EM6/MetaWare/cpu_c.c create mode 100644 ARM-Cortex-A/ARMv7-A/ARM/cpu.h create mode 100644 ARM-Cortex-A/ARMv7-A/ARM/cpu_a.s create mode 100644 ARM-Cortex-A/ARMv7-A/CCS/cpu.h create mode 100644 ARM-Cortex-A/ARMv7-A/CCS/cpu_a.asm create mode 100644 ARM-Cortex-A/ARMv7-A/GNU/cpu.h create mode 100644 ARM-Cortex-A/ARMv7-A/GNU/cpu_a.S create mode 100644 ARM-Cortex-A/ARMv7-A/IAR/cpu.h create mode 100644 ARM-Cortex-A/ARMv7-A/IAR/cpu_a.asm create mode 100644 ARM-Cortex-A/ARMv8-A/ARM/cpu.h create mode 100644 ARM-Cortex-A/ARMv8-A/ARM/cpu_a.s create mode 100644 ARM-Cortex-A/ARMv8-A/GNU/cpu.h create mode 100644 ARM-Cortex-A/ARMv8-A/GNU/cpu_a.S create mode 100644 ARM-Cortex-M/ARMv6-M/ARM/cpu.h create mode 100644 ARM-Cortex-M/ARMv6-M/ARM/cpu_a.asm create mode 100644 ARM-Cortex-M/ARMv6-M/GNU/cpu.h create mode 100644 ARM-Cortex-M/ARMv6-M/GNU/cpu_a.s create mode 100644 ARM-Cortex-M/ARMv6-M/IAR/cpu.h create mode 100644 ARM-Cortex-M/ARMv6-M/IAR/cpu_a.asm create mode 100644 ARM-Cortex-M/ARMv6-M/cpu_c.c create mode 100644 ARM-Cortex-M/ARMv7-M/ARM/cpu.h create mode 100644 ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm create mode 100644 ARM-Cortex-M/ARMv7-M/CCS/cpu.h create mode 100644 ARM-Cortex-M/ARMv7-M/CCS/cpu_a.asm create mode 100644 ARM-Cortex-M/ARMv7-M/GNU/cpu.h create mode 100644 ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s create mode 100644 ARM-Cortex-M/ARMv7-M/IAR/cpu.h create mode 100644 ARM-Cortex-M/ARMv7-M/IAR/cpu_a.asm create mode 100644 ARM-Cortex-M/ARMv7-M/cpu_c.c create mode 100644 ARM-Cortex-R/ARMv7-R/ARM/cpu.h create mode 100644 ARM-Cortex-R/ARMv7-R/ARM/cpu_a.s create mode 100644 ARM-Cortex-R/ARMv7-R/CCS/cpu.h create mode 100644 ARM-Cortex-R/ARMv7-R/CCS/cpu_a.asm create mode 100644 ARM-Cortex-R/ARMv7-R/GNU/cpu.h create mode 100644 ARM-Cortex-R/ARMv7-R/GNU/cpu_a.S create mode 100644 ARM-Cortex-R/ARMv7-R/IAR/cpu.h create mode 100644 ARM-Cortex-R/ARMv7-R/IAR/cpu_a.asm create mode 100644 ARM/GNU/cpu.h create mode 100644 ARM/GNU/cpu_a.s create mode 100644 ARM/IAR/cpu.h create mode 100644 ARM/IAR/cpu_a.s create mode 100644 ARM/IAR/cpu_c.c create mode 100644 ARM/RealView/cpu.h create mode 100644 ARM/RealView/cpu_a.s create mode 100644 ARM/RealView/cpu_c.c create mode 100644 AVR/ATmega128/IAR/cpu.h create mode 100644 AVR/ATmega128/IAR/cpu_a.s90 create mode 100644 AVR/ATmega256/IAR/cpu.h create mode 100644 AVR/ATmega256/IAR/cpu_a.s90 create mode 100644 AVR/ATxmega128/GNU/cpu.h create mode 100644 AVR/ATxmega128/GNU/cpu_a.s create mode 100644 AVR/ATxmega128/IAR/cpu.h create mode 100644 AVR/ATxmega128/IAR/cpu_a.s90 create mode 100644 AVR32/AP7000/GNU/cpu.h create mode 100644 AVR32/AP7000/GNU/cpu_a.s create mode 100644 AVR32/AP7000/IAR/cpu.h create mode 100644 AVR32/AP7000/IAR/cpu_a.asm create mode 100644 AVR32/UC3/AtmelStudio6/cpu.h create mode 100644 AVR32/UC3/AtmelStudio6/cpu_a.S create mode 100644 AVR32/UC3/GNU/cpu.h create mode 100644 AVR32/UC3/GNU/cpu_a.s create mode 100644 AVR32/UC3/IAR/cpu.h create mode 100644 AVR32/UC3/IAR/cpu_a.asm create mode 100644 BSP/Template/bsp_cpu.c create mode 100644 Blackfin/VDSP++/cpu.h create mode 100644 Blackfin/VDSP++/cpu_a.asm create mode 100644 C28x/CCS/cpu.h create mode 100644 C28x/CCS/cpu_a.asm create mode 100644 C28x/CCS/cpu_c.c create mode 100644 Cache/ARC/EM6/cpu_cache_em6.c create mode 100644 Cache/ARM/armv5_generic_l1/IAR/cpu_cache_armv5_generic_l1_a.s create mode 100644 Cache/ARM/armv5_generic_l1/cpu_cache_armv5_generic_l1.c create mode 100644 Cache/ARM/armv7_generic_l1/ARM/cpu_cache_armv7_generic_l1_a.s create mode 100644 Cache/ARM/armv7_generic_l1/GNU/cpu_cache_armv7_generic_l1_a.S create mode 100644 Cache/ARM/armv7_generic_l1/IAR/cpu_cache_armv7_generic_l1_a.s create mode 100644 Cache/ARM/armv7_generic_l1/cpu_cache_armv7_generic_l1.c create mode 100644 Cache/ARM/armv7_generic_l1_l2c310_l2/ARM/cpu_cache_armv7_generic_l1_l2c310_l2_a.s create mode 100644 Cache/ARM/armv7_generic_l1_l2c310_l2/GNU/cpu_cache_armv7_generic_l1_l2c310_l2_a.S create mode 100644 Cache/ARM/armv7_generic_l1_l2c310_l2/IAR/cpu_cache_armv7_generic_l1_l2c310_l2_a.s create mode 100644 Cache/ARM/armv7_generic_l1_l2c310_l2/cpu_cache_armv7_generic_l1_l2c310_l2.c create mode 100644 Cache/ARM/armv7m_generic_l1/cpu_cache_armv7m_generic_l1.c create mode 100644 Cache/Freescale/Kinetis/cpu_cache_kinetis.c create mode 100644 Cache/NXP/powerpc_e200z4204n3/GNU/cpu_cache_powerpc_e200z4204n3_a.S create mode 100644 Cache/NXP/powerpc_e200z4204n3/cpu_cache_powerpc_e200z4204n3.c create mode 100644 Cache/NiosII/cpu_cache_niosII.c create mode 100644 Cfg/Template/cpu_cfg.h create mode 100644 ColdFire/Generic/CW_For_Microcontrollers/cpu.h create mode 100644 ColdFire/Generic/CW_For_Microcontrollers/cpu_a.asm create mode 100644 ColdFire/Generic/CW_For_Microcontrollers/cpu_c.c create mode 100644 ColdFire/Generic/Codewarrior/cpu.h create mode 100644 ColdFire/Generic/Codewarrior/cpu_a.asm create mode 100644 ColdFire/Generic/Codewarrior/cpu_c.c create mode 100644 ColdFire/Generic/IAR/cpu.h create mode 100644 ColdFire/Generic/IAR/cpu_a.asm create mode 100644 ColdFire/Generic/IAR/cpu_c.c create mode 100644 EnSilica/eSi-3250/EDS/cpu.h create mode 100644 EnSilica/eSi-3250/EDS/cpu_a.S create mode 100644 EnSilica/eSi-3250/EDS/cpu_c.c create mode 100644 FR/Softune/cpu.h create mode 100644 FR/Softune/cpu_a.asm create mode 100644 H8-300L/Normal/HEW/cpu.h create mode 100644 H8-300L/Normal/IAR/cpu.h create mode 100644 H8S/Adv/HEW/cpu.h create mode 100644 H8S/Adv/IAR/cpu.h create mode 100644 H8SX/Adv/HEW/cpu.h create mode 100644 H8SX/Adv/IAR/cpu.h create mode 100644 LatticeMico32/GNU/cpu.h create mode 100644 LatticeMico32/GNU/cpu_a.s create mode 100644 M14K/CodeSourcery/cpu.h create mode 100644 M14K/CodeSourcery/cpu_a.s create mode 100644 M16C/HEW/cpu.h create mode 100644 M16C/HEW/cpu_a.a30 create mode 100644 M16C/IAR/cpu.h create mode 100644 M16C/IAR/cpu_a.s34 create mode 100644 M32C/HEW/cpu.h create mode 100644 M32C/HEW/cpu_a.a30 create mode 100644 M32C/IAR/cpu.h create mode 100644 M32C/IAR/cpu_a.s48 create mode 100644 MC9S08/NonPaged/Codewarrior/cpu.h create mode 100644 MC9S08/NonPaged/Codewarrior/cpu_a.s create mode 100644 MC9S08/Paged/Codewarrior/cpu.h create mode 100644 MC9S08/Paged/Codewarrior/cpu_a.s create mode 100644 MC9S12/Codewarrior/NonPaged/cpu.h create mode 100644 MC9S12/Codewarrior/NonPaged/cpu_a.s create mode 100644 MC9S12/Codewarrior/cpu.h create mode 100644 MC9S12/Codewarrior/cpu_a.s create mode 100644 MC9S12X/Codewarrior/cpu.h create mode 100644 MC9S12X/Codewarrior/cpu_a.s create mode 100644 MCF5272/GNU/cpu.h create mode 100644 MCF5272/GNU/cpu_a.s create mode 100644 MIPS32-4K/MPLAB-PIC32-GCC/cpu.h create mode 100644 MIPS32-4K/MPLAB-PIC32-GCC/cpu_a.s create mode 100644 MPC55xx-VLE/CodeWarrior/cpu.h create mode 100644 MPC55xx-VLE/CodeWarrior/cpu_a.s create mode 100644 MPC55xx/CodeWarrior/cpu.h create mode 100644 MPC55xx/CodeWarrior/cpu_a.s create mode 100644 MPC56xx-VLE/CodeWarrior/cpu.h create mode 100644 MPC56xx-VLE/CodeWarrior/cpu_a.s create mode 100644 MPC56xx/CodeWarrior/cpu.h create mode 100644 MPC56xx/CodeWarrior/cpu_a.s create mode 100644 MPC57xx-VLE/GNU/cpu.h create mode 100644 MPC57xx-VLE/GNU/cpu_a.S create mode 100644 MPC8349E/CodeWarrior/cpu.h create mode 100644 MPC8349E/CodeWarrior/cpu_a.s create mode 100644 MSP430X/CCS/cpu.h create mode 100644 MSP430X/CCS/cpu_a.s43 create mode 100644 MSP430X/IAR/cpu.h create mode 100644 MSP430X/IAR/cpu_a.s43 create mode 100644 MicroBlaze/GNU/cpu.h create mode 100644 MicroBlaze/GNU/cpu_a.S create mode 100644 MicroBlaze/GNU/cpu_c.c create mode 100644 NiosII/GNU/cpu.h create mode 100644 NiosII/GNU/cpu_c.c create mode 100644 PIC24FJ128/C30/cpu.h create mode 100644 PIC24FJ128/DSPICC/cpu.h create mode 100644 PIC24FJ128/ICCDSPIC/cpu.h create mode 100644 PIC30F6014/C30/cpu.h create mode 100644 PIC33FJ256/C30/cpu.h create mode 100644 PIC33FJ256/DSPICC/cpu.h create mode 100644 PIC33FJ256/ICCDSPIC/cpu.h create mode 100644 PPC405/GNU/cpu.h create mode 100644 PPC405/GNU/cpu_a.s create mode 100644 Posix/GNU/cpu.h create mode 100644 Posix/GNU/cpu_c.c create mode 100644 R32C/HEW/cpu.h create mode 100644 R32C/HEW/cpu_a.a30 create mode 100644 R32C/IAR/cpu.h create mode 100644 R32C/IAR/cpu_a.s53 create mode 100644 RISC-V/GCC/cpu.h create mode 100644 RISC-V/GCC/cpu_a.S create mode 100644 RL78/GNURL78/cpu.h create mode 100644 RL78/GNURL78/cpu_c.c create mode 100644 RL78/IAR/cpu.h create mode 100644 RX/GNURX/cpu.h create mode 100644 RX/GNURX/cpu_a.s create mode 100644 RX/IAR/cpu.h create mode 100644 RX/RXC/cpu.h create mode 100644 RX610/GNURX/cpu.h create mode 100644 RX610/GNURX/cpu_a.s create mode 100644 RX610/IAR/cpu.h create mode 100644 RX610/RXC/cpu.h create mode 100644 SH-2/HEW/cpu.h create mode 100644 Template/cpu.h create mode 100644 Template/cpu_a.asm create mode 100644 V850E2M/CubeSuite+/cpu.h create mode 100644 V850E2M/CubeSuite+/cpu_a.asm create mode 100644 V850E2M/IAR/cpu.h create mode 100644 V850E2M/IAR/cpu_a.s85 create mode 100644 V850E2S/IAR/cpu.h create mode 100644 V850E2S/IAR/cpu_a.s85 create mode 100644 V850ES/CubeSuite/cpu.h create mode 100644 V850ES/CubeSuite/cpu_a.s create mode 100644 V850ES/IAR/cpu.h create mode 100644 V850ES/IAR/cpu_a.s85 create mode 100644 V850ES/PM+/cpu.h create mode 100644 V850ES/PM+/cpu_a.s create mode 100644 Win32/Visual_Studio/cpu.h create mode 100644 Win32/Visual_Studio/cpu_c.c create mode 100644 cpu_cache.h create mode 100644 cpu_core.c create mode 100644 cpu_core.h create mode 100644 cpu_def.h create mode 100644 license.txt create mode 100644 readme.md diff --git a/78K0/IAR/cpu.h b/78K0/IAR/cpu.h new file mode 100644 index 0000000..0c60ca1 --- /dev/null +++ b/78K0/IAR/cpu.h @@ -0,0 +1,479 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* NEC 78K0 Specific code +* IAR C/C++ Compiler for NEC 78K0 4.60A +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __disable_interrupt(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __enable_interrupt(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_state(); \ + __disable_interrupt(); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { __set_interrupt_state(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/78K0R/IAR/cpu.h b/78K0R/IAR/cpu.h new file mode 100644 index 0000000..672a46c --- /dev/null +++ b/78K0R/IAR/cpu.h @@ -0,0 +1,479 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* NEC 78K0R Specific code +* IAR C/C++ Compiler for NEC 78K0R 4.60A +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __disable_interrupt(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __enable_interrupt(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_state(); \ + __disable_interrupt(); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { __set_interrupt_state(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/ARC/EM6/MetaWare/cpu.h b/ARC/EM6/MetaWare/cpu.h new file mode 100644 index 0000000..092013e --- /dev/null +++ b/ARC/EM6/MetaWare/cpu.h @@ -0,0 +1,607 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Synopsys ARC EM6 +* DesignWare ARC C/C++ Compiler +* +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() _sync() +#define CPU_RMB() _sync() +#define CPU_WMB() _sync() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 1 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 1 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ +void CPU_IntLevelSet (CPU_INT08U level); /* Set interrupt priority operating level. */ +void CPU_IntVectTableSet(CPU_FNCT_VOID *p_table); /* Set Interrupt Vector Table. */ + +void CPU_IntSrcDis (CPU_INT08U src); /* Disable specific interrupt source. */ +void CPU_IntSrcEn (CPU_INT08U src); /* Enable specific interrupt source. */ +void CPU_IntSrcPendClr (CPU_INT08U src); /* Clear specific pending interrupt. */ +void CPU_IntSrcPrioSet (CPU_INT08U src, /* Set priority of specific interrupt source. */ + CPU_INT08U prio); + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore (CPU_SR cpu_sr); /* Restore CPU status word. */ + +/* +********************************************************************************************************* +* AUXILIARY REGISTERS +********************************************************************************************************* +*/ + /* Baseline Auxiliary Registers. */ +#define CPU_AR_STATUS32 (0x00Au) +#define CPU_AR_AUX_USER_SP (0x00Du) +#define CPU_AR_INT_VECTOR_BASE (0x025u) + /* Baseline Auxiliary Registers Bits. */ +#define CPU_AR_STATUS32_IE (0x80000000u) +#define CPU_AR_STATUS32_SC (0x00004000u) + + /* Cache Controller Register. */ +#define CPU_AR_DC_IVDC (0x047u) +#define CPU_AR_DC_CTRL (0x048u) +#define CPU_AR_DC_IVDL (0x04Au) +#define CPU_AR_DC_FLSH (0x04Bu) +#define CPU_AR_DC_FLDL (0x04Cu) + /* Cache Controller Register Bits. */ +#define CPU_AR_DC_IVDC_IV (0x0001u) +#define CPU_AR_DC_CTRL_DC (0x0001u) +#define CPU_AR_DC_CTRL_DC_EN (0x0000u) +#define CPU_AR_DC_CTRL_FS (0x0100u) +#define CPU_AR_DC_FLSH_FL (0x0001u) + + /* Interrupt Controller Registers. */ +#define CPU_AR_AUX_IRQ_CTRL (0x00Eu) +#define CPU_AR_AUX_IRQ_HINT (0x201u) +#define CPU_AR_AUX_IRQ_PRIORITY (0x206u) +#define CPU_AR_ICAUSE (0x40Au) +#define CPU_AR_IRQ_SELECT (0x40Bu) +#define CPU_AR_IRQ_ENABLE (0x40Cu) +#define CPU_AR_IRQ_TRIGGER (0x40Du) +#define CPU_AR_IRQ_STATUS (0x40Fu) +#define CPU_AR_IRQ_PULSE_CANCEL (0x415u) + /* Interrupt Controller Register Bits. */ +#define CPU_AR_AUX_IRQ_CTRL_L (0x0400u) +#define CPU_AR_AUX_IRQ_CTRL_LP (0x2000u) +#define CPU_AR_AUX_IRQ_CTRL_NR (14u) + + /* Stack Checker Registers. */ +#define CPU_AR_USTACK_TOP (0x260u) +#define CPU_AR_USTACK_BASE (0x261u) +#define CPU_AR_KSTACK_TOP (0x264u) +#define CPU_AR_KSTACK_BASE (0x265u) + + + +/* +********************************************************************************************************* +* AUXILIARY REGISTER RD/WR +********************************************************************************************************* +*/ + +#define CPU_AR_RD(addr) _lr((addr)) +#define CPU_AR_WR(addr, val) _sr((val), (addr)) + + +/* +********************************************************************************************************* +* INTERRUPT COUNT +********************************************************************************************************* +*/ + +#define CPU_INT_NBR (16u+20u) +#define CPU_INT_INT0 (16u) + + +/* +********************************************************************************************************* +* CACHE CONFIG +********************************************************************************************************* +*/ + +#define CPU_CACHE_DATA_LINE_SIZE (32u) +#define CPU_CACHE_DATA_LINE_MASK (~(CPU_CACHE_DATA_LINE_SIZE-1u)) + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARC/EM6/MetaWare/cpu_a.s b/ARC/EM6/MetaWare/cpu_a.s new file mode 100644 index 0000000..2f40155 --- /dev/null +++ b/ARC/EM6/MetaWare/cpu_a.s @@ -0,0 +1,259 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Synopsys ARC EM6 +; DesignWare ARC C/C++ Compiler +; +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global CPU_IntDis /* Disable interrupts. */ + .global CPU_IntEn /* Enable interrupts. */ + + .global CPU_SR_Save /* Save CPU status word & disable interrupts. */ + .global CPU_SR_Restore /* Restore CPU status word. */ + + .global CPU_CntLeadZeros /* Count leading zeros. */ + .global CPU_CntTrailZeros /* Count trailing zeros. */ + + .global CPU_TS_TmrInit /* Initialize & start CPU timestamp timer. */ + .global CPU_TS_TmrRd /* Get current CPU timestamp timer count value. */ + + +;******************************************************************************************************** +; EXTERNAL GLOBAL VARIABLES +;******************************************************************************************************** + +; .extern CPU_TS_TmrFreq_Hz /* CPU timestamp timer frequency (in Hz). */ + + +;******************************************************************************************************** +; MACROS +;******************************************************************************************************** + +;******************************************************************************************************** +; FUNCTION +; +; Description : This macro declares a symbol of type function and aligns it to 4-bytes. +; +; Arguments : fname function to declare. +; +; Note(s) : none. +;******************************************************************************************************** + +.macro FUNCTION, fname + .type \&fname, @function + .align 4 + \&fname: +.endm + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + .text + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +FUNCTION CPU_IntDis + CLRI + J_S [%blink] + +FUNCTION CPU_IntEn + SETI + J_S [%blink] + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +FUNCTION CPU_SR_Save + CLRI %r0 + J_S [%blink] + +FUNCTION CPU_SR_Restore + SETI %r0 + J_S [%blink] + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +FUNCTION CPU_CntLeadZeros + MOV %r1, 31 + FLS.F %r0, %r0 + MOV.Z %r0, -1 + SUB %r0, %r1, %r0 + J_S [%blink] + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROES +; +; Description : Count the number of contiguous, least-significant, trailing zero bits in a data value. +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +FUNCTION CPU_CntTrailZeros + FFS.F %r0, %r0 + MOV.Z %r0, 32 + J_S [%blink] + + +;******************************************************************************************************** +; CPU_TS_TmrInit() +; +; Description : Initialize & start CPU timestamp timer. +; +; Prototypes : void CPU_TS_TmrInit(void); +; +; Argument(s) : none. +; +; Return(s) : none. +; +; Note(s) : none. +;******************************************************************************************************** + +FUNCTION CPU_TS_TmrInit + J_S [%blink] + + +;******************************************************************************************************** +; CPU_TS_TmrRd() +; +; Description : Get current CPU timestamp timer count value. +; +; Prototypes : CPU_TS_TMR CPU_TS_TmrRd(void); +; +; Argument(s) : none. +; +; Return(s) : Timestamp timer count. +; +; Note(s) : none. +;******************************************************************************************************** + +FUNCTION CPU_TS_TmrRd + MOV %r0, 0 + J_S [%blink] + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + +.end + diff --git a/ARC/EM6/MetaWare/cpu_c.c b/ARC/EM6/MetaWare/cpu_c.c new file mode 100644 index 0000000..64cb7c4 --- /dev/null +++ b/ARC/EM6/MetaWare/cpu_c.c @@ -0,0 +1,390 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Synopsys ARC EM6 +* DesignWare ARC C/C++ Compiler +* +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + +#define CPU_USECS_PER_SEC (1000000ULL) +#define CPU_INT_PRIO_SHIFT (1u) +#define CPU_INT_PRIO_WIDTH (0xFu) + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_IntLevelSet() +* +* Description : Set the interrupt priority operating level. +* +* Argument(s) : level interrupt priority operating level. +* +* Return(s) : None. +* +* Note(s) : None. +********************************************************************************************************* +*/ + +void CPU_IntLevelSet (CPU_INT08U level) +{ + level &= CPU_INT_PRIO_WIDTH; + _kflag(level << CPU_INT_PRIO_SHIFT); +} + + +/* +********************************************************************************************************* +* CPU_IntVectTableSet() +* +* Description : Set Interrupt Vector Table base pointer. +* +* Argument(s) : p_table pointer to base of interrupt vector table. +* +* Return(s) : None. +* +* Note(s) : (1) Must be 1Kbyte aligned. +********************************************************************************************************* +*/ + +void CPU_IntVectTableSet (CPU_FNCT_VOID *p_table) +{ + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + CPU_AR_WR(CPU_AR_INT_VECTOR_BASE, (CPU_INT32U)p_table); + CPU_CRITICAL_EXIT(); +} + + +/* +********************************************************************************************************* +* CPU_IntSrcDis() +* +* Description : Disable an interrupt source. +* +* Argument(s) : src interrupt source to disable. +* +* Return(s) : None. +* +* Note(s) : None. +********************************************************************************************************* +*/ + +void CPU_IntSrcDis (CPU_INT08U src) +{ + CPU_SR_ALLOC(); + + + if ((src >= CPU_INT_INT0) && + (src < CPU_INT_NBR)) { + CPU_CRITICAL_ENTER(); + CPU_AR_WR(CPU_AR_IRQ_SELECT, src); + CPU_AR_WR(CPU_AR_IRQ_ENABLE, 0); + CPU_CRITICAL_EXIT(); + } + + return; +} + + +/* +********************************************************************************************************* +* CPU_IntSrcEn() +* +* Description : Enable an interrupt source. +* +* Argument(s) : src interrupt source to enable. +* +* Return(s) : None. +* +* Note(s) : None. +********************************************************************************************************* +*/ + +void CPU_IntSrcEn (CPU_INT08U src) +{ + CPU_SR_ALLOC(); + + + if ((src >= CPU_INT_INT0) && + (src < CPU_INT_NBR)) { + CPU_CRITICAL_ENTER(); + CPU_AR_WR(CPU_AR_IRQ_SELECT, src); + CPU_AR_WR(CPU_AR_IRQ_ENABLE, 1); + CPU_CRITICAL_EXIT(); + } + + return; +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPendClr() +* +* Description : Clear a pending pulse-triggered interrupt. +* +* Argument(s) : src pulse-triggered interrupt source to clear. +* +* Return(s) : None. +* +* Note(s) : (1) Cannot be used for level-sensitive interrupt sources and software interrupts. +********************************************************************************************************* +*/ + +void CPU_IntSrcPendClr (CPU_INT08U src) +{ + CPU_SR_ALLOC(); + + + if ((src >= CPU_INT_INT0) && + (src < CPU_INT_NBR)) { + CPU_CRITICAL_ENTER(); + CPU_AR_WR(CPU_AR_IRQ_SELECT, src); + CPU_AR_WR(CPU_AR_IRQ_PULSE_CANCEL, 1); + CPU_CRITICAL_EXIT(); + } + + return; +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPrioSet() +* +* Description : Set the priority of an interrupt source. +* +* Argument(s) : src interrupt source to set priority. +* +* prio the priority. +* +* Return(s) : None. +* +* Note(s) : None. +********************************************************************************************************* +*/ + +void CPU_IntSrcPrioSet (CPU_INT08U src, + CPU_INT08U prio) +{ + CPU_SR_ALLOC(); + + + if ((src >= CPU_INT_INT0) && + (src < CPU_INT_NBR)) { + CPU_CRITICAL_ENTER(); + CPU_AR_WR(CPU_AR_IRQ_SELECT, src); + CPU_AR_WR(CPU_AR_AUX_IRQ_PRIORITY, prio); + CPU_CRITICAL_EXIT(); + } +} + + +/* +********************************************************************************************************* +* CPU_TS_TmrInit() +* +* Description : Initialize & start CPU timestamp timer. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +void CPU_TS_TmrInit (void) +{ + /* Initialize a performance counter with 'crun' as the countable condition. */ +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrRd() +* +* Description : Get current CPU timestamp timer count value. +* +* Argument(s) : none. +* +* Return(s) : Timestamp timer count. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_TS_TMR CPU_TS_TmrRd (void) +{ + /* Return the snapshot of the performance counter with 'crun' as the countable condition. */ +} +#endif + + +/* +********************************************************************************************************* +* CPU_TSxx_to_uSec() +* +* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds. +* +* Argument(s) : ts_cnts CPU timestamp (in timestamp timer counts [see Note #2aA]). +* +* Return(s) : Converted CPU timestamp (in microseconds [see Note #2aD]). +* +* Note(s) : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be +* optionally defined by the developer when either of the following CPU features is +* enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) The amount of time measured by CPU timestamps is calculated by either of +* the following equations : +* +* 10^6 microseconds +* (1) Time measured = Number timer counts * ------------------- * Timer period +* 1 second +* +* Number timer counts 10^6 microseconds +* (2) Time measured = --------------------- * ------------------- +* Timer frequency 1 second +* +* where +* +* (A) Number timer counts Number of timer counts measured +* (B) Timer frequency Timer's frequency in some units +* of counts per second +* (C) Timer period Timer's period in some units of +* (fractional) seconds +* (D) Time measured Amount of time measured, +* in microseconds +* +* (b) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +* +* (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits +* -- up to 32 or 64, respectively -- into microseconds. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts) +{ + CPU_INT64U time; + + + time = ((CPU_INT64U)ts_cnts*(CPU_INT64U)CPU_USECS_PER_SEC)/((CPU_INT64U)CPU_TS_TmrFreq_Hz); + + return (time); +} +#endif + + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts) +{ + + /* $$$$ Insert code to convert (up to) 64-bits of 64-bit CPU timestamp to microseconds (see Note #2) */ + + return (0u); +} +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/ARM-Cortex-A/ARMv7-A/ARM/cpu.h b/ARM-Cortex-A/ARMv7-A/ARM/cpu.h new file mode 100644 index 0000000..fd5f474 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/ARM/cpu.h @@ -0,0 +1,538 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-A +* ARM C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#if defined(__BIG_ENDIAN) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + +static __asm int disable_irq(void) +{ + MRS r0,APSR ; formerly CPSR + AND r0,r0,#0x80 + CPSID i + BX lr +} + + + +#define CPU_INT_DIS() do { cpu_sr = disable_irq(); __dsb(0xF);} while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { if(!cpu_sr) {__dsb(0xF); __enable_irq();} } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __dsb(0xF) +#define CPU_RMB() __dsb(0xF) +#define CPU_WMB() __dsb(0xF) + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv7-A/ARM/cpu_a.s b/ARM-Cortex-A/ARMv7-A/ARM/cpu_a.s new file mode 100644 index 0000000..92c016c --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/ARM/cpu_a.s @@ -0,0 +1,257 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-A +; ARM C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_WaitForInt + EXPORT CPU_WaitForEvent + + EXPORT CPU_CntLeadZeros + EXPORT CPU_CntTrailZeros + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA |.text|, CODE, READONLY, ALIGN=4 + PRESERVE8 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis FUNCTION + + CPSID IF + DSB + BX LR + + ENDFUNC + + +CPU_IntEn FUNCTION + + DSB + CPSIE IF + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save FUNCTION + + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + ENDFUNC + +CPU_SR_Restore FUNCTION ; See Note #2 + + DSB + MSR CPSR_c, R0 + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt FUNCTION + + DSB + WFI ; Wait for interrupt + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent FUNCTION + + DSB + WFE ; Wait for exception + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros FUNCTION + + CLZ R0, R0 ; Count leading zeros + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros FUNCTION + + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-A/ARMv7-A/CCS/cpu.h b/ARM-Cortex-A/ARMv7-A/CCS/cpu.h new file mode 100644 index 0000000..68f2351 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/CCS/cpu.h @@ -0,0 +1,504 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-A +* TI C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#if defined(__big_endian__) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ (" dsb") +#define CPU_RMB() __asm__ __volatile__ (" dsb") +#define CPU_WMB() __asm__ __volatile__ (" dsb") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +* +* (2) CPU_PMU_xxx() functions are intended to manage the Event & Performanace Monitor unit (PMU). +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv7-A/CCS/cpu_a.asm b/ARM-Cortex-A/ARMv7-A/CCS/cpu_a.asm new file mode 100644 index 0000000..6c55837 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/CCS/cpu_a.asm @@ -0,0 +1,222 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-A +; TI C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + .text + .arm + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_WaitForInt + .global CPU_WaitForEvent + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis: + CPSID IF + DSB + BX LR + + +CPU_IntEn: + DSB + CPSIE IF + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save: + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore: ; See Note #2 + DSB + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt: + DSB + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent: + DSB + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros: + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros: + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + diff --git a/ARM-Cortex-A/ARMv7-A/GNU/cpu.h b/ARM-Cortex-A/ARMv7-A/GNU/cpu.h new file mode 100644 index 0000000..8116102 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/GNU/cpu.h @@ -0,0 +1,506 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-A +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + +#define CPU_INT_DIS() __asm__ __volatile__ ("mrs %[sr_res], cpsr\r\n" "cpsid if\r\n" "dsb\r\n" : [sr_res]"=r" (cpu_sr) :: "memory"); + +#define CPU_INT_EN() __asm__ __volatile__ ("dsb\r\n" "msr cpsr_c, %[sr_val]\r\n" :: [sr_val]"r" (cpu_sr) : "memory"); + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +* +* (2) CPU_PMU_xxx() functions are intended to manage the Event & Performanace Monitor unit (PMU). +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv7-A/GNU/cpu_a.S b/ARM-Cortex-A/ARMv7-A/GNU/cpu_a.S new file mode 100644 index 0000000..9454fb4 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/GNU/cpu_a.S @@ -0,0 +1,223 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU PORT FILE +@ +@ ARMv7-A +@ GNU C Compiler +@ +@ Filename : cpu_a.S +@ Version : v1.32.00 +@******************************************************************************************************** + + +@******************************************************************************************************** +@ .global FUNCTIONS +@******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_WaitForInt + .global CPU_WaitForEvent + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + + +@******************************************************************************************************** +@ CODE GENERATION DIRECTIVES +@******************************************************************************************************** + + .code 32 + + +@******************************************************************************************************** +@ ENABLE & DISABLE INTERRUPTS +@ +@ Description : Disable/Enable IRQs & FIQs. +@ +@ Prototypes : void CPU_IntEn (void)@ +@ void CPU_IntDis(void)@ +@******************************************************************************************************** + + .type CPU_IntDis, %function +CPU_IntDis: + CPSID IF + DSB + BX LR + + + .type CPU_IntEn, %function +CPU_IntEn: + DSB + CPSIE IF + BX LR + + +@******************************************************************************************************** +@ CRITICAL SECTION FUNCTIONS +@ +@ Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +@ state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +@ are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +@ The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +@ +@ Prototypes : CPU_SR CPU_SR_Save (void)@ +@ void CPU_SR_Restore(CPU_SR cpu_sr)@ +@ +@ Note(s) : (1) These functions are used in general like this : +@ +@ void Task (void *p_arg) +@ { +@ CPU_SR_ALLOC()@ /* Allocate storage for CPU status register */ +@ : +@ : +@ CPU_CRITICAL_ENTER()@ /* cpu_sr = CPU_SR_Save()@ */ +@ : +@ : +@ CPU_CRITICAL_EXIT()@ /* CPU_SR_Restore(cpu_sr)@ */ +@ : +@ } +@******************************************************************************************************** + + .type CPU_SR_Save, %function +CPU_SR_Save: + MRS R0, CPSR + CPSID IF @ Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR @ DISABLED, return the original CPSR contents in R0 + + .type CPU_SR_Restore, %function +CPU_SR_Restore: + DSB + MSR CPSR_c, R0 + BX LR + + +@******************************************************************************************************** +@ WAIT FOR INTERRUPT +@ +@ Description : Enters sleep state, which will be exited when an interrupt is received. +@ +@ Prototypes : void CPU_WaitForInt (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + + .type CPU_WaitForInt, %function +CPU_WaitForInt: + DSB + WFI @ Wait for interrupt + BX LR + + + +@******************************************************************************************************** +@ WAIT FOR EXCEPTION +@ +@ Description : Enters sleep state, which will be exited when an exception is received. +@ +@ Prototypes : void CPU_WaitForExcept (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + + .type CPU_WaitForEvent, %function +CPU_WaitForEvent: + DSB + WFE @ Wait for exception + BX LR + + +@******************************************************************************************************** +@ CPU_CntLeadZeros() +@ COUNT LEADING ZEROS +@ +@ Description : Counts the number of contiguous, most-significant, leading zero bits before the first +@ binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count leading zero bits. +@ +@ Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +@ +@ Note(s) : (1) If the argument is zero, the value 32 is returned. +@ +@ (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + + .type CPU_CntLeadZeros, %function +CPU_CntLeadZeros: + CLZ R0, R0 @ Count leading zeros + BX LR + + +@******************************************************************************************************** +@ CPU_CntTrailZeros() +@ COUNT TRAILING ZEROS +@ +@ Description : Counts the number of contiguous, least-significant, trailing zero bits before the +@ first binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count trailing zero bits. +@ +@ Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +@ +@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +@ CPU WORD CONFIGURATION Note #1'). +@ +@ (b) For 32-bit values : +@ +@ b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +@ --- --- --- --- --- --- --- --- ---------------- +@ x x x x x x x 1 0 +@ x x x x x x 1 0 1 +@ x x x x x 1 0 0 2 +@ : : : : : : : : : +@ : : : : : : : : : +@ x x x x 1 0 0 0 27 +@ x x x 1 0 0 0 0 28 +@ x x 1 0 0 0 0 0 29 +@ x 1 0 0 0 0 0 0 30 +@ 1 0 0 0 0 0 0 0 31 +@ 0 0 0 0 0 0 0 0 32 +@ +@ +@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + + .type CPU_CntTrailZeros, %function +CPU_CntTrailZeros: + RBIT R0, R0 @ Reverse bits + CLZ R0, R0 @ Count trailing zeros + BX LR + + +@******************************************************************************************************** +@ CPU ASSEMBLY PORT FILE END +@******************************************************************************************************** + + .end + diff --git a/ARM-Cortex-A/ARMv7-A/IAR/cpu.h b/ARM-Cortex-A/ARMv7-A/IAR/cpu.h new file mode 100644 index 0000000..2574ffa --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/IAR/cpu.h @@ -0,0 +1,514 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-A +* IAR EWARM +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) '__LITTLE_ENDIAN__' is an IAR compiler #define that reflects the '--endian' option, +* indicating the data word-memory order : +* +* (a) '0' for big endian word-memory order +* (b) '1' for little endian word-memory order +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (defined(__LITTLE_ENDIAN__) && \ + (__LITTLE_ENDIAN__ == 1)) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* See Note #3b. */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* See Note #3a. */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __DSB() +#define CPU_RMB() __DSB() +#define CPU_WMB() __DSB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +* +* (2) CPU_PMU_xxx() functions are intended to manage the Event & Performanace Monitor unit (PMU). +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv7-A/IAR/cpu_a.asm b/ARM-Cortex-A/ARMv7-A/IAR/cpu_a.asm new file mode 100644 index 0000000..5b0ab01 --- /dev/null +++ b/ARM-Cortex-A/ARMv7-A/IAR/cpu_a.asm @@ -0,0 +1,217 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-A +; IAR EWARM +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_WaitForInt + PUBLIC CPU_WaitForEvent + + PUBLIC CPU_CntLeadZeros + PUBLIC CPU_CntTrailZeros + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + PRESERVE8 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID IF + DSB + BX LR + + +CPU_IntEn + DSB + CPSIE IF + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore + DSB + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt + DSB + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent + DSB + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the first +; binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) If the argument is zero, the value 32 is returned. +; +; (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-A/ARMv8-A/ARM/cpu.h b/ARM-Cortex-A/ARMv8-A/ARM/cpu.h new file mode 100644 index 0000000..935bcb1 --- /dev/null +++ b/ARM-Cortex-A/ARMv8-A/ARM/cpu.h @@ -0,0 +1,530 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv8-A +* ARM C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_64 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_64 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (16u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT64U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT64U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb sy" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb sy" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb sy" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv8-A/ARM/cpu_a.s b/ARM-Cortex-A/ARMv8-A/ARM/cpu_a.s new file mode 100644 index 0000000..ed63fbe --- /dev/null +++ b/ARM-Cortex-A/ARMv8-A/ARM/cpu_a.s @@ -0,0 +1,262 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv8-A +; ARM C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_WaitForInt + EXPORT CPU_WaitForEvent + + EXPORT CPU_CntLeadZeros + EXPORT CPU_CntTrailZeros + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA |.text|, CODE, READONLY, ALIGN=4 + PRESERVE8 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis FUNCTION + + MSR DAIFSet, #3 + DSB SY + RET + + ENDFUNC + + +CPU_IntEn FUNCTION + + DSB SY + MSR DAIFClr, #3 + RET + + ENDFUNC + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save FUNCTION + + MRS x0, DAIF + MSR DAIFSet, #3 + DSB SY + RET + + ENDFUNC + + +CPU_SR_Restore FUNCTION + + DSB SY + MOV x1, #0xC0 + ANDS x0, x0, x1 + B.NE CPU_SR_Restore_Exit + MSR DAIFClr, #3 +CPU_SR_Restore_Exit + RET + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt FUNCTION + + DSB SY + WFI ; Wait for interrupt + RET + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent FUNCTION + + DSB SY + WFE ; Wait for exception + RET + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros FUNCTION + + CLZ x0, x0 ; Count leading zeros + RET + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros FUNCTION + + RBIT x0, x0 ; Reverse bits + CLZ x0, x0 ; Count trailing zeros + RET + + ENDFUNC + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-A/ARMv8-A/GNU/cpu.h b/ARM-Cortex-A/ARMv8-A/GNU/cpu.h new file mode 100644 index 0000000..32e7664 --- /dev/null +++ b/ARM-Cortex-A/ARMv8-A/GNU/cpu.h @@ -0,0 +1,543 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv8-A +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_64 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_64 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (16u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT64U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT64U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb sy" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb sy" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb sy" : : : "memory") + +/* +********************************************************************************************************* +* CP15 ACCESSORS +* +* Note(s) : (1) (a) Read and Write CP15 registers using the architecturally defined name. +* +********************************************************************************************************* +*/ + +#define CPU_CP_GET(val, reg) __asm__ __volatile__ ("mrs %0, " #reg : "=r" (val) : : "memory") + +#define CPU_CP_SET(val, reg) __asm__ __volatile__ ("msr " #reg ",%0" : : "r" (val) : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-A/ARMv8-A/GNU/cpu_a.S b/ARM-Cortex-A/ARMv8-A/GNU/cpu_a.S new file mode 100644 index 0000000..e8964fe --- /dev/null +++ b/ARM-Cortex-A/ARMv8-A/GNU/cpu_a.S @@ -0,0 +1,244 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv8-A +* GNU C Compiler +* +* Filename : cpu_a.S +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* .global FUNCTIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_WaitForInt + .global CPU_WaitForEvent + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + + +/* +********************************************************************************************************* +* CODE GENERATION DIRECTIVES +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DISABLE and ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts. +* +* Prototypes : void CPU_IntDis(void); +* void CPU_IntEn (void); +********************************************************************************************************* +*/ + +CPU_IntDis: + + MSR DAIFSet, #3 + DSB SY + RET + +CPU_IntEn: + + DSB SY + MSR DAIFClr, #3 + RET + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +* state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +* are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +* The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +* +* Prototypes : CPU_SR CPU_SR_Save (void)* +* void CPU_SR_Restore(CPU_SR cpu_sr)* +********************************************************************************************************* +*/ + +CPU_SR_Save: + + MRS x0, DAIF + MSR DAIFSet, #3 + DSB SY + RET + + +CPU_SR_Restore: + + DSB SY + MOV x1, #0xC0 + ANDS x0, x0, x1 + B.NE CPU_SR_Restore_Exit + MSR DAIFClr, #3 +CPU_SR_Restore_Exit: + RET + + +/* +********************************************************************************************************* +* WAIT FOR INTERRUPT +* +* Description : Enters sleep state, which will be exited when an interrupt is received. +* +* Prototypes : void CPU_WaitForInt (void) +* +* Argument(s) : none. +********************************************************************************************************* +*/ + +CPU_WaitForInt: + + DSB SY + WFI /* Wait for interrupt */ + RET + + +/* +********************************************************************************************************* +* WAIT FOR EXCEPTION +* +* Description : Enters sleep state, which will be exited when an exception is received. +* +* Prototypes : void CPU_WaitForExcept (void) +* +* Argument(s) : none. +********************************************************************************************************* +*/ + +CPU_WaitForEvent: + + DSB SY + WFE /* Wait for exception */ + RET + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val)* +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +* #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + + CLZ x0, x0 /* Count leading zeros */ + RET + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros() +* COUNT TRAILING ZEROS +* +* Description : Counts the number of contiguous, least-significant, trailing zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val)* +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 27 +* x x x 1 0 0 0 0 28 +* x x 1 0 0 0 0 0 29 +* x 1 0 0 0 0 0 0 30 +* 1 0 0 0 0 0 0 0 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +* #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntTrailZeros: + + RBIT x0, x0 /* Reverse bits */ + CLZ x0, x0 /* Count trailing zeros */ + RET + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ diff --git a/ARM-Cortex-M/ARMv6-M/ARM/cpu.h b/ARM-Cortex-M/ARMv6-M/ARM/cpu.h new file mode 100644 index 0000000..130f937 --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/ARM/cpu.h @@ -0,0 +1,655 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv6-M +* ARM C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __dsb(0xF) +#define CPU_RMB() __dsb(0xF) +#define CPU_WMB() __dsb(0xF) + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio); + + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); /* C-code replacement for asm function */ + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_RSVD_04 4u /* RSVD interrupts may be designated on newer models */ +#define CPU_INT_RSVD_05 5u +#define CPU_INT_RSVD_06 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_RSVD_12 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv6-M/ARM/cpu_a.asm b/ARM-Cortex-M/ARMv6-M/ARM/cpu_a.asm new file mode 100644 index 0000000..bc3d7f8 --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/ARM/cpu_a.asm @@ -0,0 +1,143 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv6-M +; ARM C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +; Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_WaitForInt + EXPORT CPU_WaitForExcept + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA |.text|, CODE, READONLY, ALIGN=2 + THUMB + REQUIRE8 + PRESERVE8 + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID I + BX LR + + +CPU_IntEn + CPSIE I + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, PRIMASK ; Set prio int mask to mask all (except faults) + CPSID I + BX LR + + +CPU_SR_Restore ; See Note #2. + MSR PRIMASK, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForExcept + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-M/ARMv6-M/GNU/cpu.h b/ARM-Cortex-M/ARMv6-M/GNU/cpu.h new file mode 100644 index 0000000..c7d0798 --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/GNU/cpu.h @@ -0,0 +1,655 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv6-M +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio); + + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); /* C-code replacement for asm function */ + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_RSVD_04 4u /* RSVD interrupts may be designated on newer models */ +#define CPU_INT_RSVD_05 5u +#define CPU_INT_RSVD_06 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_RSVD_12 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv6-M/GNU/cpu_a.s b/ARM-Cortex-M/ARMv6-M/GNU/cpu_a.s new file mode 100644 index 0000000..65579fd --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/GNU/cpu_a.s @@ -0,0 +1,148 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU PORT FILE +@ +@ ARMv6-M +@ GNU C Compiler +@ +@ Filename : cpu_a.s +@ Version : v1.32.00 +@******************************************************************************************************** +@ Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +@******************************************************************************************************** + + +@******************************************************************************************************** +@ PUBLIC FUNCTIONS +@******************************************************************************************************** + +.global CPU_IntDis +.global CPU_IntEn + +.global CPU_SR_Save +.global CPU_SR_Restore + +.global CPU_WaitForInt +.global CPU_WaitForExcept + + +@******************************************************************************************************** +@ CODE GENERATION DIRECTIVES +@******************************************************************************************************** + +.text +.align 2 +.thumb +.syntax unified + + +@******************************************************************************************************** +@ DISABLE and ENABLE INTERRUPTS +@ +@ Description : Disable/Enable interrupts. +@ +@ Prototypes : void CPU_IntDis(void); +@ void CPU_IntEn (void); +@******************************************************************************************************** + +.thumb_func +CPU_IntDis: + CPSID I + BX LR + +.thumb_func +CPU_IntEn: + CPSIE I + BX LR + + +@******************************************************************************************************** +@ CRITICAL SECTION FUNCTIONS +@ +@ Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +@ state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +@ are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +@ The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +@ +@ Prototypes : CPU_SR CPU_SR_Save (void); +@ void CPU_SR_Restore(CPU_SR cpu_sr); +@ +@ Note(s) : (1) These functions are used in general like this : +@ +@ void Task (void *p_arg) +@ { +@ CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +@ : +@ : +@ CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +@ : +@ : +@ CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +@ : +@ } +@******************************************************************************************************** + +.thumb_func +CPU_SR_Save: + MRS R0, PRIMASK @ Set prio int mask to mask all (except faults) + CPSID I + BX LR + +.thumb_func +CPU_SR_Restore: @ See Note #2. + MSR PRIMASK, R0 + BX LR + + +@******************************************************************************************************** +@ WAIT FOR INTERRUPT +@ +@ Description : Enters sleep state, which will be exited when an interrupt is received. +@ +@ Prototypes : void CPU_WaitForInt (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.thumb_func +CPU_WaitForInt: + WFI @ Wait for interrupt + BX LR + + +@******************************************************************************************************** +@ WAIT FOR EXCEPTION +@ +@ Description : Enters sleep state, which will be exited when an exception is received. +@ +@ Prototypes : void CPU_WaitForExcept (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.thumb_func +CPU_WaitForExcept: + WFE @ Wait for exception + BX LR + + +@******************************************************************************************************** +@ CPU ASSEMBLY PORT FILE END +@******************************************************************************************************** + +.end + diff --git a/ARM-Cortex-M/ARMv6-M/IAR/cpu.h b/ARM-Cortex-M/ARMv6-M/IAR/cpu.h new file mode 100644 index 0000000..2921a2f --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/IAR/cpu.h @@ -0,0 +1,657 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv6-M +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __DSB() +#define CPU_RMB() __DSB() +#define CPU_WMB() __DSB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio); + + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); /* C-code replacement for asm function */ + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_RSVD_04 4u /* RSVD interrupts may be designated on newer models */ +#define CPU_INT_RSVD_05 5u +#define CPU_INT_RSVD_06 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_RSVD_12 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv6-M/IAR/cpu_a.asm b/ARM-Cortex-M/ARMv6-M/IAR/cpu_a.asm new file mode 100644 index 0000000..38bb2a6 --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/IAR/cpu_a.asm @@ -0,0 +1,142 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv6-M +; IAR C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +; Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + PUBLIC CPU_WaitForInt + PUBLIC CPU_WaitForExcept + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + THUMB + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID I + BX LR + + +CPU_IntEn + CPSIE I + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, PRIMASK ; Set prio int mask to mask all (except faults) + CPSID I + BX LR + + +CPU_SR_Restore ; See Note #2. + MSR PRIMASK, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForExcept + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-M/ARMv6-M/cpu_c.c b/ARM-Cortex-M/ARMv6-M/cpu_c.c new file mode 100644 index 0000000..17b88a2 --- /dev/null +++ b/ARM-Cortex-M/ARMv6-M/cpu_c.c @@ -0,0 +1,695 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv6-M +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + +#define CPU_INT_SRC_POS_MAX ((((CPU_REG_ICTR + 1) & 0x1F) * 32) + 16) + +#define CPU_BIT_BAND_SRAM_REG_LO 0x20000000 +#define CPU_BIT_BAND_SRAM_REG_HI 0x200FFFFF +#define CPU_BIT_BAND_SRAM_BASE 0x22000000 + + +#define CPU_BIT_BAND_PERIPH_REG_LO 0x40000000 +#define CPU_BIT_BAND_PERIPH_REG_HI 0x400FFFFF +#define CPU_BIT_BAND_PERIPH_BASE 0x42000000 + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +* +* Note(s) : (1) Determines the interrupt programmable priority levels. This is normally specified in the +* Microcontroller reference manual. 2-bits gives us 4 programmable priority levels. +* +* NVIC_IPRx +* 7 0 +* +------------------+ +* | PRIO | +* +------------------+ +* +* Bits[7:6] Priority mask bits +* Bits[5:0] Reserved +* +* In this example our CPU_CFG_NVIC_PRIO_BITS define should be set to 2 due to the processor +* implementing only bits[7:6]. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_NVIC_PRIO_BITS +#error "CPU_CFG_NVIC_PRIO_BITS not #define'd in 'cpu_cfg.h' " /* See Note # 1 */ +#endif + + +/* +********************************************************************************************************* +* CPU_BitBandClr() +* +* Description : Clear bit in bit-band region. +* +* Argument(s) : addr Byte address in memory space. +* +* bit_nbr Bit number in byte. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr) +{ + CPU_ADDR bit_word_off; + CPU_ADDR bit_word_addr; + + + if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) && + (addr <= CPU_BIT_BAND_SRAM_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 0; + + } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) && + (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 0; + } +} + + +/* +********************************************************************************************************* +* CPU_BitBandSet() +* +* Description : Set bit in bit-band region. +* +* Argument(s) : addr Byte address in memory space. +* +* bit_nbr Bit number in byte. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr) +{ + CPU_ADDR bit_word_off; + CPU_ADDR bit_word_addr; + + + if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) && + (addr <= CPU_BIT_BAND_SRAM_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 1; + + } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) && + (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 1; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcDis() +* +* Description : Disable an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table : +* +* 0 Invalid (see Note #1a). +* 1 Invalid (see Note #1b). +* 2 Non-maskable Interrupt. +* 3 Hard Fault. +* 4 Memory Management. +* 5 Bus Fault. +* 6 Usage Fault. +* 7-10 Reserved. +* 11 SVCall. +* 12 Debug Monitor. +* 13 Reserved. +* 14 PendSV. +* 15 SysTick. +* 16+ External Interrupt. +* +* Return(s) : none. +* +* Note(s) : (1) Several table positions do not contain interrupt sources : +* +* (a) Position 0 contains the stack pointer. +* (b) Positions 7-10, 13 are reserved. +* +* (2) Several interrupts cannot be disabled/enabled : +* +* (a) Reset. +* (b) NMI. +* (c) Hard fault. +* (d) SVCall. +* (e) Debug monitor. +* (f) PendSV. +* +* (3) The maximum Cortex-M0 table position is 256. A particular Cortex-M0 may have fewer +* than 240 external exceptions and, consequently, fewer than 256 table positions. +* This function assumes that the specified table position is valid if the interrupt +* controller type register's INTLINESNUM field is large enough so that the position +* COULD be valid. +********************************************************************************************************* +*/ + +void CPU_IntSrcDis (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT08U pos_max; + CPU_INT08U nbr; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SYST_CSR &= ~CPU_REG_SYST_CSR_ENABLE; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ICER(group) = DEF_BIT(nbr); /* Disable interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcEn() +* +* Description : Enable an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) See 'CPU_IntSrcDis() Note #2'. +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +void CPU_IntSrcEn (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT08U pos_max; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_ENABLE; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ISER(group) = DEF_BIT(nbr); /* Enable interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPendClr() +* +* Description : Clear a pending interrupt. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) The pending status of several interrupts cannot be clear/set : +* +* (a) Reset. +* (b) NMI. +* (c) Hard fault. +* (d) Memory Managment. +* (e) Bus Fault. +* (f) Usage Fault. +* (g) SVCall. +* (h) Debug monitor. +* (i) PendSV. +* (j) Systick +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +void CPU_IntSrcPendClr (CPU_INT08U pos) + +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT08U pos_max; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + case CPU_INT_SYSTICK: /* SysTick. */ + break; + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ICPR(group) = DEF_BIT(nbr); /* Clear Pending interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPrioSet() +* +* Description : Set priority of an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* prio Priority. Use a lower priority number for a higher priority. +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) Several interrupts priorities CANNOT be set : +* +* (a) Reset (always -3). +* (b) NMI (always -2). +* (c) Hard fault (always -1). +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +void CPU_IntSrcPrioSet (CPU_INT08U pos, + CPU_INT08U prio) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT08U pos_max; + CPU_INT32U temp; + CPU_INT32U prio_offset; + CPU_SR_ALLOC(); + + + prio_offset = (prio << (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS)); + if (prio >= (1u << CPU_CFG_NVIC_PRIO_BITS)) { /* Priority should not exceed the max allowed by MCU */ + CPU_SW_Exception(); + } + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + break; + + case CPU_INT_SVCALL: /* SVCall. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI2; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI2 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_PENDSV: /* PendSV. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI3 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI3 = temp; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 4; + nbr = (pos - 16) % 4; + + CPU_CRITICAL_ENTER(); + temp = CPU_REG_NVIC_IPR(group); + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (nbr * DEF_OCTET_NBR_BITS)); + CPU_REG_NVIC_IPR(group) = temp; /* Set interrupt priority. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPrioGet() +* +* Description : Get priority of an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : Priority of interrupt source. If the interrupt source specified is invalid, then +* DEF_INT_16S_MIN_VAL is returned. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) See 'CPU_IntSrcPrioSet() Note #2'. +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +CPU_INT16S CPU_IntSrcPrioGet (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT08U pos_max; + CPU_INT16S prio; + CPU_INT32U temp; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + prio = DEF_INT_16S_MIN_VAL; + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + prio = -3; + break; + + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + prio = -2; + break; + + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + prio = -1; + break; + + case CPU_INT_SVCALL: /* SVCall. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI2; + prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_PENDSV: /* PendSV. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 4; + nbr = (pos - 16) % 4; + + CPU_CRITICAL_ENTER(); + temp = CPU_REG_NVIC_IPR(group); /* Read group interrupt priority. */ + CPU_CRITICAL_EXIT(); + + prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + } else { + prio = DEF_INT_16S_MIN_VAL; + } + break; + } + + if (prio != DEF_INT_16S_MIN_VAL) { + prio = (prio >> (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS)); + } + + return (prio); +} + + +/* +********************************************************************************************************* +* CPU_RevBits() +*Description : Reverses the bits in a data value. +* +* Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +* +* Argument(s) : val Data value to reverse bits. +* +* Return(s) : Value with all bits in 'val' reversed (see Note #1). +* +* Note(s) : (1) val is a 32-bit number +* (2) Goes through a number and checks for sets bits which are then set +* in the reverse locations: +* +* reverse_val => 0b00000....00 +* val => 0101100....10 +* val's 2nd bit is set => reverse_val's bit (num_bits - 1 - count) +* val's 5th bit is set => reverse_val's bit (num_bits - 1 - count) +* ... ... +* ... ... +* +********************************************************************************************************* +*/ + +CPU_DATA CPU_RevBits(CPU_DATA val) +{ + CPU_DATA reverse_val; + CPU_INT08U nbr_bits; /* establish how many bits are in val */ + CPU_INT32U cnt; /* for stepping through each bit in val */ + CPU_INT32U tmp; /* gets shifted off bit to check if set or not */ + + + nbr_bits = sizeof(CPU_DATA) * 8; + reverse_val = 0; /* make sure reverse_val is cleared out to zeros */ + + for (cnt = 0; cnt < nbr_bits; cnt++) + { + tmp = (val & (1 << cnt)); /* shift the next bit into tmp */ + + if(tmp) { + reverse_val |= (1 << ((nbr_bits - 1) - cnt)); /* shift in a 1 bit to reverse equivalent bit */ + } + } + + return (reverse_val); +} + +#ifdef __cplusplus +} +#endif diff --git a/ARM-Cortex-M/ARMv7-M/ARM/cpu.h b/ARM-Cortex-M/ARMv7-M/ARM/cpu.h new file mode 100644 index 0000000..b3aa027 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/ARM/cpu.h @@ -0,0 +1,762 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-M +* ARM C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + /* Save CPU current BASEPRI priority lvl for exception. */ +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0) +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __dsb(0xF) +#define CPU_RMB() __dsb(0xF) +#define CPU_WMB() __dsb(0xF) + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio, + CPU_INT08U type); + + +CPU_SR CPU_SR_Save (CPU_SR new_basepri); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_MEM 4u +#define CPU_INT_BUSFAULT 5u +#define CPU_INT_USAGEFAULT 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_DBGMON 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* INTERRUPT TYPE +********************************************************************************************************* +*/ + +#define CPU_INT_KA 0u /* Kernel Aware interrupt request. */ +#define CPU_INT_NKA 1u /* Non-Kernel Aware interrupt request. */ + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IABR(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */ +#define CPU_REG_SCB_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ +#define CPU_REG_SCB_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */ +#define CPU_REG_SCB_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */ +#define CPU_REG_SCB_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */ +#define CPU_REG_SCB_CPACR (*((CPU_REG32 *)(0xE000ED88))) /* Coprocessor Access Control Reg. */ + + /* ----- SCB REG FOR FP EXTENSION ----- */ +#define CPU_REG_SCB_FPCCR (*((CPU_REG32 *)(0xE000EF34))) /* Floating-Point Context Control Reg. */ +#define CPU_REG_SCB_FPCAR (*((CPU_REG32 *)(0xE000EF38))) /* Floating-Point Context Address Reg. */ +#define CPU_REG_SCB_FPDSCR (*((CPU_REG32 *)(0xE000EF3C))) /* FP Default Status Control Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */ +#define CPU_REG_CPUID_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */ +#define CPU_REG_CPUID_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */ +#define CPU_REG_CPUID_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DHCSR (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 +#define CPU_REG_SCB_ICSR_RETTOBASE 0x00000800 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 +#define CPU_REG_SCB_AIRCR_VECTRESET 0x00000001 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_BFHFNMIGN 0x00000100 +#define CPU_REG_SCB_CCR_DIV_0_TRP 0x00000010 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 +#define CPU_REG_SCB_CCR_USERSETMPEND 0x00000002 +#define CPU_REG_SCB_CCR_NONBASETHRDENA 0x00000001 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_USGFAULTENA 0x00040000 +#define CPU_REG_SCB_SHCSR_BUSFAULTENA 0x00020000 +#define CPU_REG_SCB_SHCSR_MEMFAULTENA 0x00010000 +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 +#define CPU_REG_SCB_SHCSR_BUSFAULTPENDED 0x00004000 +#define CPU_REG_SCB_SHCSR_MEMFAULTPENDED 0x00002000 +#define CPU_REG_SCB_SHCSR_USGFAULTPENDED 0x00001000 +#define CPU_REG_SCB_SHCSR_SYSTICKACT 0x00000800 +#define CPU_REG_SCB_SHCSR_PENDSVACT 0x00000400 +#define CPU_REG_SCB_SHCSR_MONITORACT 0x00000100 +#define CPU_REG_SCB_SHCSR_SVCALLACT 0x00000080 +#define CPU_REG_SCB_SHCSR_USGFAULTACT 0x00000008 +#define CPU_REG_SCB_SHCSR_BUSFAULTACT 0x00000002 +#define CPU_REG_SCB_SHCSR_MEMFAULTACT 0x00000001 + + /* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */ +#define CPU_REG_SCB_CFSR_DIVBYZERO 0x02000000 +#define CPU_REG_SCB_CFSR_UNALIGNED 0x01000000 +#define CPU_REG_SCB_CFSR_NOCP 0x00080000 +#define CPU_REG_SCB_CFSR_INVPC 0x00040000 +#define CPU_REG_SCB_CFSR_INVSTATE 0x00020000 +#define CPU_REG_SCB_CFSR_UNDEFINSTR 0x00010000 +#define CPU_REG_SCB_CFSR_BFARVALID 0x00008000 +#define CPU_REG_SCB_CFSR_STKERR 0x00001000 +#define CPU_REG_SCB_CFSR_UNSTKERR 0x00000800 +#define CPU_REG_SCB_CFSR_IMPRECISERR 0x00000400 +#define CPU_REG_SCB_CFSR_PRECISERR 0x00000200 +#define CPU_REG_SCB_CFSR_IBUSERR 0x00000100 +#define CPU_REG_SCB_CFSR_MMARVALID 0x00000080 +#define CPU_REG_SCB_CFSR_MSTKERR 0x00000010 +#define CPU_REG_SCB_CFSR_MUNSTKERR 0x00000008 +#define CPU_REG_SCB_CFSR_DACCVIOL 0x00000002 +#define CPU_REG_SCB_CFSR_IACCVIOL 0x00000001 + + /* ------------ HARD FAULT STATUS REG BITS ------------ */ +#define CPU_REG_SCB_HFSR_DEBUGEVT 0x80000000 +#define CPU_REG_SCB_HFSR_FORCED 0x40000000 +#define CPU_REG_SCB_HFSR_VECTTBL 0x00000002 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + /* -------- COPROCESSOR ACCESS CONTROL REG BITS ------- */ +#define CPU_REG_SCB_CPACR_CP10_FULL_ACCESS 0x00300000 +#define CPU_REG_SCB_CPACR_CP11_FULL_ACCESS 0x00C00000 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm b/ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm new file mode 100644 index 0000000..1e24ff8 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm @@ -0,0 +1,287 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-M +; ARM C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +; Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_WaitForInt + EXPORT CPU_WaitForExcept + + + EXPORT CPU_CntLeadZeros + EXPORT CPU_CntTrailZeros + EXPORT CPU_RevBits + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA |.text|, CODE, READONLY, ALIGN=2 + THUMB + REQUIRE8 + PRESERVE8 + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID I + BX LR + + +CPU_IntEn + CPSIE I + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking, +; the state of the BASEPRI interrupt exception processing is stored in the local variable +; 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions +; that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored +; by copying 'cpu_sr' into the BASEPRI register. +; +; Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) Increasing priority using a write to BASEPRI does not take effect immediately. +; (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI +; might incorrectly be preempted by an insufficient high priority exception. +; +; (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence: +; +; CPSID i +; MSR to BASEPRI +; DSB +; ISB +; CPSIE i +;******************************************************************************************************** + +CPU_SR_Save + CPSID I ; Cortex-M7 errata notice. See Note #2 + PUSH {R1} + MRS R1, BASEPRI + MSR BASEPRI, R0 + DSB + ISB + MOV R0, R1 + POP {R1} + CPSIE I + BX LR + + +CPU_SR_Restore + CPSID I ; Cortex-M7 errata notice. See Note #2 + MSR BASEPRI, R0 + DSB + ISB + CPSIE I + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForExcept + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + +;******************************************************************************************************** +; CPU_RevBits() +; REVERSE BITS +; +; Description : Reverses the bits in a data value. +; +; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +; +; Argument(s) : val Data value to reverse bits. +; +; Return(s) : Value with all bits in 'val' reversed (see Note #1). +; +; Note(s) : (1) The final, reversed data value for 'val' is such that : +; +; 'val's final bit 0 = 'val's original bit N +; 'val's final bit 1 = 'val's original bit (N - 1) +; 'val's final bit 2 = 'val's original bit (N - 2) +; +; ... ... +; +; 'val's final bit (N - 2) = 'val's original bit 2 +; 'val's final bit (N - 1) = 'val's original bit 1 +; 'val's final bit N = 'val's original bit 0 +;******************************************************************************************************** + +CPU_RevBits + RBIT R0, R0 ; Reverse bits + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-M/ARMv7-M/CCS/cpu.h b/ARM-Cortex-M/ARMv7-M/CCS/cpu.h new file mode 100644 index 0000000..b1fc31b --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/CCS/cpu.h @@ -0,0 +1,762 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-M +* TI C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + /* Save CPU current BASEPRI priority lvl for exception. */ +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0) +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ (" dsb") +#define CPU_RMB() __asm__ __volatile__ (" dsb") +#define CPU_WMB() __asm__ __volatile__ (" dsb") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio, + CPU_INT08U type); + + +CPU_SR CPU_SR_Save (CPU_SR new_basepri); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_MEM 4u +#define CPU_INT_BUSFAULT 5u +#define CPU_INT_USAGEFAULT 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_DBGMON 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* INTERRUPT TYPE +********************************************************************************************************* +*/ + +#define CPU_INT_KA 0u /* Kernel Aware interrupt request. */ +#define CPU_INT_NKA 1u /* Non-Kernel Aware interrupt request. */ + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IABR(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */ +#define CPU_REG_SCB_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ +#define CPU_REG_SCB_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */ +#define CPU_REG_SCB_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */ +#define CPU_REG_SCB_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */ +#define CPU_REG_SCB_CPACR (*((CPU_REG32 *)(0xE000ED88))) /* Coprocessor Access Control Reg. */ + + /* ----- SCB REG FOR FP EXTENSION ----- */ +#define CPU_REG_SCB_FPCCR (*((CPU_REG32 *)(0xE000EF34))) /* Floating-Point Context Control Reg. */ +#define CPU_REG_SCB_FPCAR (*((CPU_REG32 *)(0xE000EF38))) /* Floating-Point Context Address Reg. */ +#define CPU_REG_SCB_FPDSCR (*((CPU_REG32 *)(0xE000EF3C))) /* FP Default Status Control Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */ +#define CPU_REG_CPUID_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */ +#define CPU_REG_CPUID_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */ +#define CPU_REG_CPUID_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DHCSR (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 +#define CPU_REG_SCB_ICSR_RETTOBASE 0x00000800 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 +#define CPU_REG_SCB_AIRCR_VECTRESET 0x00000001 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_BFHFNMIGN 0x00000100 +#define CPU_REG_SCB_CCR_DIV_0_TRP 0x00000010 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 +#define CPU_REG_SCB_CCR_USERSETMPEND 0x00000002 +#define CPU_REG_SCB_CCR_NONBASETHRDENA 0x00000001 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_USGFAULTENA 0x00040000 +#define CPU_REG_SCB_SHCSR_BUSFAULTENA 0x00020000 +#define CPU_REG_SCB_SHCSR_MEMFAULTENA 0x00010000 +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 +#define CPU_REG_SCB_SHCSR_BUSFAULTPENDED 0x00004000 +#define CPU_REG_SCB_SHCSR_MEMFAULTPENDED 0x00002000 +#define CPU_REG_SCB_SHCSR_USGFAULTPENDED 0x00001000 +#define CPU_REG_SCB_SHCSR_SYSTICKACT 0x00000800 +#define CPU_REG_SCB_SHCSR_PENDSVACT 0x00000400 +#define CPU_REG_SCB_SHCSR_MONITORACT 0x00000100 +#define CPU_REG_SCB_SHCSR_SVCALLACT 0x00000080 +#define CPU_REG_SCB_SHCSR_USGFAULTACT 0x00000008 +#define CPU_REG_SCB_SHCSR_BUSFAULTACT 0x00000002 +#define CPU_REG_SCB_SHCSR_MEMFAULTACT 0x00000001 + + /* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */ +#define CPU_REG_SCB_CFSR_DIVBYZERO 0x02000000 +#define CPU_REG_SCB_CFSR_UNALIGNED 0x01000000 +#define CPU_REG_SCB_CFSR_NOCP 0x00080000 +#define CPU_REG_SCB_CFSR_INVPC 0x00040000 +#define CPU_REG_SCB_CFSR_INVSTATE 0x00020000 +#define CPU_REG_SCB_CFSR_UNDEFINSTR 0x00010000 +#define CPU_REG_SCB_CFSR_BFARVALID 0x00008000 +#define CPU_REG_SCB_CFSR_STKERR 0x00001000 +#define CPU_REG_SCB_CFSR_UNSTKERR 0x00000800 +#define CPU_REG_SCB_CFSR_IMPRECISERR 0x00000400 +#define CPU_REG_SCB_CFSR_PRECISERR 0x00000200 +#define CPU_REG_SCB_CFSR_IBUSERR 0x00000100 +#define CPU_REG_SCB_CFSR_MMARVALID 0x00000080 +#define CPU_REG_SCB_CFSR_MSTKERR 0x00000010 +#define CPU_REG_SCB_CFSR_MUNSTKERR 0x00000008 +#define CPU_REG_SCB_CFSR_DACCVIOL 0x00000002 +#define CPU_REG_SCB_CFSR_IACCVIOL 0x00000001 + + /* ------------ HARD FAULT STATUS REG BITS ------------ */ +#define CPU_REG_SCB_HFSR_DEBUGEVT 0x80000000 +#define CPU_REG_SCB_HFSR_FORCED 0x40000000 +#define CPU_REG_SCB_HFSR_VECTTBL 0x00000002 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + /* -------- COPROCESSOR ACCESS CONTROL REG BITS ------- */ +#define CPU_REG_SCB_CPACR_CP10_FULL_ACCESS 0x00300000 +#define CPU_REG_SCB_CPACR_CP11_FULL_ACCESS 0x00C00000 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv7-M/CCS/cpu_a.asm b/ARM-Cortex-M/ARMv7-M/CCS/cpu_a.asm new file mode 100644 index 0000000..63a36b3 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/CCS/cpu_a.asm @@ -0,0 +1,302 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-M +; TI C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +; Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_WaitForInt + .global CPU_WaitForExcept + + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + .global CPU_RevBits + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + .text + .align 2 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + + .asmfunc +CPU_IntDis: + CPSID I + BX LR + .endasmfunc + + .asmfunc +CPU_IntEn: + CPSIE I + BX LR + .endasmfunc + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking, +; the state of the BASEPRI interrupt exception processing is stored in the local variable +; 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions +; that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored +; by copying 'cpu_sr' into the BASEPRI register. +; +; Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) Increasing priority using a write to BASEPRI does not take effect immediately. +; (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI +; might incorrectly be preempted by an insufficient high priority exception. +; +; (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence: +; +; CPSID i +; MSR to BASEPRI +; DSB +; ISB +; CPSIE i +;******************************************************************************************************** + + .asmfunc +CPU_SR_Save: + CPSID I ; Cortex-M7 errata notice. See Note #2 + PUSH {R1} + MRS R1, BASEPRI + MSR BASEPRI, R0 + DSB + ISB + MOV R0, R1 + POP {R1} + CPSIE I + BX LR + .endasmfunc + + .asmfunc +CPU_SR_Restore: + CPSID I ; Cortex-M7 errata notice. See Note #2 + MSR BASEPRI, R0 + DSB + ISB + CPSIE I + BX LR + .endasmfunc + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + .asmfunc +CPU_WaitForInt: + WFI ; Wait for interrupt + BX LR + .endasmfunc + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + .asmfunc +CPU_WaitForExcept: + WFE ; Wait for exception + BX LR + .endasmfunc + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + + .asmfunc +CPU_CntLeadZeros: + CLZ R0, R0 ; Count leading zeros + BX LR + .endasmfunc + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + + .asmfunc +CPU_CntTrailZeros: + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + .endasmfunc + + +;******************************************************************************************************** +; CPU_RevBits() +; REVERSE BITS +; +; Description : Reverses the bits in a data value. +; +; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +; +; Argument(s) : val Data value to reverse bits. +; +; Return(s) : Value with all bits in 'val' reversed (see Note #1). +; +; Note(s) : (1) The final, reversed data value for 'val' is such that : +; +; 'val's final bit 0 = 'val's original bit N +; 'val's final bit 1 = 'val's original bit (N - 1) +; 'val's final bit 2 = 'val's original bit (N - 2) +; +; ... ... +; +; 'val's final bit (N - 2) = 'val's original bit 2 +; 'val's final bit (N - 1) = 'val's original bit 1 +; 'val's final bit N = 'val's original bit 0 +;******************************************************************************************************** + + .asmfunc +CPU_RevBits: + RBIT R0, R0 ; Reverse bits + BX LR + .endasmfunc + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .end + diff --git a/ARM-Cortex-M/ARMv7-M/GNU/cpu.h b/ARM-Cortex-M/ARMv7-M/GNU/cpu.h new file mode 100644 index 0000000..060c0db --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/GNU/cpu.h @@ -0,0 +1,762 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-M +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + /* Save CPU current BASEPRI priority lvl for exception. */ +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0) +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio, + CPU_INT08U type); + + +CPU_SR CPU_SR_Save (CPU_SR new_basepri); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_MEM 4u +#define CPU_INT_BUSFAULT 5u +#define CPU_INT_USAGEFAULT 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_DBGMON 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* INTERRUPT TYPE +********************************************************************************************************* +*/ + +#define CPU_INT_KA 0u /* Kernel Aware interrupt request. */ +#define CPU_INT_NKA 1u /* Non-Kernel Aware interrupt request. */ + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IABR(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */ +#define CPU_REG_SCB_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ +#define CPU_REG_SCB_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */ +#define CPU_REG_SCB_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */ +#define CPU_REG_SCB_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */ +#define CPU_REG_SCB_CPACR (*((CPU_REG32 *)(0xE000ED88))) /* Coprocessor Access Control Reg. */ + + /* ----- SCB REG FOR FP EXTENSION ----- */ +#define CPU_REG_SCB_FPCCR (*((CPU_REG32 *)(0xE000EF34))) /* Floating-Point Context Control Reg. */ +#define CPU_REG_SCB_FPCAR (*((CPU_REG32 *)(0xE000EF38))) /* Floating-Point Context Address Reg. */ +#define CPU_REG_SCB_FPDSCR (*((CPU_REG32 *)(0xE000EF3C))) /* FP Default Status Control Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */ +#define CPU_REG_CPUID_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */ +#define CPU_REG_CPUID_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */ +#define CPU_REG_CPUID_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DHCSR (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 +#define CPU_REG_SCB_ICSR_RETTOBASE 0x00000800 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 +#define CPU_REG_SCB_AIRCR_VECTRESET 0x00000001 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_BFHFNMIGN 0x00000100 +#define CPU_REG_SCB_CCR_DIV_0_TRP 0x00000010 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 +#define CPU_REG_SCB_CCR_USERSETMPEND 0x00000002 +#define CPU_REG_SCB_CCR_NONBASETHRDENA 0x00000001 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_USGFAULTENA 0x00040000 +#define CPU_REG_SCB_SHCSR_BUSFAULTENA 0x00020000 +#define CPU_REG_SCB_SHCSR_MEMFAULTENA 0x00010000 +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 +#define CPU_REG_SCB_SHCSR_BUSFAULTPENDED 0x00004000 +#define CPU_REG_SCB_SHCSR_MEMFAULTPENDED 0x00002000 +#define CPU_REG_SCB_SHCSR_USGFAULTPENDED 0x00001000 +#define CPU_REG_SCB_SHCSR_SYSTICKACT 0x00000800 +#define CPU_REG_SCB_SHCSR_PENDSVACT 0x00000400 +#define CPU_REG_SCB_SHCSR_MONITORACT 0x00000100 +#define CPU_REG_SCB_SHCSR_SVCALLACT 0x00000080 +#define CPU_REG_SCB_SHCSR_USGFAULTACT 0x00000008 +#define CPU_REG_SCB_SHCSR_BUSFAULTACT 0x00000002 +#define CPU_REG_SCB_SHCSR_MEMFAULTACT 0x00000001 + + /* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */ +#define CPU_REG_SCB_CFSR_DIVBYZERO 0x02000000 +#define CPU_REG_SCB_CFSR_UNALIGNED 0x01000000 +#define CPU_REG_SCB_CFSR_NOCP 0x00080000 +#define CPU_REG_SCB_CFSR_INVPC 0x00040000 +#define CPU_REG_SCB_CFSR_INVSTATE 0x00020000 +#define CPU_REG_SCB_CFSR_UNDEFINSTR 0x00010000 +#define CPU_REG_SCB_CFSR_BFARVALID 0x00008000 +#define CPU_REG_SCB_CFSR_STKERR 0x00001000 +#define CPU_REG_SCB_CFSR_UNSTKERR 0x00000800 +#define CPU_REG_SCB_CFSR_IMPRECISERR 0x00000400 +#define CPU_REG_SCB_CFSR_PRECISERR 0x00000200 +#define CPU_REG_SCB_CFSR_IBUSERR 0x00000100 +#define CPU_REG_SCB_CFSR_MMARVALID 0x00000080 +#define CPU_REG_SCB_CFSR_MSTKERR 0x00000010 +#define CPU_REG_SCB_CFSR_MUNSTKERR 0x00000008 +#define CPU_REG_SCB_CFSR_DACCVIOL 0x00000002 +#define CPU_REG_SCB_CFSR_IACCVIOL 0x00000001 + + /* ------------ HARD FAULT STATUS REG BITS ------------ */ +#define CPU_REG_SCB_HFSR_DEBUGEVT 0x80000000 +#define CPU_REG_SCB_HFSR_FORCED 0x40000000 +#define CPU_REG_SCB_HFSR_VECTTBL 0x00000002 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + /* -------- COPROCESSOR ACCESS CONTROL REG BITS ------- */ +#define CPU_REG_SCB_CPACR_CP10_FULL_ACCESS 0x00300000 +#define CPU_REG_SCB_CPACR_CP11_FULL_ACCESS 0x00C00000 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s b/ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s new file mode 100644 index 0000000..03b57af --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s @@ -0,0 +1,295 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU PORT FILE +@ +@ ARMv7-M +@ GNU C Compiler +@ +@ Filename : cpu_a.s +@ Version : v1.32.00 +@******************************************************************************************************** +@ Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +@******************************************************************************************************** + + +@******************************************************************************************************** +@ PUBLIC FUNCTIONS +@******************************************************************************************************** + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_WaitForInt + .global CPU_WaitForExcept + + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + .global CPU_RevBits + + +@******************************************************************************************************** +@ CODE GENERATION DIRECTIVES +@******************************************************************************************************** + +.text +.align 2 +.syntax unified + + +@******************************************************************************************************** +@ DISABLE and ENABLE INTERRUPTS +@ +@ Description : Disable/Enable interrupts. +@ +@ Prototypes : void CPU_IntDis(void); +@ void CPU_IntEn (void); +@******************************************************************************************************** + +.thumb_func +CPU_IntDis: + CPSID I + BX LR + +.thumb_func +CPU_IntEn: + CPSIE I + BX LR + + +@******************************************************************************************************** +@ CRITICAL SECTION FUNCTIONS +@ +@ Description : Disable/Enable Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking, +@ the state of the BASEPRI interrupt exception processing is stored in the local variable +@ 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions +@ that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored +@ by copying 'cpu_sr' into the BASEPRI register. +@ +@ Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri); +@ void CPU_SR_Restore(CPU_SR cpu_sr); +@ +@ Note(s) : (1) These functions are used in general like this : +@ +@ void Task (void *p_arg) +@ { +@ CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +@ : +@ : +@ CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +@ : +@ : +@ CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +@ : +@ } +@ +@ (2) Increasing priority using a write to BASEPRI does not take effect immediately. +@ (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI +@ might incorrectly be preempted by an insufficient high priority exception. +@ +@ (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence: +@ +@ CPSID i +@ MSR to BASEPRI +@ DSB +@ ISB +@ CPSIE i +@******************************************************************************************************** + +.thumb_func +CPU_SR_Save: + CPSID I @ Cortex-M7 errata notice. See Note #2 + PUSH {R1} + MRS R1, BASEPRI + MSR BASEPRI, R0 + DSB + ISB + MOV R0, R1 + POP {R1} + CPSIE I + BX LR + + +.thumb_func +CPU_SR_Restore: + CPSID I @ Cortex-M7 errata notice. See Note #2 + MSR BASEPRI, R0 + DSB + ISB + CPSIE I + BX LR + + +@******************************************************************************************************** +@ WAIT FOR INTERRUPT +@ +@ Description : Enters sleep state, which will be exited when an interrupt is received. +@ +@ Prototypes : void CPU_WaitForInt (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.thumb_func +CPU_WaitForInt: + WFI @ Wait for interrupt + BX LR + + +@******************************************************************************************************** +@ WAIT FOR EXCEPTION +@ +@ Description : Enters sleep state, which will be exited when an exception is received. +@ +@ Prototypes : void CPU_WaitForExcept (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.thumb_func +CPU_WaitForExcept: + WFE @ Wait for exception + BX LR + + +@******************************************************************************************************** +@ CPU_CntLeadZeros() +@ COUNT LEADING ZEROS +@ +@ Description : Counts the number of contiguous, most-significant, leading zero bits before the +@ first binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count leading zero bits. +@ +@ Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +@ +@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +@ CPU WORD CONFIGURATION Note #1'). +@ +@ (b) For 32-bit values : +@ +@ b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +@ --- --- --- --- --- --- --- --- --------------- +@ 1 x x x x x x x 0 +@ 0 1 x x x x x x 1 +@ 0 0 1 x x x x x 2 +@ : : : : : : : : : +@ : : : : : : : : : +@ 0 0 0 1 x x x x 27 +@ 0 0 0 0 1 x x x 28 +@ 0 0 0 0 0 1 x x 29 +@ 0 0 0 0 0 0 1 x 30 +@ 0 0 0 0 0 0 0 1 31 +@ 0 0 0 0 0 0 0 0 32 +@ +@ +@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + +.thumb_func +CPU_CntLeadZeros: + CLZ R0, R0 @ Count leading zeros + BX LR + + +@******************************************************************************************************** +@ CPU_CntTrailZeros() +@ COUNT TRAILING ZEROS +@ +@ Description : Counts the number of contiguous, least-significant, trailing zero bits before the +@ first binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count trailing zero bits. +@ +@ Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +@ +@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +@ CPU WORD CONFIGURATION Note #1'). +@ +@ (b) For 32-bit values : +@ +@ b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +@ --- --- --- --- --- --- --- --- ---------------- +@ x x x x x x x 1 0 +@ x x x x x x 1 0 1 +@ x x x x x 1 0 0 2 +@ : : : : : : : : : +@ : : : : : : : : : +@ x x x x 1 0 0 0 27 +@ x x x 1 0 0 0 0 28 +@ x x 1 0 0 0 0 0 29 +@ x 1 0 0 0 0 0 0 30 +@ 1 0 0 0 0 0 0 0 31 +@ 0 0 0 0 0 0 0 0 32 +@ +@ +@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + +.thumb_func +CPU_CntTrailZeros: + RBIT R0, R0 @ Reverse bits + CLZ R0, R0 @ Count trailing zeros + BX LR + + +@******************************************************************************************************** +@ CPU_RevBits() +@ REVERSE BITS +@ +@ Description : Reverses the bits in a data value. +@ +@ Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +@ +@ Argument(s) : val Data value to reverse bits. +@ +@ Return(s) : Value with all bits in 'val' reversed (see Note #1). +@ +@ Note(s) : (1) The final, reversed data value for 'val' is such that : +@ +@ 'val's final bit 0 = 'val's original bit N +@ 'val's final bit 1 = 'val's original bit (N - 1) +@ 'val's final bit 2 = 'val's original bit (N - 2) +@ +@ ... ... +@ +@ 'val's final bit (N - 2) = 'val's original bit 2 +@ 'val's final bit (N - 1) = 'val's original bit 1 +@ 'val's final bit N = 'val's original bit 0 +@******************************************************************************************************** + +.thumb_func +CPU_RevBits: + RBIT R0, R0 @ Reverse bits + BX LR + + +@******************************************************************************************************** +@ CPU ASSEMBLY PORT FILE END +@******************************************************************************************************** + +.end + diff --git a/ARM-Cortex-M/ARMv7-M/IAR/cpu.h b/ARM-Cortex-M/ARMv7-M/IAR/cpu.h new file mode 100644 index 0000000..4451276 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/IAR/cpu.h @@ -0,0 +1,764 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-M +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable should be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + /* Save CPU current BASEPRI priority lvl for exception. */ +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0) +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __DSB() +#define CPU_RMB() __DSB() +#define CPU_WMB() __DSB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_IntSrcDis (CPU_INT08U pos); +void CPU_IntSrcEn (CPU_INT08U pos); +void CPU_IntSrcPendClr(CPU_INT08U pos); +CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos); +void CPU_IntSrcPrioSet(CPU_INT08U pos, + CPU_INT08U prio, + CPU_INT08U type); + + +CPU_SR CPU_SR_Save (CPU_SR new_basepri); +void CPU_SR_Restore (CPU_SR cpu_sr); + + +void CPU_WaitForInt (void); +void CPU_WaitForExcept(void); + + +CPU_DATA CPU_RevBits (CPU_DATA val); + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr); +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr); + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_STK_PTR 0u +#define CPU_INT_RESET 1u +#define CPU_INT_NMI 2u +#define CPU_INT_HFAULT 3u +#define CPU_INT_MEM 4u +#define CPU_INT_BUSFAULT 5u +#define CPU_INT_USAGEFAULT 6u +#define CPU_INT_RSVD_07 7u +#define CPU_INT_RSVD_08 8u +#define CPU_INT_RSVD_09 9u +#define CPU_INT_RSVD_10 10u +#define CPU_INT_SVCALL 11u +#define CPU_INT_DBGMON 12u +#define CPU_INT_RSVD_13 13u +#define CPU_INT_PENDSV 14u +#define CPU_INT_SYSTICK 15u +#define CPU_INT_EXT0 16u + + +/* +********************************************************************************************************* +* INTERRUPT TYPE +********************************************************************************************************* +*/ + +#define CPU_INT_KA 0u /* Kernel Aware interrupt request. */ +#define CPU_INT_NKA 1u /* Non-Kernel Aware interrupt request. */ + + +/* +********************************************************************************************************* +* CPU REGISTERS +********************************************************************************************************* +*/ + /* -------- SYSTICK REGISTERS --------- */ +#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */ +#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */ +#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */ +#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */ + + /* ---------- NVIC REGISTERS ---------- */ +#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */ +#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */ +#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */ +#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */ +#define CPU_REG_NVIC_IABR(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */ +#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */ + + /* -- SYSTEM CONTROL BLOCK(SCB) REG -- */ +#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */ +#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */ +#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */ +#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */ +#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */ +#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */ +#define CPU_REG_SCB_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */ +#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */ +#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */ +#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */ +#define CPU_REG_SCB_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */ +#define CPU_REG_SCB_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */ +#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */ +#define CPU_REG_SCB_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */ +#define CPU_REG_SCB_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */ +#define CPU_REG_SCB_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */ +#define CPU_REG_SCB_CPACR (*((CPU_REG32 *)(0xE000ED88))) /* Coprocessor Access Control Reg. */ + + /* ----- SCB REG FOR FP EXTENSION ----- */ +#define CPU_REG_SCB_FPCCR (*((CPU_REG32 *)(0xE000EF34))) /* Floating-Point Context Control Reg. */ +#define CPU_REG_SCB_FPCAR (*((CPU_REG32 *)(0xE000EF38))) /* Floating-Point Context Address Reg. */ +#define CPU_REG_SCB_FPDSCR (*((CPU_REG32 *)(0xE000EF3C))) /* FP Default Status Control Reg. */ + + /* ---------- CPUID REGISTERS --------- */ +#define CPU_REG_CPUID_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */ +#define CPU_REG_CPUID_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */ +#define CPU_REG_CPUID_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */ +#define CPU_REG_CPUID_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */ +#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */ +#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */ +#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */ +#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */ +#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */ +#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */ +#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */ + + /* ----------- MPU REGISTERS ---------- */ +#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */ +#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */ +#define CPU_REG_MPU_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */ +#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */ +#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */ + + /* ----- REGISTERS NOT IN THE SCB ----- */ +#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */ +#define CPU_REG_DHCSR (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */ +#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */ +#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */ +#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */ +#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */ + + +/* +********************************************************************************************************* +* CPU REGISTER BITS +********************************************************************************************************* +*/ + + /* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */ +#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000 +#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004 +#define CPU_REG_SYST_CSR_TICKINT 0x00000002 +#define CPU_REG_SYST_CSR_ENABLE 0x00000001 + + /* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */ +#define CPU_REG_SYST_CALIB_NOREF 0x80000000 +#define CPU_REG_SYST_CALIB_SKEW 0x40000000 + + /* -------------- INT CTRL STATE REG BITS ------------- */ +#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000 +#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000 +#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000 +#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000 +#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000 +#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000 +#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000 +#define CPU_REG_SCB_ICSR_RETTOBASE 0x00000800 + + /* ------------- VECT TBL OFFSET REG BITS ------------- */ +#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000 + + /* ------------ APP INT/RESET CTRL REG BITS ----------- */ +#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000 +#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004 +#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002 +#define CPU_REG_SCB_AIRCR_VECTRESET 0x00000001 + + /* --------------- SYSTEM CTRL REG BITS --------------- */ +#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010 +#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004 +#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002 + + /* ----------------- CFG CTRL REG BITS ---------------- */ +#define CPU_REG_SCB_CCR_STKALIGN 0x00000200 +#define CPU_REG_SCB_CCR_BFHFNMIGN 0x00000100 +#define CPU_REG_SCB_CCR_DIV_0_TRP 0x00000010 +#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008 +#define CPU_REG_SCB_CCR_USERSETMPEND 0x00000002 +#define CPU_REG_SCB_CCR_NONBASETHRDENA 0x00000001 + + /* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */ +#define CPU_REG_SCB_SHCSR_USGFAULTENA 0x00040000 +#define CPU_REG_SCB_SHCSR_BUSFAULTENA 0x00020000 +#define CPU_REG_SCB_SHCSR_MEMFAULTENA 0x00010000 +#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000 +#define CPU_REG_SCB_SHCSR_BUSFAULTPENDED 0x00004000 +#define CPU_REG_SCB_SHCSR_MEMFAULTPENDED 0x00002000 +#define CPU_REG_SCB_SHCSR_USGFAULTPENDED 0x00001000 +#define CPU_REG_SCB_SHCSR_SYSTICKACT 0x00000800 +#define CPU_REG_SCB_SHCSR_PENDSVACT 0x00000400 +#define CPU_REG_SCB_SHCSR_MONITORACT 0x00000100 +#define CPU_REG_SCB_SHCSR_SVCALLACT 0x00000080 +#define CPU_REG_SCB_SHCSR_USGFAULTACT 0x00000008 +#define CPU_REG_SCB_SHCSR_BUSFAULTACT 0x00000002 +#define CPU_REG_SCB_SHCSR_MEMFAULTACT 0x00000001 + + /* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */ +#define CPU_REG_SCB_CFSR_DIVBYZERO 0x02000000 +#define CPU_REG_SCB_CFSR_UNALIGNED 0x01000000 +#define CPU_REG_SCB_CFSR_NOCP 0x00080000 +#define CPU_REG_SCB_CFSR_INVPC 0x00040000 +#define CPU_REG_SCB_CFSR_INVSTATE 0x00020000 +#define CPU_REG_SCB_CFSR_UNDEFINSTR 0x00010000 +#define CPU_REG_SCB_CFSR_BFARVALID 0x00008000 +#define CPU_REG_SCB_CFSR_STKERR 0x00001000 +#define CPU_REG_SCB_CFSR_UNSTKERR 0x00000800 +#define CPU_REG_SCB_CFSR_IMPRECISERR 0x00000400 +#define CPU_REG_SCB_CFSR_PRECISERR 0x00000200 +#define CPU_REG_SCB_CFSR_IBUSERR 0x00000100 +#define CPU_REG_SCB_CFSR_MMARVALID 0x00000080 +#define CPU_REG_SCB_CFSR_MSTKERR 0x00000010 +#define CPU_REG_SCB_CFSR_MUNSTKERR 0x00000008 +#define CPU_REG_SCB_CFSR_DACCVIOL 0x00000002 +#define CPU_REG_SCB_CFSR_IACCVIOL 0x00000001 + + /* ------------ HARD FAULT STATUS REG BITS ------------ */ +#define CPU_REG_SCB_HFSR_DEBUGEVT 0x80000000 +#define CPU_REG_SCB_HFSR_FORCED 0x40000000 +#define CPU_REG_SCB_HFSR_VECTTBL 0x00000002 + + /* ------------ DEBUG FAULT STATUS REG BITS ----------- */ +#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010 +#define CPU_REG_SCB_DFSR_VCATCH 0x00000008 +#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004 +#define CPU_REG_SCB_DFSR_BKPT 0x00000002 +#define CPU_REG_SCB_DFSR_HALTED 0x00000001 + + /* -------- COPROCESSOR ACCESS CONTROL REG BITS ------- */ +#define CPU_REG_SCB_CPACR_CP10_FULL_ACCESS 0x00300000 +#define CPU_REG_SCB_CPACR_CP11_FULL_ACCESS 0x00C00000 + + +/* +********************************************************************************************************* +* CPU REGISTER MASK +********************************************************************************************************* +*/ + +#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-M/ARMv7-M/IAR/cpu_a.asm b/ARM-Cortex-M/ARMv7-M/IAR/cpu_a.asm new file mode 100644 index 0000000..f54e7b9 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/IAR/cpu_a.asm @@ -0,0 +1,286 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-M +; IAR C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +; Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + PUBLIC CPU_WaitForInt + PUBLIC CPU_WaitForExcept + + + PUBLIC CPU_CntLeadZeros + PUBLIC CPU_CntTrailZeros + PUBLIC CPU_RevBits + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + THUMB + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID I + BX LR + + +CPU_IntEn + CPSIE I + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking, +; the state of the BASEPRI interrupt exception processing is stored in the local variable +; 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions +; that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored +; by copying 'cpu_sr' into the BASEPRI register. +; +; Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) Increasing priority using a write to BASEPRI does not take effect immediately. +; (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI +; might incorrectly be preempted by an insufficient high priority exception. +; +; (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence: +; +; CPSID i +; MSR to BASEPRI +; DSB +; ISB +; CPSIE i +;******************************************************************************************************** + +CPU_SR_Save + CPSID I ; Cortex-M7 errata notice. See Note #2 + PUSH {R1} + MRS R1, BASEPRI + MSR BASEPRI, R0 + DSB + ISB + MOV R0, R1 + POP {R1} + CPSIE I + BX LR + + +CPU_SR_Restore + CPSID I ; Cortex-M7 errata notice. See Note #2 + MSR BASEPRI, R0 + DSB + ISB + CPSIE I + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt: + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForExcept: + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros: + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros: + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + +;******************************************************************************************************** +; CPU_RevBits() +; REVERSE BITS +; +; Description : Reverses the bits in a data value. +; +; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +; +; Argument(s) : val Data value to reverse bits. +; +; Return(s) : Value with all bits in 'val' reversed (see Note #1). +; +; Note(s) : (1) The final, reversed data value for 'val' is such that : +; +; 'val's final bit 0 = 'val's original bit N +; 'val's final bit 1 = 'val's original bit (N - 1) +; 'val's final bit 2 = 'val's original bit (N - 2) +; +; ... ... +; +; 'val's final bit (N - 2) = 'val's original bit 2 +; 'val's final bit (N - 1) = 'val's original bit 1 +; 'val's final bit N = 'val's original bit 0 +;******************************************************************************************************** + +CPU_RevBits: + RBIT R0, R0 ; Reverse bits + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-M/ARMv7-M/cpu_c.c b/ARM-Cortex-M/ARMv7-M/cpu_c.c new file mode 100644 index 0000000..ccba747 --- /dev/null +++ b/ARM-Cortex-M/ARMv7-M/cpu_c.c @@ -0,0 +1,772 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-M +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + +#define CPU_INT_SRC_POS_MAX ((((CPU_REG_ICTR & 0xF) + 1) * 32) + 16) + +#define CPU_BIT_BAND_SRAM_REG_LO 0x20000000 +#define CPU_BIT_BAND_SRAM_REG_HI 0x200FFFFF +#define CPU_BIT_BAND_SRAM_BASE 0x22000000 + + +#define CPU_BIT_BAND_PERIPH_REG_LO 0x40000000 +#define CPU_BIT_BAND_PERIPH_REG_HI 0x400FFFFF +#define CPU_BIT_BAND_PERIPH_BASE 0x42000000 + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_BitBandClr() +* +* Description : Clear bit in bit-band region. +* +* Argument(s) : addr Byte address in memory space. +* +* bit_nbr Bit number in byte. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_BitBandClr (CPU_ADDR addr, + CPU_INT08U bit_nbr) +{ + CPU_ADDR bit_word_off; + CPU_ADDR bit_word_addr; + + + if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) && + (addr <= CPU_BIT_BAND_SRAM_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 0; + + } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) && + (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 0; + } +} + + +/* +********************************************************************************************************* +* CPU_BitBandSet() +* +* Description : Set bit in bit-band region. +* +* Argument(s) : addr Byte address in memory space. +* +* bit_nbr Bit number in byte. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_BitBandSet (CPU_ADDR addr, + CPU_INT08U bit_nbr) +{ + CPU_ADDR bit_word_off; + CPU_ADDR bit_word_addr; + + + if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) && + (addr <= CPU_BIT_BAND_SRAM_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 1; + + } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) && + (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) { + bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4); + bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off; + + *(volatile CPU_INT32U *)(bit_word_addr) = 1; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcDis() +* +* Description : Disable an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table : +* +* 0 Invalid (see Note #1a). +* 1 Invalid (see Note #1b). +* 2 Non-maskable Interrupt. +* 3 Hard Fault. +* 4 Memory Management. +* 5 Bus Fault. +* 6 Usage Fault. +* 7-10 Reserved. +* 11 SVCall. +* 12 Debug Monitor. +* 13 Reserved. +* 14 PendSV. +* 15 SysTick. +* 16+ External Interrupt. +* +* Return(s) : none. +* +* Note(s) : (1) Several table positions do not contain interrupt sources : +* +* (a) Position 0 contains the stack pointer. +* (b) Positions 7-10, 13 are reserved. +* +* (2) Several interrupts cannot be disabled/enabled : +* +* (a) Reset. +* (b) NMI. +* (c) Hard fault. +* (d) SVCall. +* (e) Debug monitor. +* (f) PendSV. +* +* (3) The maximum Cortex-M3, Cortex-M4, and Cortex-M7 table position is 256. A particular +* Cortex-M may have fewer than 240 external exceptions and, consequently, fewer than +* 256 table positions. This function assumes that the specified table position is valid +* if the interrupt controller type register's INTLINESNUM field is large enough so that +* the position COULD be valid. +********************************************************************************************************* +*/ + +void CPU_IntSrcDis (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT16U pos_max; + CPU_INT08U nbr; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + break; + + case CPU_INT_MEM: /* Memory management. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_MEMFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_BUSFAULT: /* Bus fault. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_BUSFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_USAGEFAULT: /* Usage fault. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_USGFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SYST_CSR &= ~CPU_REG_SYST_CSR_ENABLE; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ICER(group) = DEF_BIT(nbr); /* Disable interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcEn() +* +* Description : Enable an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) See 'CPU_IntSrcDis() Note #2'. +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +void CPU_IntSrcEn (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT16U pos_max; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + break; + + case CPU_INT_MEM: /* Memory management. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR |= CPU_REG_SCB_SHCSR_MEMFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_BUSFAULT: /* Bus fault. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR |= CPU_REG_SCB_SHCSR_BUSFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_USAGEFAULT: /* Usage fault. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SCB_SHCSR |= CPU_REG_SCB_SHCSR_USGFAULTENA; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_ENABLE; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ISER(group) = DEF_BIT(nbr); /* Enable interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPendClr() +* +* Description : Clear a pending interrupt. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) The pending status of several interrupts cannot be clear/set : +* +* (a) Reset. +* (b) NMI. +* (c) Hard fault. +* (d) Memory Managment. +* (e) Bus Fault. +* (f) Usage Fault. +* (g) SVCall. +* (h) Debug monitor. +* (i) PendSV. +* (j) Systick +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +void CPU_IntSrcPendClr (CPU_INT08U pos) + +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT16U pos_max; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + case CPU_INT_MEM: /* Memory management (see Note #2). */ + case CPU_INT_SVCALL: /* SVCall (see Note #2). */ + case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */ + case CPU_INT_PENDSV: /* PendSV (see Note #2). */ + case CPU_INT_BUSFAULT: /* Bus fault. */ + case CPU_INT_USAGEFAULT: /* Usage fault. */ + case CPU_INT_SYSTICK: /* SysTick. */ + break; + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 32; + nbr = (pos - 16) % 32; + + CPU_CRITICAL_ENTER(); + CPU_REG_NVIC_ICPR(group) = DEF_BIT(nbr); /* Clear Pending interrupt. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPrioSet() +* +* Description : Set priority of an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* prio Priority. Use a lower priority number for a higher priority. +* +* type Kernel/Non-Kernel aware priority type. +* CPU_INT_KA Kernel Aware interrupt request. See Note #4 +* CPU_INT_NKA Non-Kernel Aware interrupt request. See Note #5 +* +* Return(s) : none. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) Several interrupts priorities CANNOT be set : +* +* (a) Reset (always -3). +* (b) NMI (always -2). +* (c) Hard fault (always -1). +* +* (3) See 'CPU_IntSrcDis() Note #3'. +* +* (4) A Kernel Aware ISR can make OS service calls in its handler (Mutex, Flags, etc.). +* It follows the template below: +* +* static void KA_ISR_Handler (void) +* { +* CPU_SR_ALLOC(); +* +* CPU_CRITICAL_ENTER(); +* OSIntEnter(); Tell OS we are starting an ISR +* CPU_CRITICAL_EXIT(); +* +* --------------- HANDLER YOUR ISR HERE --------------- +* +* OSIntExit(); Tell OS we are leaving the ISR +* } +* +* (5) A Non-Kernel Aware ISR must never make OS service calls. It follows the template below: +* +* static void NKA_ISR_Handler (void) +* { +* --------------- HANDLER YOUR ISR HERE --------------- +* } +********************************************************************************************************* +*/ + +void CPU_IntSrcPrioSet (CPU_INT08U pos, + CPU_INT08U prio, + CPU_INT08U type) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT16U pos_max; + CPU_INT32U temp; + CPU_INT32U prio_offset; + CPU_SR_ALLOC(); + + + prio_offset = (prio << (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS)); + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + break; + + case CPU_INT_MEM: /* Memory management. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (0 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI1 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_BUSFAULT: /* Bus fault. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (1 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (1 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI1 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_USAGEFAULT: /* Usage fault. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI1 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SVCALL: /* SVCall. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI2; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI2 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_DBGMON: /* Debug monitor. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (0 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI3 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_PENDSV: /* PendSV. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI3 = temp; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS)); + CPU_REG_SCB_SHPRI3 = temp; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + + if (type == CPU_INT_NKA) { /* Check if NKA priority goes beyond KA boundary */ + if (prio >= CPU_CFG_KA_IPL_BOUNDARY) { /* Priority must be < CPU_CFG_KA_IPL_BOUNDARY */ + CPU_SW_Exception(); + } + + } else { /* Check if KA priority is less than KA boundary */ + if (prio < CPU_CFG_KA_IPL_BOUNDARY) { /* Priority must be >= CPU_CFG_KA_IPL_BOUNDARY */ + CPU_SW_Exception(); + } + } + + group = (pos - 16) / 4; + nbr = (pos - 16) % 4; + + CPU_CRITICAL_ENTER(); + temp = CPU_REG_NVIC_IPR(group); + temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS)); + temp |= ((CPU_INT32U)prio_offset << (nbr * DEF_OCTET_NBR_BITS)); + CPU_REG_NVIC_IPR(group) = temp; /* Set interrupt priority. */ + CPU_CRITICAL_EXIT(); + } + break; + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPrioGet() +* +* Description : Get priority of an interrupt source. +* +* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()'). +* +* Return(s) : Priority of interrupt source. If the interrupt source specified is invalid, then +* DEF_INT_16S_MIN_VAL is returned. +* +* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'. +* +* (2) See 'CPU_IntSrcPrioSet() Note #2'. +* +* (3) See 'CPU_IntSrcDis() Note #3'. +********************************************************************************************************* +*/ + +CPU_INT16S CPU_IntSrcPrioGet (CPU_INT08U pos) +{ + CPU_INT08U group; + CPU_INT08U nbr; + CPU_INT16U pos_max; + CPU_INT16S prio; + CPU_INT32U temp; + CPU_SR_ALLOC(); + + + switch (pos) { + case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */ + case CPU_INT_RSVD_07: + case CPU_INT_RSVD_08: + case CPU_INT_RSVD_09: + case CPU_INT_RSVD_10: + case CPU_INT_RSVD_13: + prio = DEF_INT_16S_MIN_VAL; + break; + + + /* ----------------- SYSTEM EXCEPTIONS ---------------- */ + case CPU_INT_RESET: /* Reset (see Note #2). */ + prio = -3; + break; + + case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */ + prio = -2; + break; + + case CPU_INT_HFAULT: /* Hard fault (see Note #2). */ + prio = -1; + break; + + + case CPU_INT_MEM: /* Memory management. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + + case CPU_INT_BUSFAULT: /* Bus fault. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + prio = (temp >> (1 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + + case CPU_INT_USAGEFAULT: /* Usage fault. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI1; + prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SVCALL: /* SVCall. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI2; + prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_DBGMON: /* Debug monitor. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_PENDSV: /* PendSV. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + case CPU_INT_SYSTICK: /* SysTick. */ + CPU_CRITICAL_ENTER(); + temp = CPU_REG_SCB_SHPRI3; + prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + CPU_CRITICAL_EXIT(); + break; + + + /* ---------------- EXTERNAL INTERRUPT ---------------- */ + default: + pos_max = CPU_INT_SRC_POS_MAX; + if (pos < pos_max) { /* See Note #3. */ + group = (pos - 16) / 4; + nbr = (pos - 16) % 4; + + CPU_CRITICAL_ENTER(); + temp = CPU_REG_NVIC_IPR(group); /* Read group interrupt priority. */ + CPU_CRITICAL_EXIT(); + + prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK; + } else { + prio = DEF_INT_16S_MIN_VAL; + } + break; + } + + if (prio != DEF_INT_16S_MIN_VAL) { + prio = (prio >> (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS)); + } + + return (prio); +} + +#ifdef __cplusplus +} +#endif diff --git a/ARM-Cortex-R/ARMv7-R/ARM/cpu.h b/ARM-Cortex-R/ARMv7-R/ARM/cpu.h new file mode 100644 index 0000000..626d16f --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/ARM/cpu.h @@ -0,0 +1,538 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-R +* ARM C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#if defined(__BIG_ENDIAN) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + +static __asm int disable_irq(void) +{ + MRS r0,APSR ; formerly CPSR + AND r0,r0,#0x80 + CPSID i + BX lr +} + + + +#define CPU_INT_DIS() do { cpu_sr = disable_irq(); __dsb(0xF);} while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { if(!cpu_sr) {__dsb(0xF); __enable_irq();} } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __dsb(0xF) +#define CPU_RMB() __dsb(0xF) +#define CPU_WMB() __dsb(0xF) + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-R/ARMv7-R/ARM/cpu_a.s b/ARM-Cortex-R/ARMv7-R/ARM/cpu_a.s new file mode 100644 index 0000000..0b8899a --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/ARM/cpu_a.s @@ -0,0 +1,257 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-R +; ARM C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_WaitForInt + EXPORT CPU_WaitForEvent + + EXPORT CPU_CntLeadZeros + EXPORT CPU_CntTrailZeros + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA |.text|, CODE, READONLY, ALIGN=4 + PRESERVE8 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis FUNCTION + + CPSID IF + DSB + BX LR + + ENDFUNC + + +CPU_IntEn FUNCTION + + DSB + CPSIE IF + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save FUNCTION + + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + ENDFUNC + +CPU_SR_Restore FUNCTION ; See Note #2 + + DSB + MSR CPSR_c, R0 + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt FUNCTION + + DSB + WFI ; Wait for interrupt + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent FUNCTION + + DSB + WFE ; Wait for exception + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the first +; binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros FUNCTION + + CLZ R0, R0 ; Count leading zeros + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the first +; binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros FUNCTION + + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM-Cortex-R/ARMv7-R/CCS/cpu.h b/ARM-Cortex-R/ARMv7-R/CCS/cpu.h new file mode 100644 index 0000000..a9366e3 --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/CCS/cpu.h @@ -0,0 +1,551 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-R +* TI C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) (a) '__big_endian__' is a CCS compiler #define that reflects the '--endian' option, +* indicating the data word-memory order is defined as big endian. +* +* (b) '__little_endian__' is a CCS compiler #define that reflects the '--endian' option, +* indicating the data word-memory order is defined as little endian. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (!(defined(__big_endian__ )) && \ + !(defined(__little_endian__))) +#error "CCS compiler '--endian' option NOT #define'd" + +#elif ((defined(__big_endian__ )) && \ + (defined(__little_endian__))) +#error "CCS compiler '--endian' option illegally #define'd" +#endif + +#ifdef __big_endian__ +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* See Note #3a. */ +#endif + +#ifdef __little_endian__ +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* See Note #3b. */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ (" dsb") +#define CPU_RMB() __asm__ __volatile__ (" dsb") +#define CPU_WMB() __asm__ __volatile__ (" dsb") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-R/ARMv7-R/CCS/cpu_a.asm b/ARM-Cortex-R/ARMv7-R/CCS/cpu_a.asm new file mode 100644 index 0000000..acc55ae --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/CCS/cpu_a.asm @@ -0,0 +1,229 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-R +; TI C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + .text + .arm + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_WaitForInt + .global CPU_WaitForEvent + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis: + CPSID IF + DSB + BX LR + + +CPU_IntEn: + DSB + CPSIE IF + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save: + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore: ; See Note #2 + DSB + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt: + DSB + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent: + DSB + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the first +; binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros: + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros: + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .end + diff --git a/ARM-Cortex-R/ARMv7-R/GNU/cpu.h b/ARM-Cortex-R/ARMv7-R/GNU/cpu.h new file mode 100644 index 0000000..56e59d8 --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/GNU/cpu.h @@ -0,0 +1,506 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-R +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + +#define CPU_INT_DIS() __asm__ __volatile__ ("mrs %[sr_res], cpsr\r\n" "cpsid if\r\n" "dsb\r\n" : [sr_res]"=r" (cpu_sr) :: "memory"); + +#define CPU_INT_EN() __asm__ __volatile__ ("dsb\r\n" "msr cpsr_c, %[sr_val]\r\n" :: [sr_val]"r" (cpu_sr) : "memory"); + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +* +* (2) CPU_PMU_xxx() functions are intended to manage the Event & Performanace Monitor unit (PMU). +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-R/ARMv7-R/GNU/cpu_a.S b/ARM-Cortex-R/ARMv7-R/GNU/cpu_a.S new file mode 100644 index 0000000..e784444 --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/GNU/cpu_a.S @@ -0,0 +1,223 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU PORT FILE +@ +@ ARMv7-R +@ GNU C Compiler +@ +@ Filename : cpu_a.S +@ Version : v1.32.00 +@******************************************************************************************************** + + +@******************************************************************************************************** +@ .global FUNCTIONS +@******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_WaitForInt + .global CPU_WaitForEvent + + .global CPU_CntLeadZeros + .global CPU_CntTrailZeros + + +@******************************************************************************************************** +@ CODE GENERATION DIRECTIVES +@******************************************************************************************************** + + .code 32 + + +@******************************************************************************************************** +@ ENABLE & DISABLE INTERRUPTS +@ +@ Description : Disable/Enable IRQs & FIQs. +@ +@ Prototypes : void CPU_IntEn (void)@ +@ void CPU_IntDis(void)@ +@******************************************************************************************************** + + .type CPU_IntDis, %function +CPU_IntDis: + CPSID IF + DSB + BX LR + + + .type CPU_IntEn, %function +CPU_IntEn: + DSB + CPSIE IF + BX LR + + +@******************************************************************************************************** +@ CRITICAL SECTION FUNCTIONS +@ +@ Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +@ state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +@ are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +@ The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +@ +@ Prototypes : CPU_SR CPU_SR_Save (void)@ +@ void CPU_SR_Restore(CPU_SR cpu_sr)@ +@ +@ Note(s) : (1) These functions are used in general like this : +@ +@ void Task (void *p_arg) +@ { +@ CPU_SR_ALLOC()@ /* Allocate storage for CPU status register */ +@ : +@ : +@ CPU_CRITICAL_ENTER()@ /* cpu_sr = CPU_SR_Save()@ */ +@ : +@ : +@ CPU_CRITICAL_EXIT()@ /* CPU_SR_Restore(cpu_sr)@ */ +@ : +@ } +@******************************************************************************************************** + + .type CPU_SR_Save, %function +CPU_SR_Save: + MRS R0, CPSR + CPSID IF @ Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR @ DISABLED, return the original CPSR contents in R0 + + .type CPU_SR_Restore, %function +CPU_SR_Restore: + DSB + MSR CPSR_c, R0 + BX LR + + +@******************************************************************************************************** +@ WAIT FOR INTERRUPT +@ +@ Description : Enters sleep state, which will be exited when an interrupt is received. +@ +@ Prototypes : void CPU_WaitForInt (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + + .type CPU_WaitForInt, %function +CPU_WaitForInt: + DSB + WFI @ Wait for interrupt + BX LR + + + +@******************************************************************************************************** +@ WAIT FOR EXCEPTION +@ +@ Description : Enters sleep state, which will be exited when an exception is received. +@ +@ Prototypes : void CPU_WaitForExcept (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + + .type CPU_WaitForEvent, %function +CPU_WaitForEvent: + DSB + WFE @ Wait for exception + BX LR + + +@******************************************************************************************************** +@ CPU_CntLeadZeros() +@ COUNT LEADING ZEROS +@ +@ Description : Counts the number of contiguous, most-significant, leading zero bits before the first +@ binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count leading zero bits. +@ +@ Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +@ +@ Note(s) : (1) If the argument is zero, the value 32 is returned. +@ +@ (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + + .type CPU_CntLeadZeros, %function +CPU_CntLeadZeros: + CLZ R0, R0 @ Count leading zeros + BX LR + + +@******************************************************************************************************** +@ CPU_CntTrailZeros() +@ COUNT TRAILING ZEROS +@ +@ Description : Counts the number of contiguous, least-significant, trailing zero bits before the +@ first binary one bit in a data value. +@ +@ Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +@ +@ Argument(s) : val Data value to count trailing zero bits. +@ +@ Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +@ +@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +@ CPU WORD CONFIGURATION Note #1'). +@ +@ (b) For 32-bit values : +@ +@ b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +@ --- --- --- --- --- --- --- --- ---------------- +@ x x x x x x x 1 0 +@ x x x x x x 1 0 1 +@ x x x x x 1 0 0 2 +@ : : : : : : : : : +@ : : : : : : : : : +@ x x x x 1 0 0 0 27 +@ x x x 1 0 0 0 0 28 +@ x x 1 0 0 0 0 0 29 +@ x 1 0 0 0 0 0 0 30 +@ 1 0 0 0 0 0 0 0 31 +@ 0 0 0 0 0 0 0 0 32 +@ +@ +@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +@ #define'd in 'cpu_cfg.h' or 'cpu.h'. +@******************************************************************************************************** + + .type CPU_CntTrailZeros, %function +CPU_CntTrailZeros: + RBIT R0, R0 @ Reverse bits + CLZ R0, R0 @ Count trailing zeros + BX LR + + +@******************************************************************************************************** +@ CPU ASSEMBLY PORT FILE END +@******************************************************************************************************** + + .end + diff --git a/ARM-Cortex-R/ARMv7-R/IAR/cpu.h b/ARM-Cortex-R/ARMv7-R/IAR/cpu.h new file mode 100644 index 0000000..6c9d2c5 --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/IAR/cpu.h @@ -0,0 +1,543 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARMv7-R +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) \\cpu_def.h +* +* (c) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory the +* specific CPU-compiler directory, & '\\' as additional include +* path directories. +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) '__LITTLE_ENDIAN__' is an IAR compiler #define that reflects the '--endian' option, +* indicating the data word-memory order : +* +* (a) '0' for big endian word-memory order +* (b) '1' for little endian word-memory order +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (defined(__LITTLE_ENDIAN__) && \ + (__LITTLE_ENDIAN__ == 1)) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* See Note #3b. */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* See Note #3a. */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __DSB() +#define CPU_RMB() __DSB() +#define CPU_WMB() __DSB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU_CntLeadZeros() prototyped/defined respectively in : +* +* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-version function +* +* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-version function otherwise +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'. +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_WaitForInt (void); +void CPU_WaitForEvent (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM-Cortex-R/ARMv7-R/IAR/cpu_a.asm b/ARM-Cortex-R/ARMv7-R/IAR/cpu_a.asm new file mode 100644 index 0000000..fcb0a11 --- /dev/null +++ b/ARM-Cortex-R/ARMv7-R/IAR/cpu_a.asm @@ -0,0 +1,235 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARMv7-R +; IAR C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_WaitForInt + PUBLIC CPU_WaitForEvent + + PUBLIC CPU_CntLeadZeros + PUBLIC CPU_CntTrailZeros + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + PRESERVE8 + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + CPSID IF + DSB + BX LR + + +CPU_IntEn + DSB + CPSIE IF + BX LR + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + CPSID IF ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + DSB + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore + DSB + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; WAIT FOR INTERRUPT +; +; Description : Enters sleep state, which will be exited when an interrupt is received. +; +; Prototypes : void CPU_WaitForInt (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForInt + DSB + WFI ; Wait for interrupt + BX LR + + +;******************************************************************************************************** +; WAIT FOR EXCEPTION +; +; Description : Enters sleep state, which will be exited when an exception is received. +; +; Prototypes : void CPU_WaitForExcept (void) +; +; Argument(s) : none. +;******************************************************************************************************** + +CPU_WaitForEvent + DSB + WFE ; Wait for exception + BX LR + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the first +; binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros + CLZ R0, R0 ; Count leading zeros + BX LR + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +; CPU WORD CONFIGURATION Note #1'). +; +; (b) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is +; #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros + RBIT R0, R0 ; Reverse bits + CLZ R0, R0 ; Count trailing zeros + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM/GNU/cpu.h b/ARM/GNU/cpu.h new file mode 100644 index 0000000..b02bc33 --- /dev/null +++ b/ARM/GNU/cpu.h @@ -0,0 +1,526 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_IntEn (void); +void CPU_IntDis (void); + +void CPU_IRQ_En (void); +void CPU_IRQ_Dis (void); + +void CPU_FIQ_En (void); +void CPU_FIQ_Dis (void); + + +/* +********************************************************************************************************* +* ARM EXCEPTIONS VECTORS +* +* Note(s) : (1) Exceptions are taken whenever the normal flow of a program MUST temporarily halt, +* for example, to service an interrupt from a peripheral. The ARM architecture has +* the following execption vectors : +* +* CPU_ARM_EXCEPT_RST Reset Exception +* CPU_ARM_EXCEPT_UND Undefined Instruction +* CPU_ARM_EXCEPT_SWI Software Interrupt +* CPU_ARM_EXCEPT_ABORT_PREFETCH Prefetch Abort +* CPU_ARM_EXCEPT_ABORT_DATA Data Abort +* CPU_ARM_EXCEPT_IRQ Interrupt Request +* CPU_ARM_EXCEPT_FIQ Fast Interrupt Request +********************************************************************************************************* +*/ + +#define CPU_ARM_EXCEPT_RST 0u +#define CPU_ARM_EXCEPT_UND 1u +#define CPU_ARM_EXCEPT_SWI 2u +#define CPU_ARM_EXCEPT_ABORT_PREFETCH 3u +#define CPU_ARM_EXCEPT_ABORT_DATA 4u +#define CPU_ARM_EXCEPT_RSVD 5u +#define CPU_ARM_EXCEPT_IRQ 6u +#define CPU_ARM_EXCEPT_FIQ 7u + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM/GNU/cpu_a.s b/ARM/GNU/cpu_a.s new file mode 100644 index 0000000..864053c --- /dev/null +++ b/ARM/GNU/cpu_a.s @@ -0,0 +1,181 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU PORT FILE +@ +@ ARM +@ GNU C Compiler +@ +@ Filename : cpu_a.s +@ Version : v1.32.00 +@******************************************************************************************************** + + +@******************************************************************************************************** +@ PUBLIC FUNCTIONS +@******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_IntDis + .global CPU_IntEn + + .global CPU_IRQ_Dis + .global CPU_IRQ_En + + .global CPU_FIQ_Dis + .global CPU_FIQ_En + + +@******************************************************************************************************** +@ EQUATES +@******************************************************************************************************** + + .equ CPU_ARM_CTRL_INT_DIS, 0xC0 @ Disable both FIQ & IRQ + .equ CPU_ARM_CTRL_FIQ_DIS, 0x40 @ Disable FIQ. + .equ CPU_ARM_CTRL_IRQ_DIS, 0x80 @ Disable IRQ. + + +@******************************************************************************************************** +@ CODE GENERATION DIRECTIVES +@******************************************************************************************************** + + .code 32 + + +@********************************************************************************************************* +@ CRITICAL SECTION FUNCTIONS +@ +@ Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +@ state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +@ are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +@ The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +@ +@ Prototypes : CPU_SR CPU_SR_Save (void); +@ void CPU_SR_Restore(CPU_SR cpu_sr); +@ +@ Note(s) : (1) These functions are used in general like this : +@ +@ void Task (void *p_arg) +@ { +@ CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +@ : +@ : +@ CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +@ : +@ : +@ CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +@ : +@ } +@ +@ (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note : +@ +@ "Disabling Interrupts at Processor Level" +@********************************************************************************************************* + +CPU_SR_Save: + MRS R0,CPSR + +CPU_SR_Save_Loop: + @ Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + ORR R1,R0,#CPU_ARM_CTRL_INT_DIS + MSR CPSR_c,R1 + MRS R1,CPSR @ Confirm that CPSR contains the proper interrupt disable flags + AND R1,R1,#CPU_ARM_CTRL_INT_DIS + CMP R1,#CPU_ARM_CTRL_INT_DIS + BNE CPU_SR_Save_Loop @ NOT properly DISABLED (try again) + BX LR @ DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore: @ See Note #2 + MSR CPSR_c,R0 + BX LR + + +@******************************************************************************************************** +@ ENABLE & DISABLE INTERRUPTS +@ +@ Description : Disable/Enable IRQs & FIQs. +@ +@ Prototypes : void CPU_IntEn (void); +@ void CPU_IntDis(void); +@******************************************************************************************************** + +CPU_IntDis: + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_INT_DIS @ Set IRQ and FIQ bits in CPSR to disable all interrupts. + MSR CPSR_c, R0 + BX LR + +CPU_IntEn: + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_INT_DIS @ Clear IRQ and FIQ bits in CPSR to enable all interrupts. + MSR CPSR_c, R0 + BX LR + + +@******************************************************************************************************** +@ ENABLE & DISABLE IRQs +@ +@ Description : Disable/Enable IRQs. +@ +@ Prototypes : void CPU_IRQ_En (void); +@ void CPU_IRQ_Dis(void); +@******************************************************************************************************** + +CPU_IRQ_Dis: + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_IRQ_DIS @ Set IRQ bit in CPSR to disable IRQs. + MSR CPSR_c, R0 + BX LR + + +CPU_IRQ_En: + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_IRQ_DIS @ Clear IRQ bit in CPSR to enable IRQs. + MSR CPSR_c, R0 + BX LR + + +@******************************************************************************************************** +@ ENABLE & DISABLE FIQs +@ +@ Description : Disable/Enable FIQs. +@ +@ Prototypes : void CPU_FIQ_En (void); +@ void CPU_FIQ_Dis(void); +@******************************************************************************************************** + +CPU_FIQ_Dis: + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_FIQ_DIS @ Set FIQ bit in CPSR to disable FIQs. + MSR CPSR_c, R0 + BX LR + +CPU_FIQ_En: + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_FIQ_DIS @ Clear FIQ bit in CPSR to enable FIQs. + MSR CPSR_c, R0 + BX LR + + +@********************************************************************************************************* +@ CPU ASSEMBLY PORT FILE END +@********************************************************************************************************* + + .ltorg + diff --git a/ARM/IAR/cpu.h b/ARM/IAR/cpu.h new file mode 100644 index 0000000..87a93c7 --- /dev/null +++ b/ARM/IAR/cpu.h @@ -0,0 +1,606 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (2) The CLZ (count leading zeroes) assembly instruction is only available in ARM mode for the +* following ARM cores (version 5 architectures & above) : +* +* __ARM5__ +* __ARM6__ +* __ARM6M__ See Note #3a1 +* __ARM6SM__ See Note #3a1 +* __ARM7M__ See Note #3a1 +* __ARM7EM__ See Note #3a1 +* __ARM7R__ See Note #3a1 +* +* (3) (a) '__CORE__' is an IAR compiler #define that reflects the '--cpu' option, indicating the +* architecture/processor in use : +* +* __ARM4M__ +* __ARM4TM__ +* __ARM5__ +* __ARM6__ +* __ARM6M__ +* __ARM6SM__ +* __ARM7M__ +* __ARM7EM__ +* __ARM7R__ +* +* (1) For ARM-M & ARM-R profiles (ARM Cortex M3 & ARM Cortex R4, respectively), the 'cpu.h' +* port file from the appropriate CPU port directory should be used instead : +* +* (A) \\ARM-Cortex-M3\\cpu.h +* (B) \\ARM-Cortex-R4\\cpu.h +* +* where +* directory path for common CPU-compiler software +* directory name for specific compiler +* +* (b) '__CPU_MODE__' is an IAR compiler #define that reflects the selected CPU mode : +* +* (1) '1' for Thumb +* (2) '2' for ARM +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* Configure CPU count leading zeros bits ... */ +#undef CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if ((defined(__CORE__ )) && \ + ((defined(__CPU_MODE__)) && (__CPU_MODE__ == 2 )) && \ + (((defined(__ARM5__ )) && (__CORE__ == __ARM5__)) || \ + ((defined(__ARM6__ )) && (__CORE__ == __ARM6__)))) +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* See Note #2. */ +#endif + + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_IntEn (void); +void CPU_IntDis (void); + +void CPU_IRQ_En (void); +void CPU_IRQ_Dis (void); + +void CPU_FIQ_En (void); +void CPU_FIQ_Dis (void); + + +/* +********************************************************************************************************* +* ARM EXCEPTIONS VECTORS +* +* Note(s) : (1) Exceptions are taken whenever the normal flow of a program MUST temporarily halt, +* for example, to service an interrupt from a peripheral. The ARM architecture has +* the following execption vectors : +* +* CPU_ARM_EXCEPT_RST Reset Exception +* CPU_ARM_EXCEPT_UND Undefined Instruction +* CPU_ARM_EXCEPT_SWI Software Interrupt +* CPU_ARM_EXCEPT_ABORT_PREFETCH Prefetch Abort +* CPU_ARM_EXCEPT_ABORT_DATA Data Abort +* CPU_ARM_EXCEPT_IRQ Interrupt Request +* CPU_ARM_EXCEPT_FIQ Fast Interrupt Request +********************************************************************************************************* +*/ + +#define CPU_ARM_EXCEPT_RST 0u +#define CPU_ARM_EXCEPT_UND 1u +#define CPU_ARM_EXCEPT_SWI 2u +#define CPU_ARM_EXCEPT_ABORT_PREFETCH 3u +#define CPU_ARM_EXCEPT_ABORT_DATA 4u +#define CPU_ARM_EXCEPT_RSVD 5u +#define CPU_ARM_EXCEPT_IRQ 6u +#define CPU_ARM_EXCEPT_FIQ 7u + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM/IAR/cpu_a.s b/ARM/IAR/cpu_a.s new file mode 100644 index 0000000..7ecbd55 --- /dev/null +++ b/ARM/IAR/cpu_a.s @@ -0,0 +1,182 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARM +; IAR C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_IRQ_Dis + PUBLIC CPU_IRQ_En + + PUBLIC CPU_FIQ_Dis + PUBLIC CPU_FIQ_En + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +CPU_ARM_CTRL_INT_DIS EQU 0xC0 ; Disable both FIQ & IRQ +CPU_ARM_CTRL_FIQ_DIS EQU 0x40 ; Disable FIQ. +CPU_ARM_CTRL_IRQ_DIS EQU 0x80 ; Disable IRQ. + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note : +; +; "Disabling Interrupts at Processor Level" +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + +CPU_SR_Save_Loop + ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + ORR R1, R0, #CPU_ARM_CTRL_INT_DIS + MSR CPSR_c, R1 + MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags + AND R1, R1, #CPU_ARM_CTRL_INT_DIS + CMP R1, #CPU_ARM_CTRL_INT_DIS + BNE CPU_SR_Save_Loop ; NOT properly DISABLED (try again) + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore ; See Note #2 + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE INTERRUPTS +; +; Description : Disable/Enable IRQs & FIQs. +; +; Prototypes : void CPU_IntEn (void); +; void CPU_IntDis(void); +;******************************************************************************************************** + +CPU_IntDis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts. + MSR CPSR_c, R0 + BX LR + +CPU_IntEn + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_INT_DIS ; Clear IRQ and FIQ bits in CPSR to enable all interrupts. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE IRQs +; +; Description : Disable/Enable IRQs. +; +; Prototypes : void CPU_IRQ_En (void); +; void CPU_IRQ_Dis(void); +;******************************************************************************************************** + +CPU_IRQ_Dis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_IRQ_DIS ; Set IRQ bit in CPSR to disable IRQs. + MSR CPSR_c, R0 + BX LR + + +CPU_IRQ_En + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_IRQ_DIS ; Clear IRQ bit in CPSR to enable IRQs. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE FIQs +; +; Description : Disable/Enable FIQs. +; +; Prototypes : void CPU_FIQ_En (void); +; void CPU_FIQ_Dis(void); +;******************************************************************************************************** + +CPU_FIQ_Dis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_FIQ_DIS ; Set FIQ bit in CPSR to disable FIQs. + MSR CPSR_c, R0 + BX LR + +CPU_FIQ_En + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_FIQ_DIS ; Clear FIQ bit in CPSR to enable FIQs. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM/IAR/cpu_c.c b/ARM/IAR/cpu_c.c new file mode 100644 index 0000000..094cf6f --- /dev/null +++ b/ARM/IAR/cpu_c.c @@ -0,0 +1,146 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* IAR C Compiler +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntLeadZeros (CPU_DATA val) +{ + CPU_DATA cnt = 0u; + + asm("CLZ %0, %1" : "=r"(cnt) : "r" (val)); + + return (cnt); +} +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ARM/RealView/cpu.h b/ARM/RealView/cpu.h new file mode 100644 index 0000000..2af1d0c --- /dev/null +++ b/ARM/RealView/cpu.h @@ -0,0 +1,607 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* RealView Development Suite +* RealView Microcontroller Development Kit (MDK) +* ARM Developer Suite (ADS) +* Keil uVision +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (2) The CLZ (count leading zeroes) assembly instruction is only available in ARM mode for the +* following ARM cores (version 5 architectures & above) : +* +* __ARM5__ +* __ARM6__ +* __ARM6M__ See Note #3a1 +* __ARM6SM__ See Note #3a1 +* __ARM7M__ See Note #3a1 +* __ARM7EM__ See Note #3a1 +* __ARM7R__ See Note #3a1 +* +* (3) (a) '__TARGET_ARCH_ARM__'/'__TARGET_ARCH_THUMB__' are Keil MDK compiler #define's specifying +* the number of the ARM/THUMB base architecture of the target CPU irrespective of whether +* the compiler is compiling for ARM or Thumb mode : +* +* ARM VERSION __TARGET_ARCH_ARM__ __TARGET_ARCH_THUMB__ +* v4 4 0 +* v4T 4 1 +* v5T , v5TE , v5TEJ 5 2 +* v6 , v6K , v6Z 6 3 +* v6T2, 6 4 +* v6-M, v6S-M, 0 3 +* v7-M, 0 4 +* +* (1) For ARM-M & ARM-R profiles (ARM Cortex M3 & ARM Cortex R4, respectively), the 'cpu.h' +* port file from the appropriate CPU port directory should be used instead : +* +* (A) \\ARM-Cortex-M3\\cpu.h +* (B) \\ARM-Cortex-R4\\cpu.h +* +* where +* directory path for common CPU-compiler software +* directory name for specific compiler +* +* (b) '__thumb__' is a Keil MDK compiler #define that reflects the selected CPU mode : +* +* (1) '__thumb__' #define'd for Thumb +* (2) '__thumb__' not #define'd for ARM +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* Configure CPU count leading zeros bits ... */ +#undef CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if ((!(defined(__thumb__))) && \ + ((defined(__TARGET_ARCH_ARM__)) && (__TARGET_ARCH_ARM__ >= 5))) +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* See Note #2. */ +#endif + + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_IntEn (void); +void CPU_IntDis (void); + +void CPU_IRQ_En (void); +void CPU_IRQ_Dis (void); + +void CPU_FIQ_En (void); +void CPU_FIQ_Dis (void); + + +/* +********************************************************************************************************* +* ARM EXCEPTIONS VECTORS +* +* Note(s) : (1) Exceptions are taken whenever the normal flow of a program MUST temporarily halt, +* for example, to service an interrupt from a peripheral. The ARM architecture has +* the following execption vectors : +* +* CPU_ARM_EXCEPT_RST Reset Exception +* CPU_ARM_EXCEPT_UND Undefined Instruction +* CPU_ARM_EXCEPT_SWI Software Interrupt +* CPU_ARM_EXCEPT_ABORT_PREFETCH Prefetch Abort +* CPU_ARM_EXCEPT_ABORT_DATA Data Abort +* CPU_ARM_EXCEPT_IRQ Interrupt Request +* CPU_ARM_EXCEPT_FIQ Fast Interrupt Request +********************************************************************************************************* +*/ + +#define CPU_ARM_EXCEPT_RST 0u +#define CPU_ARM_EXCEPT_UND 1u +#define CPU_ARM_EXCEPT_SWI 2u +#define CPU_ARM_EXCEPT_ABORT_PREFETCH 3u +#define CPU_ARM_EXCEPT_ABORT_DATA 4u +#define CPU_ARM_EXCEPT_RSVD 5u +#define CPU_ARM_EXCEPT_IRQ 6u +#define CPU_ARM_EXCEPT_FIQ 7u + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ARM/RealView/cpu_a.s b/ARM/RealView/cpu_a.s new file mode 100644 index 0000000..df1182b --- /dev/null +++ b/ARM/RealView/cpu_a.s @@ -0,0 +1,185 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARM +; RealView Development Suite +; RealView Microcontroller Development Kit (MDK) +; ARM Developer Suite (ADS) +; Keil uVision +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + EXPORT CPU_SR_Save + EXPORT CPU_SR_Restore + + EXPORT CPU_IntDis + EXPORT CPU_IntEn + + EXPORT CPU_IRQ_Dis + EXPORT CPU_IRQ_En + + EXPORT CPU_FIQ_Dis + EXPORT CPU_FIQ_En + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +CPU_ARM_CTRL_INT_DIS EQU 0xC0 ; Disable both FIQ & IRQ +CPU_ARM_CTRL_FIQ_DIS EQU 0x40 ; Disable FIQ. +CPU_ARM_CTRL_IRQ_DIS EQU 0x80 ; Disable IRQ. + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + AREA _CPU_A_CODE_, CODE, READONLY + ARM + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note : +; +; "Disabling Interrupts at Processor Level" +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + +CPU_SR_Save_Loop + ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + ORR R1, R0, #CPU_ARM_CTRL_INT_DIS + MSR CPSR_c, R1 + MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags + AND R1, R1, #CPU_ARM_CTRL_INT_DIS + CMP R1, #CPU_ARM_CTRL_INT_DIS + BNE CPU_SR_Save_Loop ; NOT properly DISABLED (try again) + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore ; See Note #2 + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE INTERRUPTS +; +; Description : Disable/Enable IRQs & FIQs. +; +; Prototypes : void CPU_IntEn (void); +; void CPU_IntDis(void); +;******************************************************************************************************** + +CPU_IntDis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts. + MSR CPSR_c, R0 + BX LR + +CPU_IntEn + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_INT_DIS ; Clear IRQ and FIQ bits in CPSR to enable all interrupts. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE IRQs +; +; Description : Disable/Enable IRQs. +; +; Prototypes : void CPU_IRQ_En (void); +; void CPU_IRQ_Dis(void); +;******************************************************************************************************** + +CPU_IRQ_Dis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_IRQ_DIS ; Set IRQ bit in CPSR to disable IRQs. + MSR CPSR_c, R0 + BX LR + + +CPU_IRQ_En + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_IRQ_DIS ; Clear IRQ bit in CPSR to enable IRQs. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; ENABLE & DISABLE FIQs +; +; Description : Disable/Enable FIQs. +; +; Prototypes : void CPU_FIQ_En (void); +; void CPU_FIQ_Dis(void); +;******************************************************************************************************** + +CPU_FIQ_Dis + MRS R0, CPSR + ORR R0, R0, #CPU_ARM_CTRL_FIQ_DIS ; Set FIQ bit in CPSR to disable FIQs. + MSR CPSR_c, R0 + BX LR + +CPU_FIQ_En + MRS R0, CPSR + BIC R0, R0, #CPU_ARM_CTRL_FIQ_DIS ; Clear FIQ bit in CPSR to enable FIQs. + MSR CPSR_c, R0 + BX LR + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/ARM/RealView/cpu_c.c b/ARM/RealView/cpu_c.c new file mode 100644 index 0000000..c9eb9ad --- /dev/null +++ b/ARM/RealView/cpu_c.c @@ -0,0 +1,152 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* RealView Development Suite +* RealView Microcontroller Development Kit (MDK) +* ARM Developer Suite (ADS) +* Keil uVision +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntLeadZeros (CPU_DATA val) +{ + CPU_DATA cnt = 0u; + + __asm + { + CLZ ro, r1 + } + + return (cnt); +} +#endif + +#ifdef __cplusplus +} +#endif diff --git a/AVR/ATmega128/IAR/cpu.h b/AVR/ATmega128/IAR/cpu.h new file mode 100644 index 0000000..2bb5b6b --- /dev/null +++ b/AVR/ATmega128/IAR/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATmega128 +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_08 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { _CLI(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { _SEI(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { _OPC(0x930A); \ + _OPC(0xB70F); \ + _CLI(); \ + _OPC(0x930F); \ + _OPC(0x9109); } while (0) + /* Pop CPU status word. */ +#define CPU_INT_EN() do { _OPC(0x930A); \ + _OPC(0x910F); \ + _OPC(0xBF0F); \ + _OPC(0x9109); } while (0) +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR/ATmega128/IAR/cpu_a.s90 b/AVR/ATmega128/IAR/cpu_a.s90 new file mode 100644 index 0000000..d42b2ea --- /dev/null +++ b/AVR/ATmega128/IAR/cpu_a.s90 @@ -0,0 +1,88 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATmega128 +* IAR C Compiler +* +* Filename : cpu_a.s90 +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + MODULE CPU_A + + RSEG CODE:CODE:NOROOT(1) + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +SREG EQU 0x3F /* Status Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3 +* +* Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current value of SREG +* Disable interrupts +* Return original value of SREG +* +* void CPU_SR_Restore (OS_CPU_SR cpu_sr) +* Set SREG to cpu_sr +* Return +********************************************************************************************************* +*/ + +CPU_SR_Save: + IN R16,SREG /* Get current state of interrupts disable flag */ + CLI /* Disable interrupts */ + RET /* Return original SREG value in R16 */ + + +CPU_SR_Restore: + OUT SREG,R16 /* Restore SREG */ + RET /* Return */ + + END diff --git a/AVR/ATmega256/IAR/cpu.h b/AVR/ATmega256/IAR/cpu.h new file mode 100644 index 0000000..0090b81 --- /dev/null +++ b/AVR/ATmega256/IAR/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATmega256 +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_08 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { _CLI(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { _SEI(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { _OPC(0x930A); \ + _OPC(0xB70F); \ + _CLI(); \ + _OPC(0x930F); \ + _OPC(0x9109); } while (0) + /* Pop CPU status word. */ +#define CPU_INT_EN() do { _OPC(0x930A); \ + _OPC(0x910F); \ + _OPC(0xBF0F); \ + _OPC(0x9109); } while (0) +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR/ATmega256/IAR/cpu_a.s90 b/AVR/ATmega256/IAR/cpu_a.s90 new file mode 100644 index 0000000..615f898 --- /dev/null +++ b/AVR/ATmega256/IAR/cpu_a.s90 @@ -0,0 +1,88 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATmega256 +* IAR C Compiler +* +* Filename : cpu_a.s90 +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + MODULE CPU_A + + RSEG FARCODE:CODE:NOROOT(1) + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +SREG EQU 0x3F /* Status Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3 +* +* Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current value of SREG +* Disable interrupts +* Return original value of SREG +* +* void CPU_SR_Restore (OS_CPU_SR cpu_sr) +* Set SREG to cpu_sr +* Return +********************************************************************************************************* +*/ + +CPU_SR_Save: + IN R16,SREG /* Get current state of interrupts disable flag */ + CLI /* Disable interrupts */ + RET /* Return original SREG value in R16 */ + + +CPU_SR_Restore: + OUT SREG,R16 /* Restore SREG */ + RET /* Return */ + + END diff --git a/AVR/ATxmega128/GNU/cpu.h b/AVR/ATxmega128/GNU/cpu.h new file mode 100644 index 0000000..a9a9e3c --- /dev/null +++ b/AVR/ATxmega128/GNU/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATxmega128 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_08 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { _CLI(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { _SEI(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { _OPC(0x930A); \ + _OPC(0xB70F); \ + _CLI(); \ + _OPC(0x930F); \ + _OPC(0x9109); } while (0) + /* Pop CPU status word. */ +#define CPU_INT_EN() do { _OPC(0x930A); \ + _OPC(0x910F); \ + _OPC(0xBF0F); \ + _OPC(0x9109); } while (0) +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR/ATxmega128/GNU/cpu_a.s b/AVR/ATxmega128/GNU/cpu_a.s new file mode 100644 index 0000000..28a11e5 --- /dev/null +++ b/AVR/ATxmega128/GNU/cpu_a.s @@ -0,0 +1,85 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel ATxmega128 +* GNU C Compiler +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + .text + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + .equ SREG, 0x3F /* Status Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3 +* +* Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current value of SREG +* Disable interrupts +* Return original value of SREG +* +* void CPU_SR_Restore (OS_CPU_SR cpu_sr) +* Set SREG to cpu_sr +* Return +********************************************************************************************************* +*/ + +CPU_SR_Save: + IN R16,SREG /* Get current state of interrupts disable flag */ + CLI /* Disable interrupts */ + RET /* Return original SREG value in R16 */ + + +CPU_SR_Restore: + OUT SREG,R16 /* Restore SREG */ + RET /* Return */ + diff --git a/AVR/ATxmega128/IAR/cpu.h b/AVR/ATxmega128/IAR/cpu.h new file mode 100644 index 0000000..3b6e7cb --- /dev/null +++ b/AVR/ATxmega128/IAR/cpu.h @@ -0,0 +1,493 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel Xmega128 +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_08 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { _CLI(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { _SEI(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { _OPC(0x930A); \ + _OPC(0xB70F); \ + _CLI(); \ + _OPC(0x930F); \ + _OPC(0x9109); } while (0) + /* Pop CPU status word. */ +#define CPU_INT_EN() do { _OPC(0x930A); \ + _OPC(0x910F); \ + _OPC(0xBF0F); \ + _OPC(0x9109); } while (0) +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR/ATxmega128/IAR/cpu_a.s90 b/AVR/ATxmega128/IAR/cpu_a.s90 new file mode 100644 index 0000000..851dab3 --- /dev/null +++ b/AVR/ATxmega128/IAR/cpu_a.s90 @@ -0,0 +1,113 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel Xmega128 +* IAR C Compiler +* +* Filename : cpu_a.s90 +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + MODULE CPU_A + + RSEG FARCODE:CODE:NOROOT(1) + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +SREG EQU 0x3F /* Status Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3 +* +* Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current value of SREG +* Disable interrupts +* Return original value of SREG +* +* void CPU_SR_Restore (OS_CPU_SR cpu_sr) +* Set SREG to cpu_sr +* Return +********************************************************************************************************* +*/ + +CPU_SR_Save: + IN R16,SREG /* Get current state of interrupts disable flag */ + CLI /* Disable interrupts */ + RET /* Return original SREG value in R16 */ + + +CPU_SR_Restore: + OUT SREG,R16 /* Restore SREG */ + RET /* Return */ + + +/* +********************************************************************************************************* +* DISABLE INTERRUPTS +* +* Description : This function is used to disable interrupts. +* +* void CPU_IntDis (void) +* Disable interrupts +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + CLI /* Disable interrupts */ + RET /* Return */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + + END diff --git a/AVR32/AP7000/GNU/cpu.h b/AVR32/AP7000/GNU/cpu.h new file mode 100644 index 0000000..34b5069 --- /dev/null +++ b/AVR32/AP7000/GNU/cpu.h @@ -0,0 +1,513 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 AP7000 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ExceptDis (void); +void CPU_ExceptEn (void); + + +CPU_INT32U CPU_SysReg_Get_Count (void); +CPU_INT32U CPU_SysReg_Get_Config0(void); +CPU_INT32U CPU_SysReg_Get_Compare(void); +void CPU_SysReg_Set_Compare(CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR32/AP7000/GNU/cpu_a.s b/AVR32/AP7000/GNU/cpu_a.s new file mode 100644 index 0000000..7434304 --- /dev/null +++ b/AVR32/AP7000/GNU/cpu_a.s @@ -0,0 +1,267 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 AP7000 +* GNU C Compiler +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + .file "CPU_A" + + .section .text, "ax" + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + .equ CPU_SR_OFFSET, 0 /* Status Register offset in System Register */ + .equ CPU_SR_GM_OFFSET, 16 /* Status Register, Global Interrupt Mask Offset */ + .equ CPU_SR_EM_OFFSET, 21 /* Status Register, Exception Mask Offset */ + .equ CPU_COUNT_OFFSET, 0x00000108 /* Count Register offset in System Register */ + .equ CPU_CONFIG0_OFFSET, 0x00000100 /* Config0 Register offset in System Register */ + .equ CPU_COMPARE_OFFSET, 0x0000010C /* Compare Register offset in System Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_IntDis + .global CPU_IntEn + .global CPU_ExceptDis + .global CPU_ExceptEn + .global CPU_SysReg_Get_Count + .global CPU_SysReg_Get_Config0 + .global CPU_SysReg_Set_Compare + .global CPU_SysReg_Get_Compare + .global CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : These functions are used to enter and exit critical sections using Critical Method #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current global interrupt mask bit value from SR +* Disable interrupts +* Return global interrupt mask bit +* +* void CPU_SR_Restore (CPU_SR cpu_sr) +* Set global interrupt mask bit on SR according to parameter sr +* Return +* +* Argument(s) : cpu_sr global interrupt mask status. +* +* Note(s) : (1) Besides global interrupt mask bit, all other status register bits are kept unchanged. +* +* (2) Six NOP are required for properly disable interrupts. +********************************************************************************************************* +*/ + +CPU_SR_Save: + CSRFCZ CPU_SR_GM_OFFSET /* Retrieve GM bit from SR */ + SRCS R12 /* if (GM == 1) set R12 */ + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + NOP + NOP + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SR_Restore: + PUSHM R11 /* Save R11 into stack */ + + MFSR R11, CPU_SR_OFFSET /* Retrieve current Status Register */ + LSR R12, 1 /* Copy interrupt status to Carry */ + BST R11, CPU_SR_GM_OFFSET /* Overwrite GM bit based on Carry */ + + MTSR CPU_SR_OFFSET, R11 /* Restore Status Register GM with previous interrupt */ + /* ... status value */ + + POPM R11 /* Restore R11 from stack */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +* status register. +* +* void CPU_IntDis (void) +* Set global interrupt mask bit on SR +* Return +* +* void CPU_IntEn (void) +* Clear global interrupt mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + NOP + NOP + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_IntEn: + CSRF CPU_SR_GM_OFFSET /* clear global interrupt mask (enable interrupts) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE EXCEPTIONS +* +* Description : These functions are used to disable and enable exceptions by setting or clearing the +* exception mask in the cpu status register. +* +* void CPU_ExceptDis (void) +* Set exception mask bit on SR +* Return +* +* void CPU_ExcepttEn (void) +* Clear exception mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_ExceptDis: + SSRF CPU_SR_EM_OFFSET /* set exception mask (disable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_ExceptEn: + CSRF CPU_SR_EM_OFFSET /* clear exceptions mask (enable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* GET/SET SYSTEM REGISTERS +* +* Description : These functions are used to get/set specific system registers. +* +* CPU_INT32U CPU_SysReg_Get_Count (void) +* CPU_INT32U CPU_SysReg_Get_Config0 (void) +* CPU_INT32U CPU_SysReg_Get_Compare (void) +* void CPU_SysReg_Set_Compare (CPU_INT32U value) +********************************************************************************************************* +*/ + +CPU_SysReg_Get_Count: + MFSR R12, CPU_COUNT_OFFSET /* Retrieve COUNT system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Config0: + MFSR R12, CPU_CONFIG0_OFFSET /* Retrieve CONFIG0 system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Compare: + MFSR R12, CPU_COMPARE_OFFSET /* Retrieve COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Set_Compare: + MTSR CPU_COMPARE_OFFSET, R12 /* Save COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + CLZ R12, R12 /* Count leading zeros */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/AVR32/AP7000/IAR/cpu.h b/AVR32/AP7000/IAR/cpu.h new file mode 100644 index 0000000..bcb4edf --- /dev/null +++ b/AVR32/AP7000/IAR/cpu.h @@ -0,0 +1,508 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 AP7000 +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack word size (in octets). */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size (in number of CPU_STKs). */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ExceptDis (void); +void CPU_ExceptEn (void); + + +CPU_INT32U CPU_SysReg_Get_Count (void); +CPU_INT32U CPU_SysReg_Get_Config0(void); +CPU_INT32U CPU_SysReg_Get_Compare(void); +void CPU_SysReg_Set_Compare(CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR32/AP7000/IAR/cpu_a.asm b/AVR32/AP7000/IAR/cpu_a.asm new file mode 100644 index 0000000..461148e --- /dev/null +++ b/AVR32/AP7000/IAR/cpu_a.asm @@ -0,0 +1,269 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 AP7000 +* IAR C Compiler +* +* Filename : cpu_a.asm +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + MODULE CPU_A + + RSEG CODE32:CODE + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +CPU_SR_OFFSET EQU 0 /* Status Register offset in System Register */ +CPU_SR_GM_OFFSET EQU 16 /* Status Register, Global Interrupt Mask Offset */ +CPU_SR_EM_OFFSET EQU 21 /* Status Register, Exception Mask Offset */ +CPU_COUNT_OFFSET EQU 0x00000108 /* Count Register offset in System Register */ +CPU_CONFIG0_OFFSET EQU 0x00000100 /* Config0 Register offset in System Register */ +CPU_COMPARE_OFFSET EQU 0x0000010C /* Compare Register offset in System Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + PUBLIC CPU_ExceptDis + PUBLIC CPU_ExceptEn + PUBLIC CPU_SysReg_Get_Count + PUBLIC CPU_SysReg_Get_Config0 + PUBLIC CPU_SysReg_Set_Compare + PUBLIC CPU_SysReg_Get_Compare + PUBLIC CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : These functions are used to enter and exit critical sections using Critical Method #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current global interrupt mask bit value from SR +* Disable interrupts +* Return global interrupt mask bit +* +* void CPU_SR_Restore (CPU_SR cpu_sr) +* Set global interrupt mask bit on SR according to parameter sr +* Return +* +* Argument(s) : cpu_sr global interrupt mask status. +* +* Note(s) : (1) Besides global interrupt mask bit, all other status register bits are kept unchanged. +* +* (2) Six NOP are required for properly disable interrupts. +********************************************************************************************************* +*/ + +CPU_SR_Save: + CSRFCZ CPU_SR_GM_OFFSET /* Retrieve GM bit from SR */ + SRCS R12 /* if (GM == 1) set R12 */ + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + NOP + NOP + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SR_Restore: + PUSHM R11 /* Save R11 into stack */ + + MFSR R11, CPU_SR_OFFSET /* Retrieve current Status Register */ + LSR R12, 1 /* Copy interrupt status to Carry */ + BST R11, CPU_SR_GM_OFFSET /* Overwrite GM bit based on Carry */ + + MTSR CPU_SR_OFFSET, R11 /* Restore Status Register GM with previous interrupt */ + /* ... status value */ + + POPM R11 /* Restore R11 from stack */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +* status register. +* +* void CPU_IntDis (void) +* Set global interrupt mask bit on SR +* Return +* +* void CPU_IntEn (void) +* Clear global interrupt mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + NOP + NOP + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_IntEn: + CSRF CPU_SR_GM_OFFSET /* clear global interrupt mask (enable interrupts) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE EXCEPTIONS +* +* Description : These functions are used to disable and enable exceptions by setting or clearing the +* exception mask in the cpu status register. +* +* void CPU_ExceptDis (void) +* Set exception mask bit on SR +* Return +* +* void CPU_ExcepttEn (void) +* Clear exception mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_ExceptDis: + SSRF CPU_SR_EM_OFFSET /* set exception mask (disable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_ExceptEn: + CSRF CPU_SR_EM_OFFSET /* clear exceptions mask (enable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* GET/SET SYSTEM REGISTERS +* +* Description : These functions are used to get/set specific system registers. +* +* CPU_INT32U CPU_SysReg_Get_Count (void) +* CPU_INT32U CPU_SysReg_Get_Config0 (void) +* CPU_INT32U CPU_SysReg_Get_Compare (void) +* void CPU_SysReg_Set_Compare (CPU_INT32U value) +********************************************************************************************************* +*/ + +CPU_SysReg_Get_Count: + MFSR R12, CPU_COUNT_OFFSET /* Retrieve COUNT system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Config0: + MFSR R12, CPU_CONFIG0_OFFSET /* Retrieve CONFIG0 system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Compare: + MFSR R12, CPU_COMPARE_OFFSET /* Retrieve COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Set_Compare: + MTSR CPU_COMPARE_OFFSET, R12 /* Save COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + CLZ R12, R12 /* Count leading zeros */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + + END + diff --git a/AVR32/UC3/AtmelStudio6/cpu.h b/AVR32/UC3/AtmelStudio6/cpu.h new file mode 100644 index 0000000..3815c43 --- /dev/null +++ b/AVR32/UC3/AtmelStudio6/cpu.h @@ -0,0 +1,515 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ExceptDis (void); +void CPU_ExceptEn (void); + +void CPU_Reset (void); + + +CPU_INT32U CPU_SysReg_Get_Count (void); +CPU_INT32U CPU_SysReg_Get_Config0(void); +CPU_INT32U CPU_SysReg_Get_Compare(void); +void CPU_SysReg_Set_Compare(CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR32/UC3/AtmelStudio6/cpu_a.S b/AVR32/UC3/AtmelStudio6/cpu_a.S new file mode 100644 index 0000000..db8f8a4 --- /dev/null +++ b/AVR32/UC3/AtmelStudio6/cpu_a.S @@ -0,0 +1,327 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* GNU C Compiler +* +* Filename : cpu_a.S +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + .file "CPU_A" + + .section .text, "ax" + + .extern _start + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + .equ CPU_SR_OFFSET, 0 /* Status Register offset in System Register */ + .equ CPU_SR_GM_OFFSET, 16 /* Status Register, Global Interrupt Mask Offset */ + .equ CPU_SR_GM_MASK, 0x00010000 /* Status Register, Global Interrupt Mask */ + .equ CPU_SR_EM_OFFSET, 21 /* Status Register, Exception Mask Offset */ + .equ CPU_SR_M0_MASK, 0x00400000 /* Status Register, Supervisor Execution Mode Mask */ + .equ CPU_SR_MX_OFFSET, 22 /* Status Register, Execution Mode Mask offset */ + .equ CPU_SR_MX_SUPERVISOR_MODE, 0x00000001 /* Status Register, Execution Mode Supervisor */ + .equ CPU_COUNT_OFFSET, 0x00000108 /* Count Register offset in System Register */ + .equ CPU_CONFIG0_OFFSET, 0x00000100 /* Config0 Register offset in System Register */ + .equ CPU_COMPARE_OFFSET, 0x0000010C /* Compare Register offset in System Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_IntDis + .global CPU_IntEn + .global CPU_ExceptDis + .global CPU_ExceptEn + .global CPU_Reset + .global CPU_SysReg_Get_Count + .global CPU_SysReg_Get_Config0 + .global CPU_SysReg_Set_Compare + .global CPU_SysReg_Get_Compare + .global CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : These functions are used to enter and exit critical sections using Critical Method #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current global interrupt mask bit value from SR +* Disable interrupts +* Return global interrupt mask bit +* +* void CPU_SR_Restore (CPU_SR cpu_sr) +* Set global interrupt mask bit on SR according to parameter sr +* Return +* +* Argument(s) : cpu_sr global interrupt mask status. +* +* Note(s) : (1) Besides global interrupt mask bit, all other status register bits are kept unchanged. +* +* (2) Two NOP are required for properly disable interrupts. +********************************************************************************************************* +*/ + +CPU_SR_Save: + CSRFCZ CPU_SR_GM_OFFSET /* Retrieve GM bit from SR */ + SRCS R12 /* if (GM == 1) set R12 */ + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SR_Restore: + PUSHM R11 /* Save R11 into stack */ + + MFSR R11, CPU_SR_OFFSET /* Retrieve current Status Register */ + LSR R12, 1 /* Copy interrupt status to Carry */ + BST R11, CPU_SR_GM_OFFSET /* Overwrite GM bit based on Carry */ + + MTSR CPU_SR_OFFSET, R11 /* Restore Status Register GM with previous interrupt */ + /* ... status value */ + + POPM R11 /* Restore R11 from stack */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +* status register. +* +* void CPU_IntDis (void) +* Set global interrupt mask bit on SR +* Return +* +* void CPU_IntEn (void) +* Clear global interrupt mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_IntEn: + CSRF CPU_SR_GM_OFFSET /* clear global interrupt mask (enable interrupts) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE EXCEPTIONS +* +* Description : These functions are used to disable and enable exceptions by setting or clearing the +* exception mask in the cpu status register. +* +* void CPU_ExceptDis (void) +* Set exception mask bit on SR +* Return +* +* void CPU_ExcepttEn (void) +* Clear exception mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_ExceptDis: + SSRF CPU_SR_EM_OFFSET /* set exception mask (disable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_ExceptEn: + CSRF CPU_SR_EM_OFFSET /* clear exceptions mask (enable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* RESET CPU +* +* Description : This function is used to reset the CPU by returning to the reset vector. +* +* void CPU_Reset (void) +* if (current SR == 001b) { +* Push PC (START) +* Push clean SR (GM | M0) +* RETS +* } else { +* Push clean R8 (0x08080808) +* Push clean R9 (0x09090909) +* Push clean R10 (0x10101010) +* Push clean R11 (0x11111111) +* Push clean R12 (0x00000000) +* Push clean LR (0x14141414) +* Push PC (START) +* Push clean SR (GM | M0) +* RETE +* } +********************************************************************************************************* +*/ + +CPU_Reset: + MFSR R8, CPU_SR_OFFSET + BFEXTU R8, R8, CPU_SR_MX_OFFSET, 3 + CP.W R8, CPU_SR_MX_SUPERVISOR_MODE + BRNE CPU_Reset_RETE + + MOV R8, LO(_start) + ORH R8, HI(_start) + MOV R9, LO(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HI(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETS + + +CPU_Reset_RETE: + MOV R8, 0x0808 + ORH R8, 0x0808 + MOV R9, 0x0909 + ORH R9, 0x0909 + MOV R10, 0x1010 + ORH R10, 0x1010 + MOV R11, 0x1111 + ORH R11, 0x1111 + MOV R12, 0x0000 + ORH R12, 0x0000 + MOV LR, 0x1414 + ORH LR, 0x1414 + STM --SP, R8-R12, LR /* Push R8-R12, LR */ + MOV R8, LO(_start) + ORH R8, HI(_start) + MOV R9, LO(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HI(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETE + + +/* +********************************************************************************************************* +* GET/SET SYSTEM REGISTERS +* +* Description : These functions are used to get/set specific system registers. +* +* CPU_INT32U CPU_SysReg_Get_Count (void) +* CPU_INT32U CPU_SysReg_Get_Config0 (void) +* CPU_INT32U CPU_SysReg_Get_Compare (void) +* void CPU_SysReg_Set_Compare (CPU_INT32U value) +********************************************************************************************************* +*/ + +CPU_SysReg_Get_Count: + MFSR R12, CPU_COUNT_OFFSET /* Retrieve COUNT system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Config0: + MFSR R12, CPU_CONFIG0_OFFSET /* Retrieve CONFIG0 system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Compare: + MFSR R12, CPU_COMPARE_OFFSET /* Retrieve COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Set_Compare: + MTSR CPU_COMPARE_OFFSET, R12 /* Save COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + CLZ R12, R12 /* Count leading zeros */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/AVR32/UC3/GNU/cpu.h b/AVR32/UC3/GNU/cpu.h new file mode 100644 index 0000000..3815c43 --- /dev/null +++ b/AVR32/UC3/GNU/cpu.h @@ -0,0 +1,515 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ExceptDis (void); +void CPU_ExceptEn (void); + +void CPU_Reset (void); + + +CPU_INT32U CPU_SysReg_Get_Count (void); +CPU_INT32U CPU_SysReg_Get_Config0(void); +CPU_INT32U CPU_SysReg_Get_Compare(void); +void CPU_SysReg_Set_Compare(CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR32/UC3/GNU/cpu_a.s b/AVR32/UC3/GNU/cpu_a.s new file mode 100644 index 0000000..40891cf --- /dev/null +++ b/AVR32/UC3/GNU/cpu_a.s @@ -0,0 +1,327 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* GNU C Compiler +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + .file "CPU_A" + + .section .text, "ax" + + .extern _start + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + .equ CPU_SR_OFFSET, 0 /* Status Register offset in System Register */ + .equ CPU_SR_GM_OFFSET, 16 /* Status Register, Global Interrupt Mask Offset */ + .equ CPU_SR_GM_MASK, 0x00010000 /* Status Register, Global Interrupt Mask */ + .equ CPU_SR_EM_OFFSET, 21 /* Status Register, Exception Mask Offset */ + .equ CPU_SR_M0_MASK, 0x00400000 /* Status Register, Supervisor Execution Mode Mask */ + .equ CPU_SR_MX_OFFSET, 22 /* Status Register, Execution Mode Mask offset */ + .equ CPU_SR_MX_SUPERVISOR_MODE, 0x00000001 /* Status Register, Execution Mode Supervisor */ + .equ CPU_COUNT_OFFSET, 0x00000108 /* Count Register offset in System Register */ + .equ CPU_CONFIG0_OFFSET, 0x00000100 /* Config0 Register offset in System Register */ + .equ CPU_COMPARE_OFFSET, 0x0000010C /* Compare Register offset in System Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_IntDis + .global CPU_IntEn + .global CPU_ExceptDis + .global CPU_ExceptEn + .global CPU_Reset + .global CPU_SysReg_Get_Count + .global CPU_SysReg_Get_Config0 + .global CPU_SysReg_Set_Compare + .global CPU_SysReg_Get_Compare + .global CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : These functions are used to enter and exit critical sections using Critical Method #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current global interrupt mask bit value from SR +* Disable interrupts +* Return global interrupt mask bit +* +* void CPU_SR_Restore (CPU_SR cpu_sr) +* Set global interrupt mask bit on SR according to parameter sr +* Return +* +* Argument(s) : cpu_sr global interrupt mask status. +* +* Note(s) : (1) Besides global interrupt mask bit, all other status register bits are kept unchanged. +* +* (2) Two NOP are required for properly disable interrupts. +********************************************************************************************************* +*/ + +CPU_SR_Save: + CSRFCZ CPU_SR_GM_OFFSET /* Retrieve GM bit from SR */ + SRCS R12 /* if (GM == 1) set R12 */ + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SR_Restore: + PUSHM R11 /* Save R11 into stack */ + + MFSR R11, CPU_SR_OFFSET /* Retrieve current Status Register */ + LSR R12, 1 /* Copy interrupt status to Carry */ + BST R11, CPU_SR_GM_OFFSET /* Overwrite GM bit based on Carry */ + + MTSR CPU_SR_OFFSET, R11 /* Restore Status Register GM with previous interrupt */ + /* ... status value */ + + POPM R11 /* Restore R11 from stack */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +* status register. +* +* void CPU_IntDis (void) +* Set global interrupt mask bit on SR +* Return +* +* void CPU_IntEn (void) +* Clear global interrupt mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_IntEn: + CSRF CPU_SR_GM_OFFSET /* clear global interrupt mask (enable interrupts) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE EXCEPTIONS +* +* Description : These functions are used to disable and enable exceptions by setting or clearing the +* exception mask in the cpu status register. +* +* void CPU_ExceptDis (void) +* Set exception mask bit on SR +* Return +* +* void CPU_ExcepttEn (void) +* Clear exception mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_ExceptDis: + SSRF CPU_SR_EM_OFFSET /* set exception mask (disable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_ExceptEn: + CSRF CPU_SR_EM_OFFSET /* clear exceptions mask (enable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* RESET CPU +* +* Description : This function is used to reset the CPU by returning to the reset vector. +* +* void CPU_Reset (void) +* if (current SR == 001b) { +* Push PC (START) +* Push clean SR (GM | M0) +* RETS +* } else { +* Push clean R8 (0x08080808) +* Push clean R9 (0x09090909) +* Push clean R10 (0x10101010) +* Push clean R11 (0x11111111) +* Push clean R12 (0x00000000) +* Push clean LR (0x14141414) +* Push PC (START) +* Push clean SR (GM | M0) +* RETE +* } +********************************************************************************************************* +*/ + +CPU_Reset: + MFSR R8, CPU_SR_OFFSET + BFEXTU R8, R8, CPU_SR_MX_OFFSET, 3 + CP.W R8, CPU_SR_MX_SUPERVISOR_MODE + BRNE CPU_Reset_RETE + + MOV R8, LO(_start) + ORH R8, HI(_start) + MOV R9, LO(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HI(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETS + + +CPU_Reset_RETE: + MOV R8, 0x0808 + ORH R8, 0x0808 + MOV R9, 0x0909 + ORH R9, 0x0909 + MOV R10, 0x1010 + ORH R10, 0x1010 + MOV R11, 0x1111 + ORH R11, 0x1111 + MOV R12, 0x0000 + ORH R12, 0x0000 + MOV LR, 0x1414 + ORH LR, 0x1414 + STM --SP, R8-R12, LR /* Push R8-R12, LR */ + MOV R8, LO(_start) + ORH R8, HI(_start) + MOV R9, LO(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HI(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETE + + +/* +********************************************************************************************************* +* GET/SET SYSTEM REGISTERS +* +* Description : These functions are used to get/set specific system registers. +* +* CPU_INT32U CPU_SysReg_Get_Count (void) +* CPU_INT32U CPU_SysReg_Get_Config0 (void) +* CPU_INT32U CPU_SysReg_Get_Compare (void) +* void CPU_SysReg_Set_Compare (CPU_INT32U value) +********************************************************************************************************* +*/ + +CPU_SysReg_Get_Count: + MFSR R12, CPU_COUNT_OFFSET /* Retrieve COUNT system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Config0: + MFSR R12, CPU_CONFIG0_OFFSET /* Retrieve CONFIG0 system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Compare: + MFSR R12, CPU_COMPARE_OFFSET /* Retrieve COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Set_Compare: + MTSR CPU_COMPARE_OFFSET, R12 /* Save COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + CLZ R12, R12 /* Count leading zeros */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/AVR32/UC3/IAR/cpu.h b/AVR32/UC3/IAR/cpu.h new file mode 100644 index 0000000..f8a7af0 --- /dev/null +++ b/AVR32/UC3/IAR/cpu.h @@ -0,0 +1,515 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ExceptDis (void); +void CPU_ExceptEn (void); + +void CPU_Reset (void); + + +CPU_INT32U CPU_SysReg_Get_Count (void); +CPU_INT32U CPU_SysReg_Get_Config0(void); +CPU_INT32U CPU_SysReg_Get_Compare(void); +void CPU_SysReg_Set_Compare(CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/AVR32/UC3/IAR/cpu_a.asm b/AVR32/UC3/IAR/cpu_a.asm new file mode 100644 index 0000000..6cb21fb --- /dev/null +++ b/AVR32/UC3/IAR/cpu_a.asm @@ -0,0 +1,329 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Atmel AVR32 UC3 +* IAR C Compiler +* +* Filename : cpu_a.asm +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* ASM HEADER +********************************************************************************************************* +*/ + + MODULE CPU_A + + RSEG CODE32:CODE + + EXTERN __program_start + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +CPU_SR_OFFSET EQU 0 /* Status Register offset in System Register */ +CPU_SR_GM_OFFSET EQU 16 /* Status Register, Global Interrupt Mask Offset */ +CPU_SR_GM_MASK EQU 0x00010000 /* Status Register, Global Interrupt Mask */ +CPU_SR_EM_OFFSET EQU 21 /* Status Register, Exception Mask Offset */ +CPU_SR_M0_MASK EQU 0x00400000 /* Status Register, Supervisor Execution Mode Mask */ +CPU_SR_MX_OFFSET EQU 22 /* Status Register, Execution Mode Mask offset */ +CPU_SR_MX_SUPERVISOR_MODE EQU 0x00000001 /* Status Register, Execution Mode Supervisor */ +CPU_COUNT_OFFSET EQU 0x00000108 /* Count Register offset in System Register */ +CPU_CONFIG0_OFFSET EQU 0x00000100 /* Config0 Register offset in System Register */ +CPU_COMPARE_OFFSET EQU 0x0000010C /* Compare Register offset in System Register */ + + +/* +********************************************************************************************************* +* PUBLIC DECLARATIONS +********************************************************************************************************* +*/ + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + PUBLIC CPU_ExceptDis + PUBLIC CPU_ExceptEn + PUBLIC CPU_Reset + PUBLIC CPU_SysReg_Get_Count + PUBLIC CPU_SysReg_Get_Config0 + PUBLIC CPU_SysReg_Set_Compare + PUBLIC CPU_SysReg_Get_Compare + PUBLIC CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : These functions are used to enter and exit critical sections using Critical Method #3. +* +* CPU_SR CPU_SR_Save (void) +* Get current global interrupt mask bit value from SR +* Disable interrupts +* Return global interrupt mask bit +* +* void CPU_SR_Restore (CPU_SR cpu_sr) +* Set global interrupt mask bit on SR according to parameter sr +* Return +* +* Argument(s) : cpu_sr global interrupt mask status. +* +* Note(s) : (1) Besides global interrupt mask bit, all other status register bits are kept unchanged. +* +* (2) Two NOP are required for properly disable interrupts. +********************************************************************************************************* +*/ + +CPU_SR_Save: + CSRFCZ CPU_SR_GM_OFFSET /* Retrieve GM bit from SR */ + SRCS R12 /* if (GM == 1) set R12 */ + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SR_Restore: + PUSHM R11 /* Save R11 into stack */ + + MFSR R11, CPU_SR_OFFSET /* Retrieve current Status Register */ + LSR R12, 1 /* Copy interrupt status to Carry */ + BST R11, CPU_SR_GM_OFFSET /* Overwrite GM bit based on Carry */ + + MTSR CPU_SR_OFFSET, R11 /* Restore Status Register GM with previous interrupt */ + /* ... status value */ + + POPM R11 /* Restore R11 from stack */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE INTERRUPTS +* +* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +* status register. +* +* void CPU_IntDis (void) +* Set global interrupt mask bit on SR +* Return +* +* void CPU_IntEn (void) +* Clear global interrupt mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_IntDis: + SSRF CPU_SR_GM_OFFSET /* set global interrupt mask (disable interrupts) */ + NOP + NOP + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_IntEn: + CSRF CPU_SR_GM_OFFSET /* clear global interrupt mask (enable interrupts) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* DISABLE/ENABLE EXCEPTIONS +* +* Description : These functions are used to disable and enable exceptions by setting or clearing the +* exception mask in the cpu status register. +* +* void CPU_ExceptDis (void) +* Set exception mask bit on SR +* Return +* +* void CPU_ExcepttEn (void) +* Clear exception mask bit on SR +* Return +********************************************************************************************************* +*/ + +CPU_ExceptDis: + SSRF CPU_SR_EM_OFFSET /* set exception mask (disable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_ExceptEn: + CSRF CPU_SR_EM_OFFSET /* clear exceptions mask (enable exceptions) */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* RESET CPU +* +* Description : This function is used to reset the CPU by returning to the reset vector. +* +* void CPU_Reset (void) +* if (current SR == 001b) { +* Push PC (START) +* Push clean SR (GM | M0) +* RETS +* } else { +* Push clean R8 (0x08080808) +* Push clean R9 (0x09090909) +* Push clean R10 (0x10101010) +* Push clean R11 (0x11111111) +* Push clean R12 (0x00000000) +* Push clean LR (0x14141414) +* Push PC (START) +* Push clean SR (GM | M0) +* RETE +* } +********************************************************************************************************* +*/ + +CPU_Reset: + MFSR R8, CPU_SR_OFFSET + BFEXTU R8, R8, CPU_SR_MX_OFFSET, 3 + CP.W R8, CPU_SR_MX_SUPERVISOR_MODE + BRNE CPU_Reset_RETE + + MOV R8, LWRD(__program_start) + ORH R8, HWRD(__program_start) + MOV R9, LWRD(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HWRD(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETS + + +CPU_Reset_RETE: + MOV R8, 0x0808 + ORH R8, 0x0808 + MOV R9, 0x0909 + ORH R9, 0x0909 + MOV R10, 0x1010 + ORH R10, 0x1010 + MOV R11, 0x1111 + ORH R11, 0x1111 + MOV R12, 0x0000 + ORH R12, 0x0000 + MOV LR, 0x1414 + ORH LR, 0x1414 + STM --SP, R8-R12, LR /* Push R8-R12, LR */ + MOV R8, LWRD(__program_start) + ORH R8, HWRD(__program_start) + MOV R9, LWRD(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + ORH R9, HWRD(CPU_SR_GM_MASK | CPU_SR_M0_MASK) + STM --SP, R8-R9 /* Push PC and SR */ + RETE + + +/* +********************************************************************************************************* +* GET/SET SYSTEM REGISTERS +* +* Description : These functions are used to get/set specific system registers. +* +* CPU_INT32U CPU_SysReg_Get_Count (void) +* CPU_INT32U CPU_SysReg_Get_Config0 (void) +* CPU_INT32U CPU_SysReg_Get_Compare (void) +* void CPU_SysReg_Set_Compare (CPU_INT32U value) +********************************************************************************************************* +*/ + +CPU_SysReg_Get_Count: + MFSR R12, CPU_COUNT_OFFSET /* Retrieve COUNT system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Config0: + MFSR R12, CPU_CONFIG0_OFFSET /* Retrieve CONFIG0 system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Get_Compare: + MFSR R12, CPU_COMPARE_OFFSET /* Retrieve COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +CPU_SysReg_Set_Compare: + MTSR CPU_COMPARE_OFFSET, R12 /* Save COMPARE system register */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the +* first binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +* CPU WORD CONFIGURATION Note #1'). +* +* (b) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +CPU_CntLeadZeros: + CLZ R12, R12 /* Count leading zeros */ + MOV PC, LR /* Restore Program Counter (return) */ + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + + END + diff --git a/BSP/Template/bsp_cpu.c b/BSP/Template/bsp_cpu.c new file mode 100644 index 0000000..81db41e --- /dev/null +++ b/BSP/Template/bsp_cpu.c @@ -0,0 +1,302 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU BOARD SUPPORT PACKAGE (BSP) FUNCTIONS +* +* TEMPLATE +* +* Filename : bsp_cpu.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define BSP_CPU_MODULE +#include + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_TS_TmrInit() +* +* Description : Initialize & start CPU timestamp timer. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (c) When applicable, timer period SHOULD be less than the typical measured time +* but MUST be less than the maximum measured time; otherwise, timer resolution +* inadequate to measure desired times. +* +* See also 'CPU_TS_TmrRd() Note #2'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +void CPU_TS_TmrInit (void) +{ + + /* $$$$ Insert code to configure & start CPU timestamp timer (see Note #2). */ + +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrRd() +* +* Description : Get current CPU timestamp timer count value. +* +* Argument(s) : none. +* +* Return(s) : Timestamp timer count (see Notes #2a & #2b). +* +* Note(s) : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (1) If timer is a 'down' counter whose values decrease with each time count, +* then the returned timer value MUST be ones-complemented. +* +* (c) (1) When applicable, the amount of time measured by CPU timestamps is +* calculated by either of the following equations : +* +* (A) Time measured = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Time measured Amount of time measured, in same +* units of (fractional) seconds +* as the Timer period +* +* Number timer counts +* (B) Time measured = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Time measured Amount of time measured, in seconds +* +* (2) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_TS_TMR CPU_TS_TmrRd (void) +{ + CPU_TS_TMR ts_tmr_cnts; + + + ts_tmr_cnts = 0u; /* $$$$ Insert code to return CPU timestamp timer value (see Note #2) */ + + return (ts_tmr_cnts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TSxx_to_uSec() +* +* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds. +* +* Argument(s) : ts_cnts CPU timestamp (in timestamp timer counts [see Note #2aA]). +* +* Return(s) : Converted CPU timestamp (in microseconds [see Note #2aD]). +* +* Note(s) : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be +* optionally defined by the developer when either of the following CPU features is +* enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) The amount of time measured by CPU timestamps is calculated by either of +* the following equations : +* +* 10^6 microseconds +* (1) Time measured = Number timer counts * ------------------- * Timer period +* 1 second +* +* Number timer counts 10^6 microseconds +* (2) Time measured = --------------------- * ------------------- +* Timer frequency 1 second +* +* where +* +* (A) Number timer counts Number of timer counts measured +* (B) Timer frequency Timer's frequency in some units +* of counts per second +* (C) Timer period Timer's period in some units of +* (fractional) seconds +* (D) Time measured Amount of time measured, +* in microseconds +* +* (b) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +* +* (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits +* -- up to 32 or 64, respectively -- into microseconds. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts) +{ + + /* $$$$ Insert code to convert (up to) 64-bits of 32-bit CPU timestamp to microseconds (see Note #2) */ + + return (0u); +} +#endif + + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts) +{ + + /* $$$$ Insert code to convert (up to) 64-bits of 64-bit CPU timestamp to microseconds (see Note #2) */ + + return (0u); +} +#endif + diff --git a/Blackfin/VDSP++/cpu.h b/Blackfin/VDSP++/cpu.h new file mode 100644 index 0000000..e57f685 --- /dev/null +++ b/Blackfin/VDSP++/cpu.h @@ -0,0 +1,493 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Blackfin +* VisualDSP++ +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/Blackfin/VDSP++/cpu_a.asm b/Blackfin/VDSP++/cpu_a.asm new file mode 100644 index 0000000..cc7b45f --- /dev/null +++ b/Blackfin/VDSP++/cpu_a.asm @@ -0,0 +1,114 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Blackfin +* VisualDSP++ +* +* Filename : cpu_a.asm +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + +.global _CPU_SR_Save +.global _CPU_SR_Restore + + +/* +********************************************************************************************************* +* EQUATES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CODE GENERATION DIRECTIVES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* EXTERNAL VARIABLES +********************************************************************************************************* +*/ + +.section program; + + +/* +********************************************************************************************************* +* SAVE/RESTORE CPU STATUS REGISTER +* +* Description : Save/Restore the state of CPU interrupts, if possible. +* +* (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +* stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +* allocated in all functions that need to disable interrupts). The previous interrupt +* status state is restored by copying 'cpu_sr' into the CPU's status register. +* +* +* Prototypes : CPU_SR CPU_SR_Save (void); +* void CPU_SR_Restore(CPU_SR cpu_sr); +* +* Note(s) : (1) These functions are used in general like this : +* +* void Task (void *p_arg) +* { +* CPU_SR_ALLOC(); Allocate storage for CPU status register +* : +* : +* CPU_CRITICAL_ENTER(); cpu_sr = CPU_SR_Save(); +* : +* : +* CPU_CRITICAL_EXIT(); CPU_SR_Restore(cpu_sr); +* : +* } +********************************************************************************************************** +*/ + +_CPU_SR_Save: + + CLI R0; + +_CPU_SR_Save.end: + RTS; + +_CPU_SR_Restore: + + STI R0; + +_CPU_SR_Restore.end: + RTS; + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/C28x/CCS/cpu.h b/C28x/CCS/cpu.h new file mode 100644 index 0000000..863063d --- /dev/null +++ b/C28x/CCS/cpu.h @@ -0,0 +1,577 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* TI C28x +* TI C/C++ Compiler +* +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignment required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 1 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_IntSrcDis (CPU_DATA bit); /* Disable specific interrupt source. */ +void CPU_IntSrcEn (CPU_DATA bit); /* Enable specific interrupt source. */ +void CPU_IntSrcPendClr(CPU_DATA bit); /* Clear specific pending interrupt. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore (CPU_SR cpu_sr); /* Restore CPU status word. */ + +CPU_DATA CPU_RevBits (CPU_DATA val); /* Reverse the bits in a data value. */ + + +/* +********************************************************************************************************* +* CONTROL REGISTERS +********************************************************************************************************* +*/ + +extern cregister volatile unsigned int IFR; +extern cregister volatile unsigned int IER; + + +/* +********************************************************************************************************* +* INTERRUPT SOURCES +********************************************************************************************************* +*/ + +#define CPU_INT_RTOSINT 16u +#define CPU_INT_DLOGINT 15u +#define CPU_INT_INT14 14u +#define CPU_INT_INT13 13u +#define CPU_INT_INT12 12u +#define CPU_INT_INT11 11u +#define CPU_INT_INT10 10u +#define CPU_INT_INT9 9u +#define CPU_INT_INT8 8u +#define CPU_INT_INT7 7u +#define CPU_INT_INT6 65 +#define CPU_INT_INT5 5u +#define CPU_INT_INT4 4u +#define CPU_INT_INT3 3u +#define CPU_INT_INT2 2u +#define CPU_INT_INT1 1u + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/C28x/CCS/cpu_a.asm b/C28x/CCS/cpu_a.asm new file mode 100644 index 0000000..72f9b66 --- /dev/null +++ b/C28x/CCS/cpu_a.asm @@ -0,0 +1,268 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; TI C28x +; TI C/C++ Compiler +; +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .def _CPU_IntDis + .def _CPU_IntEn + + .def _CPU_SR_Save + .def _CPU_SR_Restore + + .def _CPU_CntLeadZeros + + .def _CPU_RevBits + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + ; Set text section and reset local labels. + .text + .newblock + + +;******************************************************************************************************** +; DISABLE/ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + + .asmfunc +_CPU_IntDis: + DINT + LRETR + .endasmfunc + + .asmfunc +_CPU_IntEn: + EINT + LRETR + .endasmfunc + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + .asmfunc +_CPU_SR_Save: + PUSH ST1 + DINT + POP @AL + AND AL, #1 + LRETR + .endasmfunc + + .asmfunc +_CPU_SR_Restore: + PUSH ST1 + POP AR0 + AND AR0, #0xFFFE + OR AL, AR0 + PUSH AL + POP ST1 + LRETR + .endasmfunc + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports up to the following data value sizes, depending on the configured +; size of 'CPU_DATA' (see 'cpu.h CPU WORD CONFIGURATION Note #1') : +; +; (1) 8-bits +; (2) 16-bits +; (3) 32-bits +; (4) 64-bits +; +; (b) (1) For 8-bit values : +; +; b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; 0 0 0 1 x x x x 3 +; 0 0 0 0 1 x x x 4 +; 0 0 0 0 0 1 x x 5 +; 0 0 0 0 0 0 1 x 6 +; 0 0 0 0 0 0 0 1 7 +; 0 0 0 0 0 0 0 0 8 +; +; +; (2) For 16-bit values : +; +; b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 11 +; 0 0 0 0 1 x x x 12 +; 0 0 0 0 0 1 x x 13 +; 0 0 0 0 0 0 1 x 14 +; 0 0 0 0 0 0 0 1 15 +; 0 0 0 0 0 0 0 0 16 +; +; +; (3) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (4) For 64-bit values : +; +; b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 59 +; 0 0 0 0 1 x x x 60 +; 0 0 0 0 0 1 x x 61 +; 0 0 0 0 0 0 1 x 62 +; 0 0 0 0 0 0 0 1 63 +; 0 0 0 0 0 0 0 0 64 +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +; is #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + + .asmfunc +_CPU_CntLeadZeros: + MOV AH, AL + AND AL, #0x8000 + SBF $1, NEQ + OR AL, #0xFFFF + CSB ACC + MOV AL, T + ADD AL, #1 + LRETR +$1: + MOV AL, #0 + LRETR + .endasmfunc + + +;******************************************************************************************************** +; CPU_RevBits() +; REVERSE BITS +; +; Description : Reverses the bits in a data value. +; +; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +; +; Argument(s) : val Data value to reverse bits. +; +; Return(s) : Value with all bits in 'val' reversed (see Note #1). +; +; Note(s) : (1) The final, reversed data value for 'val' is such that : +; +; 'val's final bit 0 = 'val's original bit N +; 'val's final bit 1 = 'val's original bit (N - 1) +; 'val's final bit 2 = 'val's original bit (N - 2) +; +; ... ... +; +; 'val's final bit (N - 2) = 'val's original bit 2 +; 'val's final bit (N - 1) = 'val's original bit 1 +; 'val's final bit N = 'val's original bit 0 +;******************************************************************************************************** + + .asmfunc +_CPU_RevBits: + FLIP AL + LRETR + .endasmfunc + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + .end diff --git a/C28x/CCS/cpu_c.c b/C28x/CCS/cpu_c.c new file mode 100644 index 0000000..d8b4fd0 --- /dev/null +++ b/C28x/CCS/cpu_c.c @@ -0,0 +1,257 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* TI C28x +* TI C/C++ Compiler +* +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_IntSrcDis() +* +* Description : Disable an interrupt source. +* +* Argument(s) : int_id Interrupt source in interrupt enable register. +* +* Return(s) : none. +* +* Note(s) : (1) The RESET interrupt cannot be disabled. +********************************************************************************************************* +*/ + +void CPU_IntSrcDis (CPU_DATA bit) +{ + CPU_SR_ALLOC(); + + + if (bit <= CPU_INT_RTOSINT) { + CPU_CRITICAL_ENTER(); + IER = IER & ~(1u << (bit-1)); + CPU_CRITICAL_EXIT(); + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcEn() +* +* Description : Enable an interrupt source. +* +* Argument(s) : int_id Interrupt source in interrupt enable register. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntSrcEn (CPU_DATA bit) +{ + CPU_SR_ALLOC(); + + + if (bit <= CPU_INT_RTOSINT) { + CPU_CRITICAL_ENTER(); + IER = IER | (1u << (bit-1)); + CPU_CRITICAL_EXIT(); + } +} + + +/* +********************************************************************************************************* +* CPU_IntSrcPendClr() +* +* Description : Clear a pending interrupt. +* +* Argument(s) : bit Bit of interrupt source in interrupt enable register (see 'CPU_IntSrcDis()'). +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntSrcPendClr (CPU_DATA bit) +{ + /* The 'AND IFR' instruction cannot be used with ... */ + /* ... anything else than a 16bit constant. */ + switch (bit) { + case CPU_INT_RTOSINT: + asm(" AND IFR, #0x7FFF"); + break; + + + case CPU_INT_DLOGINT: + asm(" AND IFR, #0xBFFF"); + break; + + + case CPU_INT_INT14: + asm(" AND IFR, #0xDFFF"); + break; + + + case CPU_INT_INT13: + asm(" AND IFR, #0xEFFF"); + break; + + + case CPU_INT_INT12: + asm(" AND IFR, #0xF7FF"); + break; + + + case CPU_INT_INT11: + asm(" AND IFR, #0xFBFF"); + break; + + + case CPU_INT_INT10: + asm(" AND IFR, #0xFDFF"); + break; + + + case CPU_INT_INT9: + asm(" AND IFR, #0xFEFF"); + break; + + + case CPU_INT_INT8: + asm(" AND IFR, #0xFF7F"); + break; + + + case CPU_INT_INT7: + asm(" AND IFR, #0xFFBF"); + break; + + + case CPU_INT_INT6: + asm(" AND IFR, #0xFFDF"); + break; + + + case CPU_INT_INT5: + asm(" AND IFR, #0xFFEF"); + break; + + + case CPU_INT_INT4: + asm(" AND IFR, #0xFFF7"); + break; + + + case CPU_INT_INT3: + asm(" AND IFR, #0xFFFB"); + break; + + + case CPU_INT_INT2: + asm(" AND IFR, #0xFFFD"); + break; + + + case CPU_INT_INT1: + asm(" AND IFR, #0xFFFE"); + break; + + + default: /* 'default' case intentionally empty. */ + break; + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/Cache/ARC/EM6/cpu_cache_em6.c b/Cache/ARC/EM6/cpu_cache_em6.c new file mode 100644 index 0000000..dfd37fd --- /dev/null +++ b/Cache/ARC/EM6/cpu_cache_em6.c @@ -0,0 +1,240 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* +* Synopsys ARC EM6 +* +* Filename : cpu_cache_em6.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + /* Cache operations. */ +#define CPU_CACHE_EM6_INVALIDATE CPU_AR_DC_IVDL +#define CPU_CACHE_EM6_FLUSH CPU_AR_DC_FLDL + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_Cache_Do (CPU_INT32U what, + void *addr_start, + CPU_ADDR len); + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_Cache_Init() +* +* Description : Initializes the cache. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init (void) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* Enable data cache. */ + CPU_AR_WR(CPU_AR_DC_CTRL, CPU_AR_DC_CTRL_DC_EN); + + /* Invalidate data cache. */ + CPU_AR_WR(CPU_AR_DC_IVDC, CPU_AR_DC_IVDC_IV); + + /* Flush data cache. */ + CPU_AR_WR(CPU_AR_DC_FLSH, CPU_AR_DC_FLSH_FL); + + while ((CPU_AR_RD(CPU_AR_DC_CTRL) & CPU_AR_DC_CTRL_FS) > 0u) { + ; + } +#endif +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeFlush() +* +* Description : Flushes a range of the data cache to the main memory. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeFlush (void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* Flush range, if found, to main memory */ + CPU_Cache_Do(CPU_CACHE_EM6_FLUSH, addr_start, len); +#else + /* Prevent possible compiler warning. */ + (void)&addr_start; + (void)&len; +#endif +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeInv() +* +* Description : Invalidates a range of the data cache. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeInv (void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* Invalidate range, if found, in cache */ + CPU_Cache_Do(CPU_CACHE_EM6_INVALIDATE, addr_start, len); +#else + /* Prevent possible compiler warning. */ + (void)&addr_start; + (void)&len; +#endif +} + + +/* +********************************************************************************************************* +* CPU_Cache_Do() +* +* Description : Does 'what' to range within addr_start and addr_start + len. +* +* Argument(s) : what Cache action to perform: +* +* CPU_CACHE_EM6_INVALIDATE Invalidate range. +* CPU_CACHE_EM6_FLUSH Flush range. +* +* addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Do (CPU_INT32U what, + void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + CPU_INT32U addr; + CPU_INT32U lines; + + + addr = ((CPU_INT32U)addr_start) & CPU_CACHE_DATA_LINE_MASK; + + lines = len / CPU_CACHE_DATA_LINE_SIZE; + if ((len % CPU_CACHE_DATA_LINE_SIZE) != 0) { + lines++; + } + + while (lines > 0) { + CPU_AR_WR(what, addr); + addr += CPU_CACHE_DATA_LINE_SIZE; + lines--; + } +#else + /* Prevent possible compiler warning. */ + (void)&what; + (void)&addr_start; + (void)&len; +#endif +} diff --git a/Cache/ARM/armv5_generic_l1/IAR/cpu_cache_armv5_generic_l1_a.s b/Cache/ARM/armv5_generic_l1/IAR/cpu_cache_armv5_generic_l1_a.s new file mode 100644 index 0000000..18304ad --- /dev/null +++ b/Cache/ARM/armv5_generic_l1/IAR/cpu_cache_armv5_generic_l1_a.s @@ -0,0 +1,128 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU CACHE IMPLEMENTATION +; ARMv5 L1 Cache +; IAR C Compiler +; +; Filename : cpu_cache_armv5_generic_l1_a.s +; Version : v1.32.00 +;******************************************************************************************************** + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + PRESERVE8 + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;******************************************************************************************************** +; CPU_DCache_LineSizeGet() +; +; Description : Returns the cache line size. +; +; Prototypes : void CPU_DCache_LineSizeGet (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + + BX lr + + +;******************************************************************************************************** +; INVALIDATE DATA CACHE RANGE +; +; Description : Invalidate a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeInv (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to invalidate. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeInv + +CPU_DCache_RangeInv + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + ADD r1, r1, r0 + BIC r0, r0, #31 + +CPU_DCache_RangeInvL1: + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, #32 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + BX LR + +CPU_DCache_RangeInv_END + BX LR + + +;******************************************************************************************************** +; FLUSH DATA CACHE RANGE +; +; Description : Flush (clean) a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to flush. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + ADD r1, r1, r0 + BIC r0, r0, #31 + +CPU_DCache_RangeFlushL1: + MCR p15, 0, r0, c7, c14, 1 + ADD r0, r0, #32 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL1 + +CPU_DCache_RangeFlush_END + BX LR + + END diff --git a/Cache/ARM/armv5_generic_l1/cpu_cache_armv5_generic_l1.c b/Cache/ARM/armv5_generic_l1/cpu_cache_armv5_generic_l1.c new file mode 100644 index 0000000..dd2662c --- /dev/null +++ b/Cache/ARM/armv5_generic_l1/cpu_cache_armv5_generic_l1.c @@ -0,0 +1,79 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* ARMv5 Generic L1 Cache +* +* Filename : cpu_cache_armv5_generic_l1.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ +#include +#include "../../../cpu_cache.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* EXTERNAL DECLARATIONS +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_Cache_Linesize; /* Cache line size. */ + + +/* +********************************************************************************************************* +* CPU_CacheMGMTInit() +* +* Description : Initialize cpu cache module. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init(void) +{ + CPU_Cache_Linesize = 32u; +} + +#ifdef __cplusplus +} +#endif diff --git a/Cache/ARM/armv7_generic_l1/ARM/cpu_cache_armv7_generic_l1_a.s b/Cache/ARM/armv7_generic_l1/ARM/cpu_cache_armv7_generic_l1_a.s new file mode 100644 index 0000000..0ce17e3 --- /dev/null +++ b/Cache/ARM/armv7_generic_l1/ARM/cpu_cache_armv7_generic_l1_a.s @@ -0,0 +1,154 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU CACHE IMPLEMENTATION +; ARMv7 Generic L1 Cache +; ARM C Compiler +; +; Filename : cpu_cache_armv7_generic_l1_a.s +; Version : v1.32.00 +;******************************************************************************************************** + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + PRESERVE8 + + AREA BSP_Cache,CODE,READONLY + + ENTRY + + +CPU_CACHE_L2C_REG7_CACHE_SYNC EQU 0x730 +CPU_CACHE_L2C_REG7_CACHE_INV_PA EQU 0x770 +CPU_CACHE_L2C_REG7_CACHE_INV_WAY EQU 0x77C +CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA EQU 0x7B0 + + + IMPORT CPU_Cache_Linesize + + +;******************************************************************************************************** +; CPU_DCache_LineSizeGet() +; +; Description : Returns the cache line size. +; +; Prototypes : void CPU_DCache_LineSizeGet (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet FUNCTION + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + BX lr + + ENDFUNC + + +;******************************************************************************************************** +; INVALIDATE DATA CACHE RANGE +; +; Description : Invalidate a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeInv (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to invalidate. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeInv + +CPU_DCache_RangeInv FUNCTION + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + MOV32 r2, CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeInvL1 + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; FLUSH DATA CACHE RANGE +; +; Description : Flush (clean) a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to flush. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush FUNCTION + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + MOV32 r2, CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeFlushL1 + MCR p15, 0, r0, c7, c10, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + +CPU_DCache_RangeFlush_END + BX LR + + ENDFUNC + + + END + diff --git a/Cache/ARM/armv7_generic_l1/GNU/cpu_cache_armv7_generic_l1_a.S b/Cache/ARM/armv7_generic_l1/GNU/cpu_cache_armv7_generic_l1_a.S new file mode 100644 index 0000000..f871663 --- /dev/null +++ b/Cache/ARM/armv7_generic_l1/GNU/cpu_cache_armv7_generic_l1_a.S @@ -0,0 +1,141 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU CACHE IMPLEMENTATION +@ ARMv7 Generic L1 Cache +@ GNU C Compiler +@ +@ Filename : cpu_cache_armv7_generic_l1_a.S +@ Version : v1.32.00 +@******************************************************************************************************** + +@******************************************************************************************************** +@ MACROS AND DEFINIITIONS +@******************************************************************************************************** + + + .code 32 + + +.equ CPU_CACHE_L2C_REG7_CACHE_SYNC, 0x730 +.equ CPU_CACHE_L2C_REG7_CACHE_INV_PA, 0x770 +.equ CPU_CACHE_L2C_REG7_CACHE_INV_WAY, 0x77C +.equ CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA, 0x7B0 + + +@******************************************************************************************************** +@ CPU_DCache_LineSizeGet() +@ +@ Description : Returns the cache line size. +@ +@ Prototypes : void CPU_DCache_LineSizeGet (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet: + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + BX lr + + +@******************************************************************************************************** +@ INVALIDATE DATA CACHE RANGE +@ +@ Description : Invalidate a range of data cache by MVA. +@ +@ Prototypes : void CPU_DCache_RangeInv (void *p_mem, +@ CPU_SIZE_T range); +@ +@ Argument(s) : p_mem Start address of the region to invalidate. +@ +@ range Size of the region to invalidate in bytes. +@ +@ Note(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_RangeInv + +CPU_DCache_RangeInv: + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + MOVW r2, #:lower16:CPU_Cache_Linesize + MOVT r2, #:upper16:CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeInvL1: + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END: + BX LR + + +@******************************************************************************************************** +@ FLUSH DATA CACHE RANGE +@ +@ Description : Flush (clean) a range of data cache by MVA. +@ +@ Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +@ CPU_SIZE_T range)@ +@ +@ Argument(s) : p_mem Start address of the region to flush. +@ +@ range Size of the region to invalidate in bytes. +@ +@ Note(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush: + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + MOVW r2, #:lower16:CPU_Cache_Linesize + MOVT r2, #:upper16:CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeFlushL1: + MCR p15, 0, r0, c7, c10, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + +CPU_DCache_RangeFlush_END: + BX LR + diff --git a/Cache/ARM/armv7_generic_l1/IAR/cpu_cache_armv7_generic_l1_a.s b/Cache/ARM/armv7_generic_l1/IAR/cpu_cache_armv7_generic_l1_a.s new file mode 100644 index 0000000..5e60d8e --- /dev/null +++ b/Cache/ARM/armv7_generic_l1/IAR/cpu_cache_armv7_generic_l1_a.s @@ -0,0 +1,140 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU CACHE IMPLEMENTATION +; ARMv7 Generic L1 Cache +; IAR EWARM Compiler +; +; Filename : cpu_cache_armv7_generic_l1_a.s +; Version : v1.32.00 +;******************************************************************************************************** + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + IMPORT CPU_Cache_Linesize + + + PRESERVE8 + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;******************************************************************************************************** +; CPU_DCache_LineSizeGet() +; +; Description : Returns the cache line size. +; +; Prototypes : void CPU_DCache_LineSizeGet (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + + BX lr + + +;******************************************************************************************************** +; INVALIDATE DATA CACHE RANGE +; +; Description : Invalidate a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeInv (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to invalidate. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeInv + +CPU_DCache_RangeInv + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + MOV32 r2, CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeInvL1 + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END + BX LR + + +;******************************************************************************************************** +; FLUSH DATA CACHE RANGE +; +; Description : Flush (clean) a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to flush. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + MOV32 r2, CPU_Cache_Linesize + LDR r2, [r2] + SUB r3, r2, #1 + ADD r1, r1, r0 + BIC r0, r0, r3 + +CPU_DCache_RangeFlushL1 + MCR p15, 0, r0, c7, c10, 1 + ADD r0, r0, r2 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + +CPU_DCache_RangeFlush_END + BX LR + + END diff --git a/Cache/ARM/armv7_generic_l1/cpu_cache_armv7_generic_l1.c b/Cache/ARM/armv7_generic_l1/cpu_cache_armv7_generic_l1.c new file mode 100644 index 0000000..3102cea --- /dev/null +++ b/Cache/ARM/armv7_generic_l1/cpu_cache_armv7_generic_l1.c @@ -0,0 +1,82 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* ARMv7 Generic L1 Cache +* +* Filename : cpu_cache_armv7_generic_l1.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ +#include +#include "../../../cpu_cache.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* EXTERNAL DECLARATIONS +********************************************************************************************************* +*/ + +CPU_INT32U CPU_DCache_LineSizeGet(void); + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_Cache_Linesize; /* Cache line size. */ + + +/* +********************************************************************************************************* +* CPU_CacheMGMTInit() +* +* Description : Initialize cpu cache module. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init(void) +{ + CPU_Cache_Linesize = CPU_DCache_LineSizeGet(); +} + +#ifdef __cplusplus +} +#endif diff --git a/Cache/ARM/armv7_generic_l1_l2c310_l2/ARM/cpu_cache_armv7_generic_l1_l2c310_l2_a.s b/Cache/ARM/armv7_generic_l1_l2c310_l2/ARM/cpu_cache_armv7_generic_l1_l2c310_l2_a.s new file mode 100644 index 0000000..b709d49 --- /dev/null +++ b/Cache/ARM/armv7_generic_l1_l2c310_l2/ARM/cpu_cache_armv7_generic_l1_l2c310_l2_a.s @@ -0,0 +1,175 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU CACHE IMPLEMENTATION +; Generic ARMv7 L1 Cache and External L2C310 L2 Cache Controller +; ARM C Compiler +; +; Filename : cpu_cache_armv7_generic_l1_l2c310_l2_a.s +; Version : v1.32.00 +;******************************************************************************************************** + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + PRESERVE8 + + AREA BSP_Cache,CODE,READONLY + + ENTRY + + +CPU_CACHE_L2C_REG7_CACHE_SYNC EQU 0x730 +CPU_CACHE_L2C_REG7_CACHE_INV_PA EQU 0x770 +CPU_CACHE_L2C_REG7_CACHE_INV_WAY EQU 0x77C +CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA EQU 0x7B0 + + + IMPORT CPU_Cache_Linesize + IMPORT CPU_Cache_PL310BaseAddr + + +;******************************************************************************************************** +; CPU_DCache_LineSizeGet() +; +; Description : Returns the cache line size. +; +; Prototypes : void CPU_DCache_LineSizeGet (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet FUNCTION + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + BX lr + + ENDFUNC + + +;******************************************************************************************************** +; INVALIDATE DATA CACHE RANGE +; +; Description : Invalidate a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeInv (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to invalidate. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeInv + +CPU_DCache_RangeInv FUNCTION + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + ADD r1, r1, r0 + MOV32 r12, CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + MOV r3, r0 + + MOV32 r2, CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeInvL2 + STR r3, [r2, #CPU_CACHE_L2C_REG7_CACHE_INV_PA] + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeInvL2 + DSB + +CPU_DCache_RangeInvL1 + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END + BX LR + + ENDFUNC + + +;******************************************************************************************************** +; FLUSH DATA CACHE RANGE +; +; Description : Flush (clean) a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to flush. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush FUNCTION + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + ADD r1, r1, r0 + MOV32 r12, CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + + MOV r3, r0 +CPU_DCache_RangeFlushL1 + MCR p15, 0, r3, c7, c14, 1 + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + + MOV32 r2, CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeFlushL2 + STR r0, [r2, #CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA] + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL2 + DSB + +CPU_DCache_RangeFlush_END + BX LR + + ENDFUNC + + + END + diff --git a/Cache/ARM/armv7_generic_l1_l2c310_l2/GNU/cpu_cache_armv7_generic_l1_l2c310_l2_a.S b/Cache/ARM/armv7_generic_l1_l2c310_l2/GNU/cpu_cache_armv7_generic_l1_l2c310_l2_a.S new file mode 100644 index 0000000..f4fe4eb --- /dev/null +++ b/Cache/ARM/armv7_generic_l1_l2c310_l2/GNU/cpu_cache_armv7_generic_l1_l2c310_l2_a.S @@ -0,0 +1,163 @@ +@******************************************************************************************************** +@ uC/CPU +@ CPU CONFIGURATION & PORT LAYER +@ +@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +@ +@ SPDX-License-Identifier: APACHE-2.0 +@ +@ This software is subject to an open source license and is distributed by +@ Silicon Laboratories Inc. pursuant to the terms of the Apache License, +@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +@ +@******************************************************************************************************** + +@******************************************************************************************************** +@ +@ CPU CACHE IMPLEMENTATION +@ Generic ARMv7 L1 Cache and External L2C310 L2 Cache Controller +@ GNU C Compiler +@ +@ Filename : cpu_cache_armv7_generic_l1_l2c310_l2_a.S +@ Version : v1.32.00 +@******************************************************************************************************** + +@******************************************************************************************************** +@ MACROS AND DEFINIITIONS +@******************************************************************************************************** + + + .code 32 + + +.equ CPU_CACHE_L2C_REG7_CACHE_SYNC, 0x730 +.equ CPU_CACHE_L2C_REG7_CACHE_INV_PA, 0x770 +.equ CPU_CACHE_L2C_REG7_CACHE_INV_WAY, 0x77C +.equ CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA, 0x7B0 + + +@******************************************************************************************************** +@ CPU_DCache_LineSizeGet() +@ +@ Description : Returns the cache line size. +@ +@ Prototypes : void CPU_DCache_LineSizeGet (void) +@ +@ Argument(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet: + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + BX lr + + +@******************************************************************************************************** +@ INVALIDATE DATA CACHE RANGE +@ +@ Description : Invalidate a range of data cache by MVA. +@ +@ Prototypes : void CPU_DCache_RangeInv (void *p_mem, +@ CPU_SIZE_T range)@ +@ +@ Argument(s) : p_mem Start address of the region to invalidate. +@ +@ range Size of the region to invalidate in bytes. +@ +@ Note(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_RangeInv + +CPU_DCache_RangeInv: + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + ADD r1, r1, r0 + MOVW R12, #:lower16:CPU_Cache_Linesize + MOVT R12, #:upper16:CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + MOV r3, r0 + + MOVW r2, #:lower16:CPU_Cache_PL310BaseAddr + MOVT r2, #:upper16:CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeInvL2: + STR r3, [r2, #CPU_CACHE_L2C_REG7_CACHE_INV_PA] + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeInvL2 + DSB + +CPU_DCache_RangeInvL1: + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END: + BX LR + + +@******************************************************************************************************** +@ FLUSH DATA CACHE RANGE +@ +@ Description : Flush (clean) a range of data cache by MVA. +@ +@ Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +@ CPU_SIZE_T range)@ +@ +@ Argument(s) : p_mem Start address of the region to flush. +@ +@ range Size of the region to invalidate in bytes. +@ +@ Note(s) : none. +@******************************************************************************************************** + +.global CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush: + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + ADD r1, r1, r0 + MOVW R12, #:lower16:CPU_Cache_Linesize + MOVT R12, #:upper16:CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + + MOV r3, r0 +CPU_DCache_RangeFlushL1: + MCR p15, 0, r3, c7, c14, 1 + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + + MOVW r2, #:lower16:CPU_Cache_PL310BaseAddr + MOVT r2, #:upper16:CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeFlushL2: + STR r0, [r2, #CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA] + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL2 + DSB + +CPU_DCache_RangeFlush_END: + BX LR + diff --git a/Cache/ARM/armv7_generic_l1_l2c310_l2/IAR/cpu_cache_armv7_generic_l1_l2c310_l2_a.s b/Cache/ARM/armv7_generic_l1_l2c310_l2/IAR/cpu_cache_armv7_generic_l1_l2c310_l2_a.s new file mode 100644 index 0000000..911102c --- /dev/null +++ b/Cache/ARM/armv7_generic_l1_l2c310_l2/IAR/cpu_cache_armv7_generic_l1_l2c310_l2_a.s @@ -0,0 +1,169 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU CACHE IMPLEMENTATION +; Generic ARMv7 L1 Cache and External L2C310 L2 Cache Controller +; IAR EWARM Compiler +; +; Filename : cpu_cache_armv7_generic_l1_l2c310_l2_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + +CPU_CACHE_L2C_REG7_CACHE_SYNC EQU 0x730 +CPU_CACHE_L2C_REG7_CACHE_INV_PA EQU 0x770 +CPU_CACHE_L2C_REG7_CACHE_INV_WAY EQU 0x77C +CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA EQU 0x7B0 + + + IMPORT CPU_Cache_Linesize + IMPORT CPU_Cache_PL310BaseAddr + + + PRESERVE8 + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;******************************************************************************************************** +; CPU_DCache_LineSizeGet() +; +; Description : Returns the cache line size. +; +; Prototypes : void CPU_DCache_LineSizeGet (void) +; +; Argument(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_LineSizeGet + +CPU_DCache_LineSizeGet + + MRC p15, 0, r0, c0, c0, 1 + AND r0, r0, #0xF0000 + LSR r0, r0, #16 + MOV r1, #1 + LSL r1, r1, r0 + LSL r0, r1, #2 + + + BX lr + + +;******************************************************************************************************** +; INVALIDATE DATA CACHE RANGE +; +; Description : Invalidate a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeInv (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to invalidate. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeInv + +CPU_DCache_RangeInv + CMP r1, #0 + BEQ CPU_DCache_RangeInv_END + + DSB + ADD r1, r1, r0 + MOV32 r12, CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + MOV r3, r0 + + MOV32 r2, CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeInvL2 + STR r3, [r2, #CPU_CACHE_L2C_REG7_CACHE_INV_PA] + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeInvL2 + DSB + +CPU_DCache_RangeInvL1 + MCR p15,0, r0, c7, c6, 1 + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeInvL1 + DSB + +CPU_DCache_RangeInv_END + BX LR + + +;******************************************************************************************************** +; FLUSH DATA CACHE RANGE +; +; Description : Flush (clean) a range of data cache by MVA. +; +; Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +; CPU_SIZE_T range); +; +; Argument(s) : p_mem Start address of the region to flush. +; +; range Size of the region to invalidate in bytes. +; +; Note(s) : none. +;******************************************************************************************************** + + EXPORT CPU_DCache_RangeFlush + +CPU_DCache_RangeFlush + CMP r1, #0 + BEQ CPU_DCache_RangeFlush_END + + DSB + ADD r1, r1, r0 + MOV32 r12, CPU_Cache_Linesize + LDR r12, [r12] + SUB r2, r12, #1 + BIC r0, r0, r2 + + MOV r3, r0 +CPU_DCache_RangeFlushL1 + MCR p15, 0, r3, c7, c14, 1 + ADD r3, r3, r12 + CMP r3, r1 + BLT CPU_DCache_RangeFlushL1 + DSB + + MOV32 r2, CPU_Cache_PL310BaseAddr + LDR r2, [r2] +CPU_DCache_RangeFlushL2 + STR r0, [r2, #CPU_CACHE_L2C_REG7_CACHE_CLEAN_PA] + ADD r0, r0, r12 + CMP r0, r1 + BLT CPU_DCache_RangeFlushL2 + DSB + +CPU_DCache_RangeFlush_END + BX LR + + END diff --git a/Cache/ARM/armv7_generic_l1_l2c310_l2/cpu_cache_armv7_generic_l1_l2c310_l2.c b/Cache/ARM/armv7_generic_l1_l2c310_l2/cpu_cache_armv7_generic_l1_l2c310_l2.c new file mode 100644 index 0000000..bb7dddd --- /dev/null +++ b/Cache/ARM/armv7_generic_l1_l2c310_l2/cpu_cache_armv7_generic_l1_l2c310_l2.c @@ -0,0 +1,88 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* Generic ARMv7 L1 Cache and External L2C310 L2 Cache Controller +* +* Filename : cpu_cache_armv7_generic_l1_l2c310_l2.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ +#include +#include "../../../cpu_cache.h" +#include + +#ifndef CPU_CACHE_CFG_L2C310_BASE_ADDR +#error "CPU_CFG.H, Missing CPU_CACHE_CFG_L2C310_BASE_ADDR: Base address of L2C310 Level 2 cache controller" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* EXTERNAL DECLARATIONS +********************************************************************************************************* +*/ + +CPU_INT32U CPU_DCache_LineSizeGet (void); + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_Cache_Linesize; /* Cache line size. */ +CPU_INT32U CPU_Cache_PL310BaseAddr; /* PL310 L2 cache controller base addr. */ + + +/* +********************************************************************************************************* +* CPU_CacheMGMTInit() +* +* Description : Initialize cpu cache module. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init(void) +{ + CPU_Cache_Linesize = CPU_DCache_LineSizeGet(); + CPU_Cache_PL310BaseAddr = CPU_CACHE_CFG_L2C310_BASE_ADDR; +} + +#ifdef __cplusplus +} +#endif diff --git a/Cache/ARM/armv7m_generic_l1/cpu_cache_armv7m_generic_l1.c b/Cache/ARM/armv7m_generic_l1/cpu_cache_armv7m_generic_l1.c new file mode 100644 index 0000000..34d2918 --- /dev/null +++ b/Cache/ARM/armv7m_generic_l1/cpu_cache_armv7m_generic_l1.c @@ -0,0 +1,203 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* ARMv7-M L1 Cache +* +* Filename : cpu_cache_armv7m_generic_l1.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ +#include +#include "../../../cpu_cache.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* MACROS AND DEFINIITIONS +********************************************************************************************************* +*/ + /* ------ CACHE CONTROL IDENTIFICATION REGISTERS ------ */ +#define SCS_CLIDR (*((CPU_REG32 *)(0xE000ED78u))) +#define SCS_CTR (*((CPU_REG32 *)(0xE000ED7Cu))) +#define SCS_CCSIDR (*((CPU_REG32 *)(0xE000ED80u))) +#define SCS_CCSELR (*((CPU_REG32 *)(0xE000ED84u))) + /* ----------- CACHE MAINTENANCE OPERATIONS ----------- */ +#define SCS_ICIALLU (*((CPU_REG32 *)(0xE000EF50u))) /* Invalidate I-cache to PoU */ +#define SCS_ICIMVAU (*((CPU_REG32 *)(0xE000EF58u))) /* Invalidate I-cache to PoU by MVA */ +#define SCS_DCIMVAC (*((CPU_REG32 *)(0xE000EF5Cu))) /* Invalidate D-cache to PoC by MVA */ +#define SCS_DCISW (*((CPU_REG32 *)(0xE000EF60u))) /* Invalidate D-cache by Set/Way */ +#define SCS_DCCMVAU (*((CPU_REG32 *)(0xE000EF64u))) /* Clean D-cache to PoU by MVA */ +#define SCS_DCCMVAC (*((CPU_REG32 *)(0xE000EF68u))) /* Clean D-cache to PoC by MVA */ +#define SCS_DCCSW (*((CPU_REG32 *)(0xE000EF6Cu))) /* Clean D-cache by Set/Way */ +#define SCS_DCCIMVAC (*((CPU_REG32 *)(0xE000EF70u))) /* Clean and invalidate D-cache by MVA */ +#define SCS_DCCISW (*((CPU_REG32 *)(0xE000EF74u))) /* Clean and invalidate D-cache by Set/Way */ +#define SCS_BPIALL (*((CPU_REG32 *)(0xE000EF78u))) /* Invalidate Branch predictor */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static CPU_INT32U CPU_DCache_LineSizeGet (void); + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +static CPU_INT32U CPU_Cache_Linesize; /* Cache line size. */ + + +/* +********************************************************************************************************* +* CPU_Cache_Init() +* +* Description : Initialize cpu cache module. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init (void) +{ + CPU_Cache_Linesize = CPU_DCache_LineSizeGet(); +} + + +/* +********************************************************************************************************* +* CPU_DCache_LineSizeGet() +* +* Description : Returns the cache line size. +* +* Prototypes : CPU_INT32U CPU_DCache_LineSizeGet (void) +* +* Argument(s) : none. +* +* Note(s) : Line Size = 2^(CCSIDR[2:0] + 2) +********************************************************************************************************* +*/ + +static CPU_INT32U CPU_DCache_LineSizeGet (void) +{ + return (1u << ((SCS_CCSIDR & 0x7u)) + 2u); +} + + +/* +********************************************************************************************************* +* INVALIDATE DATA CACHE RANGE +* +* Description : Invalidate a range of data cache by MVA. +* +* Prototypes : void CPU_DCache_RangeInv (void *p_mem, +* CPU_ADDR len); +* +* Argument(s) : p_mem Start address of the region to invalidate. +* +* range Size of the region to invalidate in bytes. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeInv (void *addr_start, + CPU_ADDR len) +{ + /* Align the address according to the line size. */ + addr_start = (void *)((CPU_ADDR)addr_start & ~(CPU_Cache_Linesize - 1u)); + + CPU_MB(); + + while(len > CPU_Cache_Linesize) { + SCS_DCIMVAC = (CPU_ADDR)addr_start; + addr_start = (void *)((CPU_ADDR)addr_start + CPU_Cache_Linesize); + len -= CPU_Cache_Linesize; + } + + if (len > 0u) { + SCS_DCIMVAC = (CPU_ADDR)addr_start; + } + + CPU_MB(); +} + + +/* +********************************************************************************************************* +* FLUSH DATA CACHE RANGE +* +* Description : Flush (clean) a range of data cache by MVA. +* +* Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +* CPU_ADDR len); +* +* Argument(s) : p_mem Start address of the region to flush. +* +* range Size of the region to invalidate in bytes. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeFlush (void *addr_start, + CPU_ADDR len) +{ + /* Align the address according to the line size. */ + addr_start = (void *)((CPU_ADDR)addr_start & ~(CPU_Cache_Linesize - 1u)); + + CPU_MB(); + + while(len > CPU_Cache_Linesize) { + SCS_DCCMVAC = (CPU_ADDR)addr_start; + addr_start = (void *)((CPU_ADDR)addr_start + CPU_Cache_Linesize); + len -= CPU_Cache_Linesize; + } + + if (len > 0u) { + SCS_DCCMVAC = (CPU_ADDR)addr_start; + } + + CPU_MB(); +} + +#ifdef __cplusplus +} +#endif diff --git a/Cache/Freescale/Kinetis/cpu_cache_kinetis.c b/Cache/Freescale/Kinetis/cpu_cache_kinetis.c new file mode 100644 index 0000000..be8231a --- /dev/null +++ b/Cache/Freescale/Kinetis/cpu_cache_kinetis.c @@ -0,0 +1,338 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* +* Freescale Kinetis +* +* Filename : cpu_cache_kinetis.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#define KINETIS_CACHE_MODULE +#include +#include + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + /* ----- KINETIS LOCAL MEMORY CONTROLLER ADDRESS ------ */ +#define CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR (0xE0082000u) + + /* ------------ CORE/CODE CACHE CONTROLLER ------------ */ +#define CPU_CACHE_KINETIS_PCCCR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x000) +#define CPU_CACHE_KINETIS_PCCLCR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x004) +#define CPU_CACHE_KINETIS_PCCSAR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x008) +#define CPU_CACHE_KINETIS_PCCCVR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x00C) +#define CPU_CACHE_KINETIS_PCCRMR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x020) + + /* ------------- SYSTEM CACHE CONTROLLER -------------- */ +#define CPU_CACHE_KINETIS_PSCCR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x800) +#define CPU_CACHE_KINETIS_PSCLCR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x804) +#define CPU_CACHE_KINETIS_PSCSAR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x808) +#define CPU_CACHE_KINETIS_PSCCVR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x80C) +#define CPU_CACHE_KINETIS_PSCRMR *(CPU_REG32 *)(CPU_CACHE_KINETIS_CONTROLLER_BASE_ADDR + 0x820) + + /* -------------- CACHE CONTROL REGISTER -------------- */ +#define CPU_CACHE_KINETIS_CCR_GO DEF_BIT_31 +#define CPU_CACHE_KINETIS_CCR_PUSHW1 DEF_BIT_27 +#define CPU_CACHE_KINETIS_CCR_INVW1 DEF_BIT_26 +#define CPU_CACHE_KINETIS_CCR_PUSHW0 DEF_BIT_25 +#define CPU_CACHE_KINETIS_CCR_INVW0 DEF_BIT_24 +#define CPU_CACHE_KINETIS_CCR_ENWRBUF DEF_BIT_01 +#define CPU_CACHE_KINETIS_CCR_ENCACHE DEF_BIT_00 + + /* ----------- CACHE LINE CONTROL REGISTER ------------ */ +#define CPU_CACHE_KINETIS_CLCR_LACC DEF_BIT_27 +#define CPU_CACHE_KINETIS_CLCR_LADSEL DEF_BIT_26 +#define CPU_CACHE_KINETIS_CLCR_LCMD_SEARCH_RW DEF_BIT_MASK(0u, 24u) +#define CPU_CACHE_KINETIS_CLCR_LCMD_INV DEF_BIT_MASK(1u, 24u) +#define CPU_CACHE_KINETIS_CLCR_LCMD_PUSH DEF_BIT_MASK(2u, 24u) +#define CPU_CACHE_KINETIS_CLCR_LCMD_CLEAR DEF_BIT_MASK(3u, 24u) +#define CPU_CACHE_KINETIS_CLCR_LCMD_MASK DEF_BIT_FIELD(2u, 24u) +#define CPU_CACHE_KINETIS_CLCR_LCWAY DEF_BIT_22 +#define CPU_CACHE_KINETIS_CLCR_LCIMB DEF_BIT_21 +#define CPU_CACHE_KINETIS_CLCR_LCIVB DEF_BIT_20 +#define CPU_CACHE_KINETIS_CLCR_TDSEL DEF_BIT_16 +#define CPU_CACHE_KINETIS_CLCR_WSEL DEF_BIT_14 +#define CPU_CACHE_KINETIS_CLCR_CACHEADDR_SET(addr) DEF_BIT_MASK((addr), 2u) +#define CPU_CACHE_KINETIS_CLCR_CACHEADDR_MASK DEF_BIT_FIELD(10u, 2u) +#define CPU_CACHE_KINETIS_CLCR_LGO DEF_BIT_00 +#define CPU_CACHE_KINETIS_CLCR_INV_BY_ADDR (CPU_CACHE_KINETIS_CLCR_LADSEL | \ + CPU_CACHE_KINETIS_CLCR_LCMD_INV) +#define CPU_CACHE_KINETIS_CLCR_PUSH_BY_ADDR (CPU_CACHE_KINETIS_CLCR_LADSEL | \ + CPU_CACHE_KINETIS_CLCR_LCMD_PUSH) + + /* ---------- CACHE SEARCH ADDRESS REGISTER ----------- */ +#define CPU_CACHE_KINETIS_CSAR_PHYADDR_SET(addr) DEF_BIT_MASK((addr), 2u) +#define CPU_CACHE_KINETIS_CSAR_PHYADDR_MASK DEF_BIT_FIELD(30u, 2u) +#define CPU_CACHE_KINETIS_CSAR_PHYADDR_SHIFT (2u) +#define CPU_CACHE_KINETIS_CSAR_LGO DEF_BIT_00 + + + /* ----------- CACHE REGIONS MODE REGISTER ------------ */ +#define CPU_CACHE_KINETIS_CCVR_NON_CACHEABLE (0u) +#define CPU_CACHE_KINETIS_CCVR_WRITE_THROUGH (2u) +#define CPU_CACHE_KINETIS_CCVR_WRITE_BACK (3u) +#define CPU_CACHE_KINETIS_CCVR_R0_SET(mode) DEF_BIT_MASK((mode), 30u) +#define CPU_CACHE_KINETIS_CCVR_R0_MASK DEF_BIT_FIELD(2u, 30u) +#define CPU_CACHE_KINETIS_CCVR_R1_SET(mode) DEF_BIT_MASK((mode), 28u) +#define CPU_CACHE_KINETIS_CCVR_R1_MASK DEF_BIT_FIELD(2u, 28u) +#define CPU_CACHE_KINETIS_CCVR_R2_SET(mode) DEF_BIT_MASK((mode), 26u) +#define CPU_CACHE_KINETIS_CCVR_R2_MASK DEF_BIT_FIELD(2u, 26u) +#define CPU_CACHE_KINETIS_CCVR_R3_SET(mode) DEF_BIT_MASK((mode), 24u) +#define CPU_CACHE_KINETIS_CCVR_R3_MASK DEF_BIT_FIELD(2u, 24u) +#define CPU_CACHE_KINETIS_CCVR_R4_SET(mode) DEF_BIT_MASK((mode), 22u) +#define CPU_CACHE_KINETIS_CCVR_R4_MASK DEF_BIT_FIELD(2u, 22u) +#define CPU_CACHE_KINETIS_CCVR_R5_SET(mode) DEF_BIT_MASK((mode), 20u) +#define CPU_CACHE_KINETIS_CCVR_R5_MASK DEF_BIT_FIELD(2u, 20u) +#define CPU_CACHE_KINETIS_CCVR_R6_SET(mode) DEF_BIT_MASK((mode), 18u) +#define CPU_CACHE_KINETIS_CCVR_R6_MASK DEF_BIT_FIELD(2u, 18u) +#define CPU_CACHE_KINETIS_CCVR_R7_SET(mode) DEF_BIT_MASK((mode), 16u) +#define CPU_CACHE_KINETIS_CCVR_R7_MASK DEF_BIT_FIELD(2u, 16u) +#define CPU_CACHE_KINETIS_CCVR_R8_SET(mode) DEF_BIT_MASK((mode), 14u) +#define CPU_CACHE_KINETIS_CCVR_R8_MASK DEF_BIT_FIELD(2u, 14u) +#define CPU_CACHE_KINETIS_CCVR_R9_SET(mode) DEF_BIT_MASK((mode), 12u) +#define CPU_CACHE_KINETIS_CCVR_R9_MASK DEF_BIT_FIELD(2u, 12u) +#define CPU_CACHE_KINETIS_CCVR_R10_SET(mode) DEF_BIT_MASK((mode), 10u) +#define CPU_CACHE_KINETIS_CCVR_R10_MASK DEF_BIT_FIELD(2u, 10u) +#define CPU_CACHE_KINETIS_CCVR_R11_SET(mode) DEF_BIT_MASK((mode), 8u) +#define CPU_CACHE_KINETIS_CCVR_R11_MASK DEF_BIT_FIELD(2u, 8u) +#define CPU_CACHE_KINETIS_CCVR_R12_SET(mode) DEF_BIT_MASK((mode), 6u) +#define CPU_CACHE_KINETIS_CCVR_R12_MASK DEF_BIT_FIELD(2u, 6u) +#define CPU_CACHE_KINETIS_CCVR_R13_SET(mode) DEF_BIT_MASK((mode), 4u) +#define CPU_CACHE_KINETIS_CCVR_R13_MASK DEF_BIT_FIELD(2u, 4u) +#define CPU_CACHE_KINETIS_CCVR_R14_SET(mode) DEF_BIT_MASK((mode), 2u) +#define CPU_CACHE_KINETIS_CCVR_R14_MASK DEF_BIT_FIELD(2u, 2u) +#define CPU_CACHE_KINETIS_CCVR_R15_SET(mode) DEF_BIT_MASK((mode), 0u) +#define CPU_CACHE_KINETIS_CCVR_R15_MASK DEF_BIT_FIELD(2u, 0u) + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_Cache_Do (CPU_INT32U what, + void *addr_start, + CPU_ADDR len); + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_Cache_Init() +* +* Description : Initializes the cache. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init (void) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* ------------ INVALIDATE & ENABLE CACHES ------------ */ + CPU_CACHE_KINETIS_PCCCR = CPU_CACHE_KINETIS_CCR_GO | + CPU_CACHE_KINETIS_CCR_INVW1 | CPU_CACHE_KINETIS_CCR_INVW0 | + CPU_CACHE_KINETIS_CCR_ENWRBUF | CPU_CACHE_KINETIS_CCR_ENCACHE; + + while ((CPU_CACHE_KINETIS_PCCCR & CPU_CACHE_KINETIS_CCR_GO) > 0) { + ; + } + + CPU_CACHE_KINETIS_PSCCR = CPU_CACHE_KINETIS_CCR_GO | + CPU_CACHE_KINETIS_CCR_INVW1 | CPU_CACHE_KINETIS_CCR_INVW0 | + CPU_CACHE_KINETIS_CCR_ENWRBUF | CPU_CACHE_KINETIS_CCR_ENCACHE; + + while ((CPU_CACHE_KINETIS_PSCCR & CPU_CACHE_KINETIS_CCR_GO) > 0) { + ; + } +#endif +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeFlush() +* +* Description : Flushes a range of the data cache to the main memory. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeFlush (void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* Flush range, if found, to main memory */ + CPU_Cache_Do(CPU_CACHE_KINETIS_CLCR_PUSH_BY_ADDR, addr_start, len); +#else + /* Prevent possible compiler warning. */ + (void)&addr_start; + (void)&len; +#endif +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeInv() +* +* Description : Invalidates a range of the data cache. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeInv (void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + /* Invalidate range, if found, in cache */ + CPU_Cache_Do(CPU_CACHE_KINETIS_CLCR_INV_BY_ADDR, addr_start, len); +#else + /* Prevent possible compiler warning. */ + (void)&addr_start; + (void)&len; +#endif +} + + +/* +********************************************************************************************************* +* CPU_Cache_Do() +* +* Description : Does 'what' to range within addr_start and addr_start + len. +* +* Argument(s) : what Cache action to perform: +* +* CPU_CACHE_KINETIS_CLCR_INV_BY_ADDR Invalidate range. +* CPU_CACHE_KINETIS_CLCR_PUSH_BY_ADDR Flush range. +* +* addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Do (CPU_INT32U what, + void *addr_start, + CPU_ADDR len) +{ +#if (defined(CPU_CFG_CACHE_MGMT_EN) && CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + CPU_INT32U addr; + CPU_INT32U start; + CPU_INT32U end; + + + if (len == 0) { + return; + } + /* Smallest addressable cache unit is one 4 byte word. */ + start = ((CPU_INT32U)(addr_start) ) >> CPU_CACHE_KINETIS_CSAR_PHYADDR_SHIFT; + end = ((CPU_INT32U)(addr_start) + len) >> CPU_CACHE_KINETIS_CSAR_PHYADDR_SHIFT; + + /* Set CLCR command to what by Address */ + CPU_CACHE_KINETIS_PSCLCR = what; + + for (addr = start; addr <= end; ++addr) { + /* Flush or invalidate word, if found, to memory */ + CPU_CACHE_KINETIS_PSCSAR = CPU_CACHE_KINETIS_CSAR_PHYADDR_SET(addr) | CPU_CACHE_KINETIS_CSAR_LGO; + + while ((CPU_CACHE_KINETIS_PSCSAR & CPU_CACHE_KINETIS_CSAR_LGO) > 0) { + ; + } + } +#else + /* Prevent possible compiler warning. */ + (void)&what; + (void)&addr_start; + (void)&len; +#endif +} + diff --git a/Cache/NXP/powerpc_e200z4204n3/GNU/cpu_cache_powerpc_e200z4204n3_a.S b/Cache/NXP/powerpc_e200z4204n3/GNU/cpu_cache_powerpc_e200z4204n3_a.S new file mode 100644 index 0000000..54367d0 --- /dev/null +++ b/Cache/NXP/powerpc_e200z4204n3/GNU/cpu_cache_powerpc_e200z4204n3_a.S @@ -0,0 +1,190 @@ +#******************************************************************************************************** +# uC/CPU +# CPU CONFIGURATION & PORT LAYER +# +# Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +# +# SPDX-License-Identifier: APACHE-2.0 +# +# This software is subject to an open source license and is distributed by +# Silicon Laboratories Inc. pursuant to the terms of the Apache License, +# Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +# +#******************************************************************************************************** + +#******************************************************************************************************** +# +# CPU CACHE IMPLEMENTATION +# PowerPC e200z4204n3 +# L1 Cache +# GNU C Compiler +# +# Filename : cpu_cache_powerpc_e200z4204n3.c +# Version : v1.32.00 +#******************************************************************************************************** + + +#******************************************************************************************************** +# PUBLIC FUNCTIONS +#******************************************************************************************************** + + .global CPU_DCache_LineSizeGet + .global CPU_DCache_RangeInv + .global CPU_DCache_RangeFlush + + +#******************************************************************************************************** +# EXTERNS +#******************************************************************************************************** + + .extern CPU_Cache_Linesize + + +#******************************************************************************************************** +# MACROS AND DEFINIITIONS +#******************************************************************************************************** + + .equ L1CFG0, 515 + + +#******************************************************************************************************** +# CODE GENERATION DIRECTIVES +#******************************************************************************************************** + + .section .text + + +#******************************************************************************************************** +# CPU_DCache_LineSizeGet() +# +# Description : Returns the cache line size. +# +# Prototypes : void CPU_DCache_LineSizeGet (void) +# +# Argument(s) : none. +#******************************************************************************************************** + +CPU_DCache_LineSizeGet: + mfspr r0, L1CFG0 # CBSIZE is in L1CFG0[39-40] + e_rlwinm r0, r0, 9, 30, 31 # Move CBSIZE into R0[62-63] and mask other bits to zero + + e_li r3, 32 # Line size is 32 << CBSIZE, 0 <= CBSIZE <= 2 + e_rlw r3, r3, r0 # ... + + se_blr # Return the line size in R3 + + +#******************************************************************************************************** +# INVALIDATE DATA CACHE RANGE +# +# Description : Invalidate a range of data cache. +# +# Prototypes : void CPU_DCache_RangeInv (void *p_mem, +# CPU_SIZE_T range); +# +# Argument(s) : p_mem Start address of the region to invalidate. +# +# range Size of the region to invalidate in bytes. +# +# Note(s) : none. +#******************************************************************************************************** + +CPU_DCache_RangeInv: + e_cmp16i r4, 0 # If the range is 0, do nothing + e_beq InvReturn # ... + + mfmsr r0 # Save MSR and disable interrupts + wrteei 0 + sync # Complete data operations before invalidation + + e_lis r11, CPU_Cache_Linesize@ha # Store the line size into R11 + e_lwz r11, CPU_Cache_Linesize@l(r11) # ... + + neg r12, r11 # The line size is a power of 2; form a mask for the lower bits + + neg r4, r4 # Pad the range so it is a multiple of the line size + and r4, r4, r12 # ... + neg. r4, r4 # Check if the result underflowed + e_bne InvRangeNotOV # If it did not, we are finished with the range + + e_or2is r4, 0xFFFF # Otherwise, Set the maximum range, aligned to the line size. + e_or2i r4, 0xFFFF # ... + and r4, r4, r12 # ... + +InvRangeNotOV: + and r3, r3, r12 # Align the address to the start of the cache line + + xor r12, r12, r12 # R12 will count how much memory has been invalidated +InvLine: + cmpw r12, r4 # Have we invalidated the entire range? + e_beq InvEnd # If so, we can return + + dcbf r3, r12 # Invalidate the cache line + + add r12, r12, r11 # Move to the next cache line + se_b InvLine # ... + +InvEnd: + sync + wrtee r0 # Restore MSR + +InvReturn: + se_blr + + +#******************************************************************************************************** +# FLUSH DATA CACHE RANGE +# +# Description : Flush (clean) a range of data cache. +# +# Prototypes : void CPU_DCache_RangeFlush (void *p_mem, +# CPU_SIZE_T range) +# +# Argument(s) : p_mem Start address of the region to flush. +# +# range Size of the region to invalidate in bytes. +# +# Note(s) : none. +#******************************************************************************************************** + +CPU_DCache_RangeFlush: + e_cmp16i r4, 0 # If the range is 0, do nothing + e_beq FlushReturn # ... + + mfmsr r0 # Save MSR and disable interrupts + wrteei 0 + sync # Complete data operations before clean + + e_lis r11, CPU_Cache_Linesize@ha # Store the line size into R11 + e_lwz r11, CPU_Cache_Linesize@l(r11) # ... + + neg r12, r11 # The line size is a power of 2; form a mask for the lower bits + + neg r4, r4 # Pad the range so it is a multiple of the line size + and r4, r4, r12 # ... + neg. r4, r4 # Check if the result underflowed + e_bne FlushRangeNotOV # If it did not, we are finished with the range + + e_or2is r4, 0xFFFF # Otherwise, Set the maximum range, aligned to the line size. + e_or2i r4, 0xFFFF # ... + and r4, r4, r12 # ... + +FlushRangeNotOV: + and r3, r3, r12 # Align the address to the start of the cache line + + xor r12, r12, r12 # R12 will count how much memory has been cleaned +FlushLine: + cmpw r12, r4 # Have we cleaned the entire range? + e_beq FlushEnd # If so, we can return + + dcbst r3, r12 # Clean the cache line + + add r12, r12, r11 # Move to the next cache line + se_b FlushLine # ... + +FlushEnd: + sync + wrtee r0 # Restore MSR + +FlushReturn: + se_blr diff --git a/Cache/NXP/powerpc_e200z4204n3/cpu_cache_powerpc_e200z4204n3.c b/Cache/NXP/powerpc_e200z4204n3/cpu_cache_powerpc_e200z4204n3.c new file mode 100644 index 0000000..a803d28 --- /dev/null +++ b/Cache/NXP/powerpc_e200z4204n3/cpu_cache_powerpc_e200z4204n3.c @@ -0,0 +1,83 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* PowerPC e200z4204n3 +* L1 Cache +* +* Filename : cpu_cache_powerpc_e200z4204n3.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ +#include +#include "../../../cpu_cache.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* EXTERNAL DECLARATIONS +********************************************************************************************************* +*/ + +CPU_INT32U CPU_DCache_LineSizeGet(void); + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_Cache_Linesize; /* Cache line size. */ + + +/* +********************************************************************************************************* +* CPU_CacheMGMTInit() +* +* Description : Initialize cpu cache module. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_Cache_Init(void) +{ + CPU_Cache_Linesize = CPU_DCache_LineSizeGet(); +} + +#ifdef __cplusplus +} +#endif diff --git a/Cache/NiosII/cpu_cache_niosII.c b/Cache/NiosII/cpu_cache_niosII.c new file mode 100644 index 0000000..40e63d5 --- /dev/null +++ b/Cache/NiosII/cpu_cache_niosII.c @@ -0,0 +1,160 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* +* CPU CACHE IMPLEMENTATION +* +* Altera Nios II +* +* Filename : cpu_cache_niosII.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#define NIOSII_CACHE_MODULE +#include + +#include +#include + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_Cache_Init() +* +* Description : Initializes the data and instruction caches of the Nios II. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : The Nios-II cache(s) are initialized before main() is called by the Altera HAL. +********************************************************************************************************* +*/ + +void CPU_Cache_Init (void) +{ + +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeFlush() +* +* Description : Flushes a range of the data cache. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeFlush (void *addr_start, + CPU_ADDR len) +{ + alt_dcache_flush(addr_start, len); +} + + +/* +********************************************************************************************************* +* CPU_DCache_RangeInv() +* +* Description : Invalidates a range of the data cache. +* +* Argument(s) : addr_start Byte address of the beginning of the range. +* +* len Size in bytes of the range. +* +* Return(s) : none. +* +* Note(s) : The Nios-II CPU doesn't support clearing the cache in two steps, i.e. invalidate then +* flush. The flush instruction invalidates the cache line before flushing it. +********************************************************************************************************* +*/ + +void CPU_DCache_RangeInv (void *addr_start, + CPU_ADDR len) +{ + (void)&addr_start; /* Prevent possible 'variable unused' warning. */ + (void)&len; /* Prevent possible 'variable unused' warning. */ +} + diff --git a/Cfg/Template/cpu_cfg.h b/Cfg/Template/cpu_cfg.h new file mode 100644 index 0000000..a267d8d --- /dev/null +++ b/Cfg/Template/cpu_cfg.h @@ -0,0 +1,254 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION FILE +* +* TEMPLATE +* +* Filename : cpu_cfg.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_MODULE_PRESENT +#define CPU_CFG_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU NAME CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_NAME_EN to enable/disable CPU host name feature : +* +* (a) CPU host name storage +* (b) CPU host name API functions +* +* (2) Configure CPU_CFG_NAME_SIZE with the desired ASCII string size of the CPU host name, +* including the terminating NULL character. +* +* See also 'cpu_core.h GLOBAL VARIABLES Note #1'. +********************************************************************************************************* +*/ + + /* Configure CPU host name feature (see Note #1) : */ +#define CPU_CFG_NAME_EN DEF_DISABLED + /* DEF_DISABLED CPU host name DISABLED */ + /* DEF_ENABLED CPU host name ENABLED */ + + /* Configure CPU host name ASCII string size ... */ +#define CPU_CFG_NAME_SIZE 16 /* ... (see Note #2). */ + + +/* +********************************************************************************************************* +* CPU TIMESTAMP CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_TS_xx_EN to enable/disable CPU timestamp features : +* +* (a) CPU_CFG_TS_32_EN enable/disable 32-bit CPU timestamp feature +* (b) CPU_CFG_TS_64_EN enable/disable 64-bit CPU timestamp feature +* +* (2) (a) Configure CPU_CFG_TS_TMR_SIZE with the CPU timestamp timer's word size : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (b) If the size of the CPU timestamp timer is not a binary multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple octet word +* size SHOULD be configured (e.g. to 16-bits). However, the minimum supported word +* size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'. +********************************************************************************************************* +*/ + + /* Configure CPU timestamp features (see Note #1) : */ +#define CPU_CFG_TS_32_EN DEF_DISABLED +#define CPU_CFG_TS_64_EN DEF_DISABLED + /* DEF_DISABLED CPU timestamps DISABLED */ + /* DEF_ENABLED CPU timestamps ENABLED */ + + /* Configure CPU timestamp timer word size ... */ + /* ... (see Note #2) : */ +#define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32 + + +/* +********************************************************************************************************* +* CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_INT_DIS_MEAS_EN to enable/disable measuring CPU's interrupts +* disabled time : +* +* (a) Enabled, if CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h' +* +* (b) Disabled, if CPU_CFG_INT_DIS_MEAS_EN NOT #define'd in 'cpu_cfg.h' +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #1'. +* +* (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure & +* average the interrupts disabled time measurements overhead. +* +* See also 'cpu_core.c CPU_IntDisMeasInit() Note #3a'. +********************************************************************************************************* +*/ + +#if 0 /* Configure CPU interrupts disabled time ... */ +#define CPU_CFG_INT_DIS_MEAS_EN /* ... measurements feature (see Note #1a). */ +#endif + + /* Configure number of interrupts disabled overhead ... */ +#define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... time measurements (see Note #1b). */ + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 0 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* CPU ENDIAN TYPE OVERRIDE +* +* Note(s) : (1) Configure CPU_CFG_ENDIAN_TYPE to override the default CPU endian type defined in cpu.h. +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (2) Defining CPU_CFG_ENDIAN_TYPE here is only valid for supported bi-endian architectures. +* See 'cpu.h CPU WORD CONFIGURATION Note #3' for details +********************************************************************************************************* +*/ + +#if 0 +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CACHE MANAGEMENT +* +* Note(s) : (1) Configure CPU_CFG_CACHE_MGMT_EN to enable the cache management API. +* +* (2) This option only enables the cache management functions. +* It does not enable any hardware caches, which should be configured in startup code. +* Caches must be configured and enabled by the time CPU_Init() is called. +* +* (3) This option is usually required for device drivers which use a DMA engine to transmit +* buffers that are located in cached memory. +********************************************************************************************************* +*/ + +#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED /* Defines CPU data word-memory order (see Note #1). */ + + +/* +********************************************************************************************************* +* KERNEL AWARE IPL BOUNDARY +* +* Note(s) : (1) Determines the IPL level that establishes the boundary for ISRs that are kernel-aware and +* those that are not. All ISRs at this level or lower are kernel-aware. +* +* (2) ARMv7-M: Since the port is using BASEPRI to separate kernel vs non-kernel aware ISR, please +* make sure your external interrupt priorities are set accordingly. For example, if +* CPU_CFG_KA_IPL_BOUNDARY is set to 4 then external interrupt priorities 4-15 will be kernel +* aware while priorities 0-3 will be use as non-kernel aware. +********************************************************************************************************* +*/ + +#define CPU_CFG_KA_IPL_BOUNDARY 4u + + +/* +********************************************************************************************************* +* ARM CORTEX-M +* +* Note(s) : (1) Determines the interrupt programmable priority levels. This is normally specified in the +* Microcontroller reference manual. 4-bits gives us 16 programmable priority levels. +* +* Example 1 Example 2 +* NVIC_IPRx NVIC_IPRx +* 7 0 7 0 +* +------------------+ +------------------+ +* | PRIO | | PRIO | +* +------------------+ +------------------+ +* +* Bits[7:4] Priority mask bits Bits[7:6] Priority mask bits +* Bits[3:0] Reserved Bits[5:0] Reserved +* +* Example 1: CPU_CFG_NVIC_PRIO_BITS should be set to 4 due to the processor +* implementing only bits[7:4]. +* +* Example 2: CPU_CFG_NVIC_PRIO_BITS should be set to 2 due to the processor +* implementing only bits[7:6]. +********************************************************************************************************* +*/ +#if 0 +#define CPU_CFG_NVIC_PRIO_BITS 4u +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of CPU cfg module include. */ + diff --git a/ColdFire/Generic/CW_For_Microcontrollers/cpu.h b/ColdFire/Generic/CW_For_Microcontrollers/cpu.h new file mode 100644 index 0000000..41972b2 --- /dev/null +++ b/ColdFire/Generic/CW_For_Microcontrollers/cpu.h @@ -0,0 +1,493 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* CW for Microcontrollers +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_VectInit (CPU_INT32U vbr); + +void *CPU_VectGet (CPU_INT16U vect); +void CPU_VectSet (CPU_INT16U vect, + void (*vect_addr)(void)); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ColdFire/Generic/CW_For_Microcontrollers/cpu_a.asm b/ColdFire/Generic/CW_For_Microcontrollers/cpu_a.asm new file mode 100644 index 0000000..15f4c4d --- /dev/null +++ b/ColdFire/Generic/CW_For_Microcontrollers/cpu_a.asm @@ -0,0 +1,132 @@ +/* +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** +*/ + +/* +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ColdFire +; CW for Microcontrollers +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +*/ + +/* +;******************************************************************************************************** +; PUBLIC DECLARATIONS +;******************************************************************************************************** +*/ + + .global _CPU_VectInit + + .global _CPU_SR_Save + .global _CPU_SR_Restore + +/* +;******************************************************************************************************** +; EXTERNAL DECLARATIONS +;******************************************************************************************************** +*/ + + .extern _CPU_VBR_Ptr + .text + +/* +;******************************************************************************************************** +; VECTOR BASE REGISTER INITIALIZATION +; +; Description : This function is called to set the Vector Base Register to the value specified in +; the function argument. +; +; Argument(s) : VBR Desired vector base address. +; +; Return(s) : none. +; +; Note(s) : 'CPU_VBR_Ptr' keeps the current vector base address. +;******************************************************************************************************** +*/ + +_CPU_VectInit: + + MOVE.L D0,-(A7) /* Save D0 */ + MOVE.L 8(A7),D0 /* Retrieve 'vbr' parameter from stack */ + MOVE.L D0,_CPU_VBR_Ptr /* Save 'vbr' into CPU_VBR_Ptr */ + MOVEC D0,VBR + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Save() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #3 function to preserve the state of the +; interrupt disable flag in order to be able to restore it later. +; +; Argument(s) : none. +; +; Return(s) : It is assumed that the return value is placed in the D0 register as expected by the +; compiler. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +_CPU_SR_Save: + + MOVE.W SR,D0 /* Copy SR into D0 */ + MOVE.L D0,-(A7) /* Save D0 */ + ORI.L #0x0700,D0 /* Disable interrupts */ + MOVE.W D0,SR /* Restore SR state with interrupts disabled */ + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Restore() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #function to restore the state of the +; interrupt flag. +; +; Argument(s) : cpu_sr Contents of the SR to restore. It is assumed that 'cpu_sr' is passed in the stack. +; +; Return(s) : none. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +_CPU_SR_Restore: + + MOVE.L D0,-(A7) /* Save D0 */ + MOVE.W 10(A7),D0 /* Retrieve cpu_sr parameter from stack */ + MOVE.W D0,SR /* Restore SR previous state */ + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** +*/ + + .end + diff --git a/ColdFire/Generic/CW_For_Microcontrollers/cpu_c.c b/ColdFire/Generic/CW_For_Microcontrollers/cpu_c.c new file mode 100644 index 0000000..d151d8b --- /dev/null +++ b/ColdFire/Generic/CW_For_Microcontrollers/cpu_c.c @@ -0,0 +1,116 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* CW for Microcontrollers +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_VBR_Ptr; + + +/* +********************************************************************************************************* +* CPU_VectGet() +* GET ISR VECTOR +* +* Description : This function is called to get the address of the exception handler specified by 'vect'. +* +* Argument(s) : vect Vector number to retrieve handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void *CPU_VectGet (CPU_INT16U vect) +{ + CPU_ADDR addr; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + addr = *(CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + CPU_CRITICAL_EXIT(); + + return ((void *)addr); +} + + +/* +********************************************************************************************************* +* CPU_VectSet() +* SET ISR VECTOR +* +* Description : This function is called to set the contents of an exception vector. The function assumes +* that the VBR (Vector Base Register) is set to 0x00000000. +* +* Argument(s) : vect is the vector number. +* +* addr is the address of the ISR handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void CPU_VectSet (CPU_INT16U vect, void (*vect_addr)(void)) +{ + CPU_ADDR *pvect; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + pvect = (CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + *pvect = (CPU_ADDR ) vect_addr; + CPU_CRITICAL_EXIT(); +} + +#ifdef __cplusplus +} +#endif diff --git a/ColdFire/Generic/Codewarrior/cpu.h b/ColdFire/Generic/Codewarrior/cpu.h new file mode 100644 index 0000000..e27facd --- /dev/null +++ b/ColdFire/Generic/Codewarrior/cpu.h @@ -0,0 +1,500 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* Codewarrior +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) The new version of CodeWarrior (7.2) requires to force the prototypes to the standard ABI +* by using #pragma 'standard_abi'. +********************************************************************************************************* +*/ + +#if ((defined(__CWCC__)) && (__CWCC__ >= 0x72)) +#pragma standard_abi /* See Note #1. */ +#endif + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_VectInit (CPU_INT32U vbr); + +void *CPU_VectGet (CPU_INT16U vect); +void CPU_VectSet (CPU_INT16U vect, + void (*vect_addr)(void)); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ColdFire/Generic/Codewarrior/cpu_a.asm b/ColdFire/Generic/Codewarrior/cpu_a.asm new file mode 100644 index 0000000..9592025 --- /dev/null +++ b/ColdFire/Generic/Codewarrior/cpu_a.asm @@ -0,0 +1,130 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ColdFire +; Codewarrior +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + + +;******************************************************************************************************** +; PUBLIC DECLARATIONS +;******************************************************************************************************** + + + .global _CPU_VectInit + + .global _CPU_SR_Save + .global _CPU_SR_Restore + + +;******************************************************************************************************** +; EXTERNAL DECLARATIONS +;******************************************************************************************************** + + + .extern _CPU_VBR_Ptr + .text + +/* +;******************************************************************************************************** +; VECTOR BASE REGISTER INITIALIZATION +; +; Description : This function is called to set the Vector Base Register to the value specified in +; the function argument. +; +; Argument(s) : VBR Desired vector base address. +; +; Return(s) : none. +; +; Note(s) : 'CPU_VBR_Ptr' keeps the current vector base address. +;******************************************************************************************************** +*/ + +_CPU_VectInit: + + MOVE.L D0,-(A7) /* Save D0 */ + MOVE.L 8(A7),D0 /* Retrieve 'vbr' parameter from stack */ + MOVE.L D0,_CPU_VBR_Ptr /* Save 'vbr' into CPU_VBR_Ptr */ + MOVEC D0,VBR + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Save() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #3 function to preserve the state of the +; interrupt disable flag in order to be able to restore it later. +; +; Argument(s) : none. +; +; Return(s) : It is assumed that the return value is placed in the D0 register as expected by the +; compiler. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +_CPU_SR_Save: + + MOVE.W SR,D0 /* Copy SR into D0 */ + MOVE.L D0,-(A7) /* Save D0 */ + ORI.L #0x0700,D0 /* Disable interrupts */ + MOVE.W D0,SR /* Restore SR state with interrupts disabled */ + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Restore() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #function to restore the state of the +; interrupt flag. +; +; Argument(s) : cpu_sr Contents of the SR to restore. It is assumed that 'cpu_sr' is passed in the stack. +; +; Return(s) : none. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +_CPU_SR_Restore: + + MOVE.L D0,-(A7) /* Save D0 */ + MOVE.W 10(A7),D0 /* Retrieve cpu_sr parameter from stack */ + MOVE.W D0,SR /* Restore SR previous state */ + MOVE.L (A7)+,D0 /* Restore D0 */ + RTS + + +/* +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** +*/ + + .end + diff --git a/ColdFire/Generic/Codewarrior/cpu_c.c b/ColdFire/Generic/Codewarrior/cpu_c.c new file mode 100644 index 0000000..7a823c0 --- /dev/null +++ b/ColdFire/Generic/Codewarrior/cpu_c.c @@ -0,0 +1,117 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* Codewarrior +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_VBR_Ptr; + + +/* +********************************************************************************************************* +* CPU_VectGet() +* GET ISR VECTOR +* +* Description : This function is called to get the address of the exception handler specified by 'vect'. +* +* Argument(s) : vect Vector number to retrieve handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void *CPU_VectGet (CPU_INT16U vect) +{ + CPU_ADDR addr; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + addr = *(CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + CPU_CRITICAL_EXIT(); + + return ((void *)addr); +} + + +/* +********************************************************************************************************* +* CPU_VectSet() +* SET ISR VECTOR +* +* Description : This function is called to set the contents of an exception vector. The function assumes +* that the VBR (Vector Base Register) is set to 0x00000000. +* +* Argument(s) : vect is the vector number. +* +* addr is the address of the ISR handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void CPU_VectSet (CPU_INT16U vect, void (*vect_addr)(void)) +{ + CPU_ADDR *pvect; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + pvect = (CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + *pvect = (CPU_ADDR ) vect_addr; + CPU_CRITICAL_EXIT(); +} + +#ifdef __cplusplus +} +#endif + diff --git a/ColdFire/Generic/IAR/cpu.h b/ColdFire/Generic/IAR/cpu.h new file mode 100644 index 0000000..16e40a5 --- /dev/null +++ b/ColdFire/Generic/IAR/cpu.h @@ -0,0 +1,493 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_VectInit (CPU_INT32U vbr); + +void *CPU_VectGet (CPU_INT16U vect); +void CPU_VectSet (CPU_INT16U vect, + void (*vect_addr)(void)); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/ColdFire/Generic/IAR/cpu_a.asm b/ColdFire/Generic/IAR/cpu_a.asm new file mode 100644 index 0000000..a288fc7 --- /dev/null +++ b/ColdFire/Generic/IAR/cpu_a.asm @@ -0,0 +1,124 @@ +/* +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** +*/ + +/* +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ColdFire +; IAR C Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** +*/ + +/* +;******************************************************************************************************** +; PUBLIC DECLARATIONS +;******************************************************************************************************** +*/ + + PUBLIC CPU_VectInit + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + +/* +;******************************************************************************************************** +; EXTERNAL DECLARATIONS +;******************************************************************************************************** +*/ + + EXTERN CPU_VBR_Ptr + + RSEG CODE:CODE:NOROOT(2) /* Align to power 2, 4 bytes. */ + +/* +;******************************************************************************************************** +; VECTOR BASE REGISTER INITIALIZATION +; +; Description : This function is called to set the Vector Base Register to the value specified in +; the function argument. +; +; Argument(s) : VBR Desired vector base address. +; +; Return(s) : none. +; +; Note(s) : (1) 'CPU_VBR_Ptr' keeps the current vector base address. +; +; (2) 'VBR' parameter is assumed to be passed on D0 by the compiler. +;******************************************************************************************************** +*/ + +CPU_VectInit: + MOVE.L D0, (CPU_VBR_Ptr) /* Save 'vbr' into CPU_VBR_Ptr */ + MOVEC D0, VBR + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Save() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #3 function to preserve the state of the +; interrupt disable flag in order to be able to restore it later. +; +; Argument(s) : none. +; +; Return(s) : It is assumed that the return value is placed in the D0 register as expected by the +; compiler. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +CPU_SR_Save: + MOVE.W SR, D0 /* Copy SR into D0 */ + MOVE.W D0, D1 + ORI.L #0x0700, D1 /* Disable interrupts */ + MOVE.W D1, SR /* Restore SR state with interrupts disabled */ + RTS + + +/* +;******************************************************************************************************** +; CPU_SR_Restore() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #function to restore the state of the +; interrupt flag. +; +; Argument(s) : cpu_sr Contents of the SR to restore. It is assumed that 'cpu_sr' is passed in D0. +; +; Return(s) : none. +; +; Note(s) : none. +;******************************************************************************************************** +*/ + +CPU_SR_Restore: + MOVE.W D0, SR /* Restore SR previous state */ + RTS + + +/* +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** +*/ + + END diff --git a/ColdFire/Generic/IAR/cpu_c.c b/ColdFire/Generic/IAR/cpu_c.c new file mode 100644 index 0000000..c916e78 --- /dev/null +++ b/ColdFire/Generic/IAR/cpu_c.c @@ -0,0 +1,116 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ColdFire +* IAR C Compiler +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U CPU_VBR_Ptr; + + +/* +********************************************************************************************************* +* CPU_VectGet() +* GET ISR VECTOR +* +* Description : This function is called to get the address of the exception handler specified by 'vect'. +* +* Argument(s) : vect Vector number to retrieve handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void *CPU_VectGet (CPU_INT16U vect) +{ + CPU_ADDR addr; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + addr = *(CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + CPU_CRITICAL_EXIT(); + + return ((void *)addr); +} + + +/* +********************************************************************************************************* +* CPU_VectSet() +* SET ISR VECTOR +* +* Description : This function is called to set the contents of an exception vector. The function assumes +* that the VBR (Vector Base Register) is set to 0x00000000. +* +* Argument(s) : vect is the vector number. +* +* addr is the address of the ISR handler. +* +* Return(s) : none. +* +* Note(s) : (1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ + +void CPU_VectSet (CPU_INT16U vect, void (*vect_addr)(void)) +{ + CPU_ADDR *pvect; + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + pvect = (CPU_ADDR *)(CPU_VBR_Ptr + (CPU_INT16U)vect * 4); + *pvect = (CPU_ADDR ) vect_addr; + CPU_CRITICAL_EXIT(); +} + +#ifdef __cplusplus +} +#endif diff --git a/EnSilica/eSi-3250/EDS/cpu.h b/EnSilica/eSi-3250/EDS/cpu.h new file mode 100644 index 0000000..263f548 --- /dev/null +++ b/EnSilica/eSi-3250/EDS/cpu.h @@ -0,0 +1,541 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* EnSilica eSi-3250 +* GNU C Compiler +* +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 1 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_IntSrcDis (CPU_INT08U src); /* Disable specific interrupt source. */ +void CPU_IntSrcEn (CPU_INT08U src); /* Enable specific interrupt source. */ +void CPU_IntSrcPendClr(CPU_INT08U src); /* Clear specific pending interrupt. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore (CPU_SR cpu_sr); /* Restore CPU status word. */ + +CPU_DATA CPU_RevBits (CPU_DATA val); /* Reverse the bits in a data value. */ + +CPU_DATA CPU_GetEID (void); /* Get Exception ID register. */ +CPU_DATA CPU_GetGP (void); /* Get Global Displacement pointer. */ +CPU_DATA CPU_GetTC (void); /* Get Thread Control register. */ + + +/* +********************************************************************************************************* +* INTERRUPT COUNT +********************************************************************************************************* +*/ + +#define CPU_INT_NBR (8+__interrupts__) +#define CPU_INT_INT0 8u + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/EnSilica/eSi-3250/EDS/cpu_a.S b/EnSilica/eSi-3250/EDS/cpu_a.S new file mode 100644 index 0000000..964b653 --- /dev/null +++ b/EnSilica/eSi-3250/EDS/cpu_a.S @@ -0,0 +1,379 @@ +#******************************************************************************************************** +# uC/CPU +# CPU CONFIGURATION & PORT LAYER +# +# Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +# +# SPDX-License-Identifier: APACHE-2.0 +# +# This software is subject to an open source license and is distributed by +# Silicon Laboratories Inc. pursuant to the terms of the Apache License, +# Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +# +#******************************************************************************************************** + +#******************************************************************************************************** +# +# CPU PORT FILE +# +# EnSilica eSi-32nn +# GNU C Compiler +# +# +# Filename : cpu_a.S +# Version : v1.32.00 +#******************************************************************************************************** + + +#******************************************************************************************************** +# PUBLIC FUNCTIONS +#******************************************************************************************************** + + .global CPU_IntDis /* Disable interrupts. */ + .global CPU_IntEn /* Enable interrupts. */ + + .global CPU_IntSrcDis /* Disable specific interrupt source. */ + .global CPU_IntSrcEn /* Enable specific interrupt source. */ + .global CPU_IntSrcPendClr /* Clear specific pending interrupt. */ + + .global CPU_SR_Save /* Save CPU status word & disable interrupts. */ + .global CPU_SR_Restore /* Restore CPU status word. */ + + .global CPU_CntLeadZeros /* Count leading zeros. */ + + .global CPU_RevBits /* Reverse the bits in a data value. */ + + .global CPU_GetEID /* Get Exception ID register. */ + .global CPU_GetGP /* Get Global Displacement pointer. */ + .global CPU_GetTC /* Get Thread Control register. */ + + .global CPU_TS_TmrInit /* Initialize & start CPU timestamp timer. */ + .global CPU_TS_TmrRd /* Get current CPU timestamp timer count value. */ + + +#******************************************************************************************************** +# EXTERNAL GLOBAL VARIABLES +#******************************************************************************************************** + + .extern CPU_TS_TmrFreq_Hz /* CPU timestamp timer frequency (in Hz). */ + + +#******************************************************************************************************** +# CODE GENERATION DIRECTIVES +#******************************************************************************************************** + + .text + + +#******************************************************************************************************** +# DISABLE and ENABLE INTERRUPTS +# +# Description : Disable/Enable interrupts. +# +# Prototypes : void CPU_IntDis(void); +# void CPU_IntEn (void); +#******************************************************************************************************** + .type CPU_IntDis, @function +CPU_IntDis: + DISABLE arg0 + RET + + .type CPU_IntEn, @function +CPU_IntEn: + ENABLE + RET + + +#******************************************************************************************************** +# CPU INTERRUPT SOURCE DISABLE/ENABLE +# +# Description : Disable/Enable an interrupt source. +# +# Prototypes : void CPU_IntSrcDis(CPU_INT08U src); +# void CPU_IntSrcEn (CPU_INT08U src); +# +# Note(s) : (1) The numbering scheme used to identify interrupts is the index defined in Table 58 of +# 'eSi-RISC Architecture Manual'. +#******************************************************************************************************** + + .type CPU_IntSrcDis, @function +CPU_IntSrcDis: + CMP arg0, 8 + BLU 1f + CMP arg0, __interrupts__+8 + BGE 1f + ADD arg0, -8 + L arg1, 1 + SL arg1, arg0 + RCSR arg0, Interrupt, IM + ANDNOT arg0, arg1 + WCSR Interrupt, IM, arg0 +1: + RET + + .type CPU_IntSrcEn, @function +CPU_IntSrcEn: + CMP arg0, 8 + BLU 1f + CMP arg0, __interrupts__+8 + BGE 1f + ADD arg0, -8 + L arg1, 1 + SL arg1, arg0 + RCSR arg0, Interrupt, IM + OR arg0, arg1 + WCSR Interrupt, IM, arg0 +1: + RET + + +#******************************************************************************************************** +# CPU INTERRUPT SOURCE PEND CLEAR +# +# Description : Acknowledge, or clear the pending status, of an interrupt. +# +# Prototype : void CPU_IntSrcPendClr(CPU_INT08U src); +# +# Note(s) : (1) The numbering scheme used to identify interrupts is the index defined in Table 58 of +# 'eSi-RISC Architecture Manual'. +#******************************************************************************************************** + + .type CPU_IntSrcPendClr, @function +CPU_IntSrcPendClr: + CMP arg0, 8 + BLU 1f + CMP arg0, __interrupts__+8 + BGE 1f + ADD arg0, -8 + L arg1, 1 + SL arg1, arg0 + WCSR Interrupt, IA, arg1 +1: + RET + + +#******************************************************************************************************** +# CRITICAL SECTION FUNCTIONS +# +# Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +# state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +# are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +# The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +# +# Prototypes : CPU_SR CPU_SR_Save (void); +# void CPU_SR_Restore(CPU_SR cpu_sr); +# +# Note(s) : (1) These functions are used in general like this : +# +# void Task (void *p_arg) +# { +# CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +# : +# : +# CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +# : +# : +# CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +# : +# } +#******************************************************************************************************** + + .type CPU_SR_Save, @function +CPU_SR_Save: + DISABLE arg0 + RET + + .type CPU_SR_Restore, @function +CPU_SR_Restore: + RESTORE arg0 + RET + + +#******************************************************************************************************** +# CPU_CntLeadZeros() +# COUNT LEADING ZEROS +# +# Description : Counts the number of contiguous, most-significant, leading zero bits before the +# first binary one bit in a data value. +# +# Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +# +# Argument(s) : val Data value to count leading zero bits. +# +# Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +# +# Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h +# CPU WORD CONFIGURATION Note #1'). +# +# (b) For 32-bit values : +# +# b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +# --- --- --- --- --- --- --- --- --------------- +# 1 x x x x x x x 0 +# 0 1 x x x x x x 1 +# 0 0 1 x x x x x 2 +# : : : : : : : : : +# : : : : : : : : : +# 0 0 0 1 x x x x 27 +# 0 0 0 0 1 x x x 28 +# 0 0 0 0 0 1 x x 29 +# 0 0 0 0 0 0 1 x 30 +# 0 0 0 0 0 0 0 1 31 +# 0 0 0 0 0 0 0 0 32 +# +# +# (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +# #define'd in 'cpu_cfg.h' or 'cpu.h'. +#******************************************************************************************************** + + .type CPU_CntLeadZeros, @function +CPU_CntLeadZeros: + CLZ arg0, arg0 + RET + + +#******************************************************************************************************** +# CPU_RevBits() +# REVERSE BITS +# +# Description : Reverses the bits in a data value. +# +# Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +# +# Argument(s) : val Data value to reverse bits. +# +# Return(s) : Value with all bits in 'val' reversed (see Note #1). +# +# Note(s) : (1) The final, reversed data value for 'val' is such that : +# +# 'val's final bit 0 = 'val's original bit N +# 'val's final bit 1 = 'val's original bit (N - 1) +# 'val's final bit 2 = 'val's original bit (N - 2) +# +# ... ... +# +# 'val's final bit (N - 2) = 'val's original bit 2 +# 'val's final bit (N - 1) = 'val's original bit 1 +# 'val's final bit N = 'val's original bit 0 +#******************************************************************************************************** + + .type CPU_RevBits, @function +CPU_RevBits: + REV arg0, arg0 + RET + + +#******************************************************************************************************** +# CPU_GetEID() +# +# Description : Read the EID CSR. +# +# Prototypes : CPU_DATA CPU_GetEID(void); +# +# Argument(s) : none. +# +# Return(s) : Value of the EID CSR the Thread bank. +# +# Note(s) : none. +#******************************************************************************************************** + + .type CPU_GetEID, @function +CPU_GetEID: + RCSR arg0, Thread, EID + RET + + +#******************************************************************************************************** +# CPU_GetGP() +# +# Description : Get the Global Displacement pointer. +# +# Prototypes : CPU_DATA CPU_GetGP(void); +# +# Argument(s) : none. +# +# Return(s) : Value of the gp (r31) register. +# +# Note(s) : none. +#******************************************************************************************************** + + .type CPU_GetGP, @function +CPU_GetGP: + MV arg0, gp + RET + + +#******************************************************************************************************** +# CPU_GetTC() +# +# Description : Get the Thread Control CSR. +# +# Prototypes : CPU_DATA CPU_GetTC(void); +# +# Argument(s) : none. +# +# Return(s) : Value of the TC CSR the Thread bank. +# +# Note(s) : none. +#******************************************************************************************************** + + .type CPU_GetTC, @function +CPU_GetTC: + RCSR arg0, Thread, TC + RET + + +#******************************************************************************************************** +# CPU_TS_TmrInit() +# +# Description : Initialize & start CPU timestamp timer. +# +# Prototypes : void CPU_TS_TmrInit(void); +# +# Argument(s) : none. +# +# Return(s) : none. +# +# Note(s) : none. +#******************************************************************************************************** + + .type CPU_TS_TmrInit, @function +CPU_TS_TmrInit: + L arg0, 0 + NOT arg0, arg0 + WCSR CycleCounter, Wrap, arg0 + RCSR arg0, Configuration, FREQ0 + RCSR arg1, Configuration, FREQ1 + SL arg1, 16 + OR arg0, arg1 + L arg1, (gp+[CPU_TS_TmrFreq_Hz]) + SW (arg1), arg0 + RET + + +#******************************************************************************************************** +# CPU_TS_TmrRd() +# +# Description : Get current CPU timestamp timer count value. +# +# Prototypes : CPU_TS_TMR CPU_TS_TmrRd(void); +# +# Argument(s) : none. +# +# Return(s) : Timestamp timer count. +# +# Note(s) : none. +#******************************************************************************************************** + + .type CPU_TS_TmrRd, @function +CPU_TS_TmrRd: + RCSR arg0, CycleCounter, Cnt + RET + + +#******************************************************************************************************** +# CPU ASSEMBLY PORT FILE END +#******************************************************************************************************** + +.end + diff --git a/EnSilica/eSi-3250/EDS/cpu_c.c b/EnSilica/eSi-3250/EDS/cpu_c.c new file mode 100644 index 0000000..c87f847 --- /dev/null +++ b/EnSilica/eSi-3250/EDS/cpu_c.c @@ -0,0 +1,174 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* EnSilica eSi-3250 +* GNU C Compiler +* +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + +#define CPU_USECS_PER_SEC (1000000ULL) + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_TSxx_to_uSec() +* +* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds. +* +* Argument(s) : ts_cnts CPU timestamp (in timestamp timer counts [see Note #2aA]). +* +* Return(s) : Converted CPU timestamp (in microseconds [see Note #2aD]). +* +* Note(s) : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be +* optionally defined by the developer when either of the following CPU features is +* enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) The amount of time measured by CPU timestamps is calculated by either of +* the following equations : +* +* 10^6 microseconds +* (1) Time measured = Number timer counts * ------------------- * Timer period +* 1 second +* +* Number timer counts 10^6 microseconds +* (2) Time measured = --------------------- * ------------------- +* Timer frequency 1 second +* +* where +* +* (A) Number timer counts Number of timer counts measured +* (B) Timer frequency Timer's frequency in some units +* of counts per second +* (C) Timer period Timer's period in some units of +* (fractional) seconds +* (D) Time measured Amount of time measured, +* in microseconds +* +* (b) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +* +* (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits +* -- up to 32 or 64, respectively -- into microseconds. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts) +{ + CPU_INT64U time; + + + time = ((CPU_INT64U)ts_cnts*(CPU_INT64U)CPU_USECS_PER_SEC)/((CPU_INT64U)CPU_TS_TmrFreq_Hz); + + return (time); +} +#endif + + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts) +{ + + /* $$$$ Insert code to convert (up to) 64-bits of 64-bit CPU timestamp to microseconds (see Note #2) */ + + return (0u); +} +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/FR/Softune/cpu.h b/FR/Softune/cpu.h new file mode 100644 index 0000000..a23d3ba --- /dev/null +++ b/FR/Softune/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Fujitsu FR +* Softune Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/FR/Softune/cpu_a.asm b/FR/Softune/cpu_a.asm new file mode 100644 index 0000000..a3586a3 --- /dev/null +++ b/FR/Softune/cpu_a.asm @@ -0,0 +1,81 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Fujitsu FR +; Softune Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + .PROGRAM CPU_A + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .EXPORT _CPU_SR_Save + .EXPORT _CPU_SR_Restore + + .section CODE, code, align=4 + + +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you +; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then +; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' +; into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + + +_CPU_SR_Save: + MOV PS, R4 ; Save state of PS + ANDCCR #0xEF ; Disable interrupts + RET + +_CPU_SR_Restore: + MOV R4, PS ; Restore state of PS + RET + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .END + diff --git a/H8-300L/Normal/HEW/cpu.h b/H8-300L/Normal/HEW/cpu.h new file mode 100644 index 0000000..a46dad6 --- /dev/null +++ b/H8-300L/Normal/HEW/cpu.h @@ -0,0 +1,474 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8-300L +* Renesas HEW Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_ccr(); \ + set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { set_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/H8-300L/Normal/IAR/cpu.h b/H8-300L/Normal/IAR/cpu.h new file mode 100644 index 0000000..9b33306 --- /dev/null +++ b/H8-300L/Normal/IAR/cpu.h @@ -0,0 +1,482 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8-300L +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __read_ccr(); \ + __set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { __save_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/H8S/Adv/HEW/cpu.h b/H8S/Adv/HEW/cpu.h new file mode 100644 index 0000000..851199e --- /dev/null +++ b/H8S/Adv/HEW/cpu.h @@ -0,0 +1,479 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8S +* Renesas HEW Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_ccr(); \ + set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { set_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/H8S/Adv/IAR/cpu.h b/H8S/Adv/IAR/cpu.h new file mode 100644 index 0000000..39b9c00 --- /dev/null +++ b/H8S/Adv/IAR/cpu.h @@ -0,0 +1,474 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8S +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __read_ccr(); \ + __set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { __save_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/H8SX/Adv/HEW/cpu.h b/H8SX/Adv/HEW/cpu.h new file mode 100644 index 0000000..c0864eb --- /dev/null +++ b/H8SX/Adv/HEW/cpu.h @@ -0,0 +1,479 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8SX +* Renesas HEW Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_ccr(); \ + set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { set_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/H8SX/Adv/IAR/cpu.h b/H8SX/Adv/IAR/cpu.h new file mode 100644 index 0000000..a892761 --- /dev/null +++ b/H8SX/Adv/IAR/cpu.h @@ -0,0 +1,475 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* H8SX 166x +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __set_imask_ccr(1); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __set_imask_ccr(0); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __read_ccr(); \ + __set_imask_ccr(1); } while (0) +#define CPU_INT_EN() do { __save_ccr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/LatticeMico32/GNU/cpu.h b/LatticeMico32/GNU/cpu.h new file mode 100644 index 0000000..e674758 --- /dev/null +++ b/LatticeMico32/GNU/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* LatticeMico32 +* GNU C/C++ Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/LatticeMico32/GNU/cpu_a.s b/LatticeMico32/GNU/cpu_a.s new file mode 100644 index 0000000..8afbc43 --- /dev/null +++ b/LatticeMico32/GNU/cpu_a.s @@ -0,0 +1,94 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* LatticeMico32 +* GNU C/C++ Compiler +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + +/* +********************************************************************************************************* +* CODE GENERATION DIRECTIVES +********************************************************************************************************* +*/ + + .text + +/* +********************************************************************************************************* +* SAVE/RESTORE CPU STATUS REGISTER +* +* Description : Save/Restore the state of CPU interrupts, if possible. +* +* (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +* stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +* allocated in all functions that need to disable interrupts). The previous interrupt +* status state is restored by copying 'cpu_sr' into the CPU's status register. +* +* +* Prototypes : CPU_SR CPU_SR_Save (void); +* void CPU_SR_Restore(CPU_SR cpu_sr); +* +* Note(s) : (2) These functions are used in general like this : +* +* void Task (void *p_arg) +* { +* CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +* : +* : +* CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +* : +* : +* CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +* : +* } +********************************************************************************************************* +*/ + +CPU_SR_Save: + rcsr r1, ie + wcsr ie, r0 + ret + + +CPU_SR_Restore: + wcsr ie, r1 + ret + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ diff --git a/M14K/CodeSourcery/cpu.h b/M14K/CodeSourcery/cpu.h new file mode 100644 index 0000000..59d7315 --- /dev/null +++ b/M14K/CodeSourcery/cpu.h @@ -0,0 +1,473 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MIPS14K +* MicroMips +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_CacheDataFlush (void *addr, CPU_INT32U len); +void CPU_CacheDataInvalidate(void *addr, CPU_INT32U len); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/M14K/CodeSourcery/cpu_a.s b/M14K/CodeSourcery/cpu_a.s new file mode 100644 index 0000000..67b68fc --- /dev/null +++ b/M14K/CodeSourcery/cpu_a.s @@ -0,0 +1,103 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MIPS14k +* MicroMips +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + +#define _ASMLANGUAGE + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + + .globl CPU_SR_Save + .globl CPU_SR_Restore + +/* +********************************************************************************************************* +* EQUATES +********************************************************************************************************* +*/ + +.text + + +/* +********************************************************************************************************* +* DISABLE INTERRUPTS +* CPU_SR CPU_SR_Save(void); +* +* Description: This function saves the state of the Status register and then disables interrupts via this +* register. This objective is accomplished with a single instruction, di. The di +* instruction's operand, $2, is the general purpose register to which the Status register's +* value is saved. This value can be read by C functions that call OS_CPU_SR_Save(). +* +* Arguments : None +* +* Returns : The previous state of the Status register +********************************************************************************************************* +*/ + + .ent CPU_SR_Save +CPU_SR_Save: + + jr $31 + di $2 /* Disable interrupts, and move the old value of the... */ + /* ...Status register into v0 ($2) */ + .end CPU_SR_Save + + +/* +********************************************************************************************************* +* ENABLE INTERRUPTS +* void CPU_SR_Restore(CPU_SR sr); +* +* Description: This function must be used in tandem with CPU_SR_Save(). Calling CPU_SR_Restore() +* causes the value returned by CPU_SR_Save() to be placed in the Status register. +* +* Arguments : The value to be placed in the Status register +* +* Returns : None +********************************************************************************************************* +*/ + + .ent CPU_SR_Restore +CPU_SR_Restore: + + jr $31 + mtc0 $4, $12, 0 /* Restore the status register to its previous state */ + + .end CPU_SR_Restore + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/M16C/HEW/cpu.h b/M16C/HEW/cpu.h new file mode 100644 index 0000000..8fa7633 --- /dev/null +++ b/M16C/HEW/cpu.h @@ -0,0 +1,472 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* M16C +* Renesas HEW w/NC30 C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/M16C/HEW/cpu_a.a30 b/M16C/HEW/cpu_a.a30 new file mode 100644 index 0000000..e980fc9 --- /dev/null +++ b/M16C/HEW/cpu_a.a30 @@ -0,0 +1,112 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; M16C +; Renesas HEW w/NC30 C Compiler +; +; Filename : cpu_a.a30 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_IntDis +_CPU_IntDis: + FCLR I + RTS + + + .SECTION program + .GLB _CPU_IntEn +_CPU_IntEn: + FSET I + RTS + + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_SR_Save +_CPU_SR_Save: + STC FLG, R0 + FCLR I + RTS + + + .SECTION program + .GLB _CPU_SR_Restore + +_CPU_SR_Restore: + LDC R0, FLG + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .END + diff --git a/M16C/IAR/cpu.h b/M16C/IAR/cpu.h new file mode 100644 index 0000000..aa5f1c3 --- /dev/null +++ b/M16C/IAR/cpu.h @@ -0,0 +1,477 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* M16C +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) Some 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. +* However, in order to compile functionality/features requiring 64-bit support; 64-bit +* data types MUST be defined even if defined with a precision lower than 64-bits (e.g. +* with 32-bits of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/M16C/IAR/cpu_a.s34 b/M16C/IAR/cpu_a.s34 new file mode 100644 index 0000000..33e7448 --- /dev/null +++ b/M16C/IAR/cpu_a.s34 @@ -0,0 +1,111 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; M16C +; IAR C Compiler +; +; Filename : cpu_a.s34 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + +CPU_IntDis + FCLR I + RTS + + +CPU_IntEn + FSET I + RTS + + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + +CPU_SR_Save + STC FLG, R0 + FCLR I + RTS + + +CPU_SR_Restore + LDC R0, FLG + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/M32C/HEW/cpu.h b/M32C/HEW/cpu.h new file mode 100644 index 0000000..19d109d --- /dev/null +++ b/M32C/HEW/cpu.h @@ -0,0 +1,472 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* M32C +* Renesas HEW w/NC30 C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/M32C/HEW/cpu_a.a30 b/M32C/HEW/cpu_a.a30 new file mode 100644 index 0000000..3e09646 --- /dev/null +++ b/M32C/HEW/cpu_a.a30 @@ -0,0 +1,112 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; M32C +; Renesas HEW w/NC30 C Compiler +; +; Filename : cpu_a.a30 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_IntDis +_CPU_IntDis: + FCLR I + RTS + + + .SECTION program + .GLB _CPU_IntEn +_CPU_IntEn: + FSET I + RTS + + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_SR_Save +_CPU_SR_Save: + STC FLG, R0 + FCLR I + RTS + + + .SECTION program + .GLB _CPU_SR_Restore + +_CPU_SR_Restore: + LDC R0, FLG + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .END + diff --git a/M32C/IAR/cpu.h b/M32C/IAR/cpu.h new file mode 100644 index 0000000..ff955d4 --- /dev/null +++ b/M32C/IAR/cpu.h @@ -0,0 +1,477 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* M32C +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) Some 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. +* However, in order to compile functionality/features requiring 64-bit support; 64-bit +* data types MUST be defined even if defined with a precision lower than 64-bits (e.g. +* with 32-bits of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/M32C/IAR/cpu_a.s48 b/M32C/IAR/cpu_a.s48 new file mode 100644 index 0000000..332d049 --- /dev/null +++ b/M32C/IAR/cpu_a.s48 @@ -0,0 +1,111 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; M32C +; IAR C Compiler +; +; Filename : cpu_a.s48 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + +CPU_IntDis + FCLR I + RTS + + +CPU_IntEn + FSET I + RTS + + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + +CPU_SR_Save + STC FLG, R0 + FCLR I + RTS + + +CPU_SR_Restore + LDC R0, FLG + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/MC9S08/NonPaged/Codewarrior/cpu.h b/MC9S08/NonPaged/Codewarrior/cpu.h new file mode 100644 index 0000000..3bfe667 --- /dev/null +++ b/MC9S08/NonPaged/Codewarrior/cpu.h @@ -0,0 +1,475 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MC9S08 +* Codewarrior +* Non Paged +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MC9S08/NonPaged/Codewarrior/cpu_a.s b/MC9S08/NonPaged/Codewarrior/cpu_a.s new file mode 100644 index 0000000..eb639a9 --- /dev/null +++ b/MC9S08/NonPaged/Codewarrior/cpu_a.s @@ -0,0 +1,67 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Freescale MC9S08 +; Codewarrior +; Non Paged +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + xdef CPU_SR_Save + xdef CPU_SR_Restore + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; SAVE THE CCR AND DISABLE INTERRUPTS +; & +; RESTORE CCR +; +; Description : These function implements OS_CRITICAL_METHOD #3 +; +; Arguments : The function prototypes for the two functions are: +; 1) OS_CPU_SR OSCPUSaveSR(void) +; where OS_CPU_SR is the contents of the CCR register prior to disabling +; interrupts. +; 2) void OSCPURestoreSR(OS_CPU_SR os_cpu_sr); +; 'os_cpu_sr' the the value of the CCR to restore. +; +; Note(s) : 1) It's assumed that the compiler uses the A register to pass a single 8-bit argument +; to and from an assembly language function. +;******************************************************************************************************** + +CPU_SR_Save: + tpa ; Transfer the CCR to A. + sei ; Disable interrupts + rts ; Return to caller with A containing the previous CCR + +CPU_SR_Restore: + tap ; Restore the CCR from the function argument stored in A + rts + diff --git a/MC9S08/Paged/Codewarrior/cpu.h b/MC9S08/Paged/Codewarrior/cpu.h new file mode 100644 index 0000000..255f4b3 --- /dev/null +++ b/MC9S08/Paged/Codewarrior/cpu.h @@ -0,0 +1,475 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MC9S08 +* Codewarrior +* Paged +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MC9S08/Paged/Codewarrior/cpu_a.s b/MC9S08/Paged/Codewarrior/cpu_a.s new file mode 100644 index 0000000..16c604b --- /dev/null +++ b/MC9S08/Paged/Codewarrior/cpu_a.s @@ -0,0 +1,67 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Freescale MC9S08 +; Codewarrior +; Paged +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + xdef CPU_SR_Save + xdef CPU_SR_Restore + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; SAVE THE CCR AND DISABLE INTERRUPTS +; & +; RESTORE CCR +; +; Description : These function implements OS_CRITICAL_METHOD #3 +; +; Arguments : The function prototypes for the two functions are: +; 1) OS_CPU_SR OSCPUSaveSR(void) +; where OS_CPU_SR is the contents of the CCR register prior to disabling +; interrupts. +; 2) void OSCPURestoreSR(OS_CPU_SR os_cpu_sr); +; 'os_cpu_sr' the the value of the CCR to restore. +; +; Note(s) : 1) It's assumed that the compiler uses the A register to pass a single 8-bit argument +; to and from an assembly language function. +;******************************************************************************************************** + +CPU_SR_Save: + tpa ; Transfer the CCR to A. + sei ; Disable interrupts + rtc ; Return to caller with A containing the previous CCR + +CPU_SR_Restore: + tap ; Restore the CCR from the function argument stored in A + rtc + diff --git a/MC9S12/Codewarrior/NonPaged/cpu.h b/MC9S12/Codewarrior/NonPaged/cpu.h new file mode 100644 index 0000000..c458783 --- /dev/null +++ b/MC9S12/Codewarrior/NonPaged/cpu.h @@ -0,0 +1,475 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MC9S12 +* Codewarrior +* Non Paged +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MC9S12/Codewarrior/NonPaged/cpu_a.s b/MC9S12/Codewarrior/NonPaged/cpu_a.s new file mode 100644 index 0000000..655e9c0 --- /dev/null +++ b/MC9S12/Codewarrior/NonPaged/cpu_a.s @@ -0,0 +1,74 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Freescale MC9S12 +; Codewarrior +; Non Paged +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + +NON_BANKED: section + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + xdef CPU_SR_Save + xdef CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; SAVE THE CCR AND DISABLE INTERRUPTS +; & +; RESTORE CCR +; +; Description : These function implements OS_CRITICAL_METHOD #3 +; +; Arguments : The function prototypes for the two functions are: +; 1) CPU_SR CPU_SR_Save(void); +; where CPU_SR is the contents of the CCR register prior to disabling +; interrupts. +; 2) void CPU_SR_Restore(CPU_SR cpu_sr); +; 'cpu_sr' the the value of the CCR to restore. +; +; Note(s) : 1) It's assumed that the compiler uses the D register to pass a single 16-bit argument +; to and from an assembly language function. +;******************************************************************************************************** + +CPU_SR_Save: + tfr ccr,b ; It's assumed that 8-bit return value is in register B + sei ; Disable interrupts + rts ; Return to caller with D containing the previous CCR + +CPU_SR_Restore: + tfr b,ccr ; B contains the CCR value to restore, move to CCR + rts + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + diff --git a/MC9S12/Codewarrior/cpu.h b/MC9S12/Codewarrior/cpu.h new file mode 100644 index 0000000..e693185 --- /dev/null +++ b/MC9S12/Codewarrior/cpu.h @@ -0,0 +1,473 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MC9S12 +* Codewarrior +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MC9S12/Codewarrior/cpu_a.s b/MC9S12/Codewarrior/cpu_a.s new file mode 100644 index 0000000..e9bd29f --- /dev/null +++ b/MC9S12/Codewarrior/cpu_a.s @@ -0,0 +1,72 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Freescale MC9S12 +; Codewarrior +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + xdef CPU_SR_Save + xdef CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; SAVE THE CCR AND DISABLE INTERRUPTS +; & +; RESTORE CCR +; +; Description : These function implements OS_CRITICAL_METHOD #3 +; +; Arguments : The function prototypes for the two functions are: +; 1) CPU_SR CPU_SR_Save(void); +; where CPU_SR is the contents of the CCR register prior to disabling +; interrupts. +; 2) void CPU_SR_Restore(CPU_SR cpu_sr); +; 'cpu_sr' the the value of the CCR to restore. +; +; Note(s) : 1) It's assumed that the compiler uses the D register to pass a single 16-bit argument +; to and from an assembly language function. +;******************************************************************************************************** + +CPU_SR_Save: + tfr ccr,b ; It's assumed that 8-bit return value is in register B + sei ; Disable interrupts + rtc ; Return to caller with D containing the previous CCR + +CPU_SR_Restore: + tfr b,ccr ; B contains the CCR value to restore, move to CCR + rtc + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + diff --git a/MC9S12X/Codewarrior/cpu.h b/MC9S12X/Codewarrior/cpu.h new file mode 100644 index 0000000..edd1bde --- /dev/null +++ b/MC9S12X/Codewarrior/cpu.h @@ -0,0 +1,474 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MC9S12X +* Codewarrior Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT08U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MC9S12X/Codewarrior/cpu_a.s b/MC9S12X/Codewarrior/cpu_a.s new file mode 100644 index 0000000..fd08eb9 --- /dev/null +++ b/MC9S12X/Codewarrior/cpu_a.s @@ -0,0 +1,72 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Freescale MC9S12X +; Codewarrior Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + xdef CPU_SR_Save + xdef CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; SAVE THE CCR AND DISABLE INTERRUPTS +; & +; RESTORE CCR +; +; Description : These function implements OS_CRITICAL_METHOD #3 +; +; Arguments : The function prototypes for the two functions are: +; 1) CPU_SR CPU_SR_Save(void); +; where CPU_SR is the contents of the CCR register prior to disabling +; interrupts. +; 2) void CPU_SR_Restore(CPU_SR cpu_sr); +; 'cpu_sr' the the value of the CCR to restore. +; +; Note(s) : 1) It's assumed that the compiler uses the D register to pass a single 16-bit argument +; to and from an assembly language function. +;******************************************************************************************************** + +CPU_SR_Save: + tfr ccrw,d ; It's assumed that 16-bit return value is in register D + sei ; Disable interrupts + rtc ; Return to caller with D containing the previous CCR + +CPU_SR_Restore: + tfr d,ccrw ; D contains the CCR word value to restore, move D to CCR + rtc + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + diff --git a/MCF5272/GNU/cpu.h b/MCF5272/GNU/cpu.h new file mode 100644 index 0000000..df3213a --- /dev/null +++ b/MCF5272/GNU/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MCF5272 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MCF5272/GNU/cpu_a.s b/MCF5272/GNU/cpu_a.s new file mode 100644 index 0000000..6491dd1 --- /dev/null +++ b/MCF5272/GNU/cpu_a.s @@ -0,0 +1,80 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; MCF5272 +; GNU C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC DECLARATIONS +;******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + +;******************************************************************************************************** +; CPU_SR_Save() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #3 function to preserve the state of the +; interrupt disable flag in order to be able to restore it later. +; +; Arguments : none +; +; Returns : It is assumed that the return value is placed in the D0 register as expected by the +; compiler. +;******************************************************************************************************** + + .text + +CPU_SR_Save: + MOVE %SR,%D0 /* Copy SR into D0 */ + MOVE.L %D0,-(%A7) /* Save D0 */ + ORI.L #0x0700,%D0 /* Disable interrupts */ + MOVE %D0,%SR + MOVE.L (%A7)+,%D0 /* Restore original state of SR */ + RTS + +;******************************************************************************************************** +; CPU_SR_Restore() for OS_CRITICAL_METHOD #3 +; +; Description : This functions implements the OS_CRITICAL_METHOD #function to restore the state of the +; interrupt flag. +; +; Arguments : cpu_sr is the contents of the SR to restore. It is assumed that this 'argument' is +; passed in the D0 register of the CPU by the compiler. +; +; Returns : None +;******************************************************************************************************** + +CPU_SR_Restore: + MOVE %D0,%SR + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/MIPS32-4K/MPLAB-PIC32-GCC/cpu.h b/MIPS32-4K/MPLAB-PIC32-GCC/cpu.h new file mode 100644 index 0000000..d2ffc96 --- /dev/null +++ b/MIPS32-4K/MPLAB-PIC32-GCC/cpu.h @@ -0,0 +1,515 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MIPS32 4K +* MPLAB +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__("sync" : : : "memory") +#define CPU_RMB() __asm__ __volatile__("sync" : : : "memory") +#define CPU_WMB() __asm__ __volatile__("sync" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); + +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ diff --git a/MIPS32-4K/MPLAB-PIC32-GCC/cpu_a.s b/MIPS32-4K/MPLAB-PIC32-GCC/cpu_a.s new file mode 100644 index 0000000..cd7fe55 --- /dev/null +++ b/MIPS32-4K/MPLAB-PIC32-GCC/cpu_a.s @@ -0,0 +1,142 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MIPS32 4K +* MPLAB +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_CntLeadZeros + + +/* +********************************************************************************************************* +* CODE GENERATION DIRECTIVES +********************************************************************************************************* +*/ + + .section .text,code + .set noreorder + + +/* +********************************************************************************************************** +* CRITICAL SECTION FUNCTIONS +* +* Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +* state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +* are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +* The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +* +* Prototypes : CPU_SR CPU_SR_Save(void); +* void CPU_SR_Restore(CPU_SR cpu_sr); +********************************************************************************************************** +*/ + + .ent CPU_SR_Save +CPU_SR_Save: + + di $2 /* Disable interrupts, and move the old value of the... */ + jr.hb $31 /* ...Status register into v0 ($2) */ + nop + + .end CPU_SR_Save + + + .ent CPU_SR_Restore +CPU_SR_Restore: + + mtc0 $4, $12, 0 /* Restore the status register to its previous state */ + jr.hb $31 + nop + + .end CPU_SR_Restore + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s). +* 0, otherwise. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits - N/A +* (2) 16-bits - N/A +* (3) 32-bits - M4K core (see MIPS clz documentation) +* (4) 64-bits - N/A +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* +* Note(s) : (1) This functions is used when CPU_CFG_LEAD_ZEROS_ASM_PRESENT is defined in cpu.h/cpu_cfg.h. +* This function has been implemented to use the Count Leading Zeros (CLZ) instruction +* present in the M4K core. +* (2) This function was located here because it is hardware dependant, and is part of the port. +* The function prototype exists in cpu.h. It is needed because this assembler routine is +* called from C. +* (3) See MIPS documentation for explanation of why the same GP register is used for source and +* desitination of the clz instruction. +********************************************************************************************************* +*/ + + .ent CPU_CntLeadZeros +CPU_CntLeadZeros: + + clz $4, $4 /* Count leading zeros in value passed into GP $4 */ + jr $31 + addu $2, $4, $0 /* Result is returned to caller in GP $2 */ + + .end CPU_CntLeadZeros diff --git a/MPC55xx-VLE/CodeWarrior/cpu.h b/MPC55xx-VLE/CodeWarrior/cpu.h new file mode 100644 index 0000000..048306f --- /dev/null +++ b/MPC55xx-VLE/CodeWarrior/cpu.h @@ -0,0 +1,504 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MPC55xx +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Rd (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_DEC_Set (CPU_INT32U val); +void CPU_DECAR_Set (CPU_INT32U val); +CPU_INT32U CPU_HID0_Get (void); +void CPU_HID0_Set (CPU_INT32U val); +CPU_INT32U CPU_TBL_Get (void); +CPU_INT32U CPU_TBU_Get (void); +void CPU_TBL_Set (CPU_INT32U val); +void CPU_TBU_Set (CPU_INT32U val); +CPU_INT32U CPU_TCR_Get (void); +void CPU_TCR_Set (CPU_INT32U val); + +void CPU_IVOR0_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR1_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR2_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR3_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR4_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR5_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR6_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR7_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR8_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR9_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR10_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR11_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR12_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR13_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR14_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR15_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR32_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR33_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR34_Set(CPU_FNCT_VOID fnct); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC55xx-VLE/CodeWarrior/cpu_a.s b/MPC55xx-VLE/CodeWarrior/cpu_a.s new file mode 100644 index 0000000..bca70f5 --- /dev/null +++ b/MPC55xx-VLE/CodeWarrior/cpu_a.s @@ -0,0 +1,380 @@ +#********************************************************************************************************* +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#********************************************************************************************************* + +#********************************************************************************************************* +#* +#* CPU PORT FILE +#* +#* Freescale MPC55xx +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#********************************************************************************************************* + + +#********************************************************************************************************* +#* ASM HEADER +#********************************************************************************************************* + + .text_vle + +#********************************************************************************************************* +#* PUBLIC DECLARATIONS +#********************************************************************************************************* + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + .global CPU_DEC_Set + .global CPU_DECAR_Set + .global CPU_HID0_Get + .global CPU_HID0_Set + .global CPU_TBL_Get + .global CPU_TBU_Get + .global CPU_TBL_Set + .global CPU_TBU_Set + .global CPU_TCR_Get + .global CPU_TCR_Set + + .global CPU_IVOR0_Set + .global CPU_IVOR1_Set + .global CPU_IVOR2_Set + .global CPU_IVOR3_Set + .global CPU_IVOR4_Set + .global CPU_IVOR5_Set + .global CPU_IVOR6_Set + .global CPU_IVOR7_Set + .global CPU_IVOR8_Set + .global CPU_IVOR9_Set + .global CPU_IVOR10_Set + .global CPU_IVOR11_Set + .global CPU_IVOR12_Set + .global CPU_IVOR13_Set + .global CPU_IVOR14_Set + .global CPU_IVOR15_Set + .global CPU_IVOR32_Set + .global CPU_IVOR33_Set + .global CPU_IVOR34_Set + + +#********************************************************************************************************* +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#********************************************************************************************************* + +CPU_SR_Save: + mfmsr r3 + wrteei 0 + se_blr + +CPU_SR_Restore: + mtmsr r3 + se_blr + + +#********************************************************************************************************* +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#********************************************************************************************************* + +CPU_SR_Rd: + mfmsr r3 + se_blr + + +#********************************************************************************************************* +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#********************************************************************************************************* + +CPU_IntDis: + wrteei 0 + se_blr + + +CPU_IntEn: + wrteei 1 + se_blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer register with a given value. +#* +#* void CPU_DEC_Set (CPU_INT32U value) +#* Write value into DEC +#* Return +#********************************************************************************************************* + +CPU_DEC_Set: + mtDEC r3 + se_blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER AUTORELOAD REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer auto-reload register with a given value. +#* +#* void CPU_DECAR_Set (CPU_INT32U value) +#* Write value into DECAR +#* Return +#********************************************************************************************************* + +CPU_DECAR_Set: + mtDECAR r3 + se_blr + + +#********************************************************************************************************* +#* READ HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the hardware implementation dependent register value. +#* +#* CPU_INT32U CPU_HID0_Get (void) +#* Get current HID0 value +#* Return +#********************************************************************************************************* + +CPU_HID0_Get: + mfspr r3, 1008 + se_blr + + +#********************************************************************************************************* +#* WRITE HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to set the hardware implementation dependent register value. +#* +#* void CPU_HID0_Set (CPU_INT32U value) +#* Write value into HID0 +#* Return +#********************************************************************************************************* + +CPU_HID0_Set: + mtspr 1008, r3 + se_blr + + +#********************************************************************************************************* +#* READ TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base low register value. +#* +#* CPU_INT32U CPU_TBL_Get (void) +#* Get current TBL value +#* Return +#********************************************************************************************************* + +CPU_TBL_Get: + mfspr r3, 268 + se_blr + + +#********************************************************************************************************* +#* READ TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base high register value. +#* +#* CPU_INT32U CPU_TBU_Get (void) +#* Get current TBU value +#* Return +#********************************************************************************************************* + +CPU_TBU_Get: + mfspr r3, 269 + se_blr + + +#********************************************************************************************************* +#* WRITE TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to set the time base low register value. +#* +#* void CPU_TBL_Set (CPU_INT32U value) +#* Write value into TBL +#* Return +#********************************************************************************************************* + +CPU_TBL_Set: + mtspr 284, r3 + se_blr + + +#********************************************************************************************************* +#* WRITE TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to set the time base high register value. +#* +#* void CPU_TBU_Set (CPU_INT32U value) +#* Write value into TBU +#* Return +#********************************************************************************************************* + +CPU_TBU_Set: + mtspr 285, r3 + se_blr + + +#********************************************************************************************************* +#* READ TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the timer control register value. +#* +#* CPU_INT32U CPU_TCR_Get (void) +#* Get current TCR value +#* Return +#********************************************************************************************************* + +CPU_TCR_Get: + mfTCR r3 + se_blr + + +#********************************************************************************************************* +#* WRITE TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to set the timer control register value. +#* +#* void CPU_TCR_Set (CPU_INT32U value) +#* Write value into TCR +#* Return +#********************************************************************************************************* + +CPU_TCR_Set: + mtTCR r3 + se_blr + + +#********************************************************************************************************* +#* WRITE IVOR REGISTER FUNCTION +#* +#* Description : These functions are used to set the exception handler functions. +#* +#* void CPU_IVORx_Set (CPU_FNCT_VOID fnct) +#* Write fnct address into IVORx +#* Return +#********************************************************************************************************* + +CPU_IVOR0_Set: + mtIVOR0 r3 + se_blr + +CPU_IVOR1_Set: + mtIVOR1 r3 + se_blr + +CPU_IVOR2_Set: + mtIVOR2 r3 + se_blr + +CPU_IVOR3_Set: + mtIVOR3 r3 + se_blr + +CPU_IVOR4_Set: + mtIVOR4 r3 + se_blr + +CPU_IVOR5_Set: + mtIVOR5 r3 + se_blr + +CPU_IVOR6_Set: + mtIVOR6 r3 + se_blr + +CPU_IVOR7_Set: + mtIVOR7 r3 + se_blr + +CPU_IVOR8_Set: + mtIVOR8 r3 + se_blr + +CPU_IVOR9_Set: + mtIVOR9 r3 + se_blr + +CPU_IVOR10_Set: + mtIVOR10 r3 + se_blr + +CPU_IVOR11_Set: + mtIVOR11 r3 + se_blr + +CPU_IVOR12_Set: + mtIVOR12 r3 + se_blr + +CPU_IVOR13_Set: + mtIVOR13 r3 + se_blr + +CPU_IVOR14_Set: + mtIVOR14 r3 + se_blr + +CPU_IVOR15_Set: + mtIVOR15 r3 + se_blr + +CPU_IVOR32_Set: + mtIVOR32 r3 + se_blr + +CPU_IVOR33_Set: + mtIVOR33 r3 + se_blr + +CPU_IVOR34_Set: + mtIVOR34 r3 + se_blr + + +#********************************************************************************************************* +#* CPU ASSEMBLY PORT FILE END +#********************************************************************************************************* + .end diff --git a/MPC55xx/CodeWarrior/cpu.h b/MPC55xx/CodeWarrior/cpu.h new file mode 100644 index 0000000..048306f --- /dev/null +++ b/MPC55xx/CodeWarrior/cpu.h @@ -0,0 +1,504 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MPC55xx +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Rd (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_DEC_Set (CPU_INT32U val); +void CPU_DECAR_Set (CPU_INT32U val); +CPU_INT32U CPU_HID0_Get (void); +void CPU_HID0_Set (CPU_INT32U val); +CPU_INT32U CPU_TBL_Get (void); +CPU_INT32U CPU_TBU_Get (void); +void CPU_TBL_Set (CPU_INT32U val); +void CPU_TBU_Set (CPU_INT32U val); +CPU_INT32U CPU_TCR_Get (void); +void CPU_TCR_Set (CPU_INT32U val); + +void CPU_IVOR0_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR1_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR2_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR3_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR4_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR5_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR6_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR7_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR8_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR9_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR10_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR11_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR12_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR13_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR14_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR15_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR32_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR33_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR34_Set(CPU_FNCT_VOID fnct); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC55xx/CodeWarrior/cpu_a.s b/MPC55xx/CodeWarrior/cpu_a.s new file mode 100644 index 0000000..6d70a0d --- /dev/null +++ b/MPC55xx/CodeWarrior/cpu_a.s @@ -0,0 +1,380 @@ +#********************************************************************************************************* +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#********************************************************************************************************* + +#********************************************************************************************************* +#* +#* CPU PORT FILE +#* +#* Freescale MPC55xx +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#********************************************************************************************************* + + +#********************************************************************************************************* +#* ASM HEADER +#********************************************************************************************************* + + .text + +#********************************************************************************************************* +#* PUBLIC DECLARATIONS +#********************************************************************************************************* + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + .global CPU_DEC_Set + .global CPU_DECAR_Set + .global CPU_HID0_Get + .global CPU_HID0_Set + .global CPU_TBL_Get + .global CPU_TBU_Get + .global CPU_TBL_Set + .global CPU_TBU_Set + .global CPU_TCR_Get + .global CPU_TCR_Set + + .global CPU_IVOR0_Set + .global CPU_IVOR1_Set + .global CPU_IVOR2_Set + .global CPU_IVOR3_Set + .global CPU_IVOR4_Set + .global CPU_IVOR5_Set + .global CPU_IVOR6_Set + .global CPU_IVOR7_Set + .global CPU_IVOR8_Set + .global CPU_IVOR9_Set + .global CPU_IVOR10_Set + .global CPU_IVOR11_Set + .global CPU_IVOR12_Set + .global CPU_IVOR13_Set + .global CPU_IVOR14_Set + .global CPU_IVOR15_Set + .global CPU_IVOR32_Set + .global CPU_IVOR33_Set + .global CPU_IVOR34_Set + + +#********************************************************************************************************* +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#********************************************************************************************************* + +CPU_SR_Save: + mfmsr r3 + wrteei 0 + blr + +CPU_SR_Restore: + mtmsr r3 + blr + + +#********************************************************************************************************* +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#********************************************************************************************************* + +CPU_SR_Rd: + mfmsr r3 + blr + + +#********************************************************************************************************* +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#********************************************************************************************************* + +CPU_IntDis: + wrteei 0 + blr + + +CPU_IntEn: + wrteei 1 + blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer register with a given value. +#* +#* void CPU_DEC_Set (CPU_INT32U value) +#* Write value into DEC +#* Return +#********************************************************************************************************* + +CPU_DEC_Set: + mtDEC r3 + blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER AUTORELOAD REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer auto-reload register with a given value. +#* +#* void CPU_DECAR_Set (CPU_INT32U value) +#* Write value into DECAR +#* Return +#********************************************************************************************************* + +CPU_DECAR_Set: + mtDECAR r3 + blr + + +#********************************************************************************************************* +#* READ HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the hardware implementation dependent register value. +#* +#* CPU_INT32U CPU_HID0_Get (void) +#* Get current HID0 value +#* Return +#********************************************************************************************************* + +CPU_HID0_Get: + mfspr r3, 1008 + blr + + +#********************************************************************************************************* +#* WRITE HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to set the hardware implementation dependent register value. +#* +#* void CPU_HID0_Set (CPU_INT32U value) +#* Write value into HID0 +#* Return +#********************************************************************************************************* + +CPU_HID0_Set: + mtspr 1008, r3 + blr + + +#********************************************************************************************************* +#* READ TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base low register value. +#* +#* CPU_INT32U CPU_TBL_Get (void) +#* Get current TBL value +#* Return +#********************************************************************************************************* + +CPU_TBL_Get: + mfspr r3, 268 + blr + + +#********************************************************************************************************* +#* READ TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base high register value. +#* +#* CPU_INT32U CPU_TBU_Get (void) +#* Get current TBU value +#* Return +#********************************************************************************************************* + +CPU_TBU_Get: + mfspr r3, 269 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to set the time base low register value. +#* +#* void CPU_TBL_Set (CPU_INT32U value) +#* Write value into TBL +#* Return +#********************************************************************************************************* + +CPU_TBL_Set: + mtspr 284, r3 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to set the time base high register value. +#* +#* void CPU_TBU_Set (CPU_INT32U value) +#* Write value into TBU +#* Return +#********************************************************************************************************* + +CPU_TBU_Set: + mtspr 285, r3 + blr + + +#********************************************************************************************************* +#* READ TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the timer control register value. +#* +#* CPU_INT32U CPU_TCR_Get (void) +#* Get current TCR value +#* Return +#********************************************************************************************************* + +CPU_TCR_Get: + mfTCR r3 + blr + + +#********************************************************************************************************* +#* WRITE TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to set the timer control register value. +#* +#* void CPU_TCR_Set (CPU_INT32U value) +#* Write value into TCR +#* Return +#********************************************************************************************************* + +CPU_TCR_Set: + mtTCR r3 + blr + + +#********************************************************************************************************* +#* WRITE IVOR REGISTER FUNCTION +#* +#* Description : These functions are used to set the exception handler functions. +#* +#* void CPU_IVORx_Set (CPU_FNCT_VOID fnct) +#* Write fnct address into IVORx +#* Return +#********************************************************************************************************* + +CPU_IVOR0_Set: + mtIVOR0 r3 + blr + +CPU_IVOR1_Set: + mtIVOR1 r3 + blr + +CPU_IVOR2_Set: + mtIVOR2 r3 + blr + +CPU_IVOR3_Set: + mtIVOR3 r3 + blr + +CPU_IVOR4_Set: + mtIVOR4 r3 + blr + +CPU_IVOR5_Set: + mtIVOR5 r3 + blr + +CPU_IVOR6_Set: + mtIVOR6 r3 + blr + +CPU_IVOR7_Set: + mtIVOR7 r3 + blr + +CPU_IVOR8_Set: + mtIVOR8 r3 + blr + +CPU_IVOR9_Set: + mtIVOR9 r3 + blr + +CPU_IVOR10_Set: + mtIVOR10 r3 + blr + +CPU_IVOR11_Set: + mtIVOR11 r3 + blr + +CPU_IVOR12_Set: + mtIVOR12 r3 + blr + +CPU_IVOR13_Set: + mtIVOR13 r3 + blr + +CPU_IVOR14_Set: + mtIVOR14 r3 + blr + +CPU_IVOR15_Set: + mtIVOR15 r3 + blr + +CPU_IVOR32_Set: + mtIVOR32 r3 + blr + +CPU_IVOR33_Set: + mtIVOR33 r3 + blr + +CPU_IVOR34_Set: + mtIVOR34 r3 + blr + + +#********************************************************************************************************* +#* CPU ASSEMBLY PORT FILE END +#********************************************************************************************************* + .end diff --git a/MPC56xx-VLE/CodeWarrior/cpu.h b/MPC56xx-VLE/CodeWarrior/cpu.h new file mode 100644 index 0000000..1d3e9f0 --- /dev/null +++ b/MPC56xx-VLE/CodeWarrior/cpu.h @@ -0,0 +1,504 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MPC56xx-VLE +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Rd (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_DEC_Set (CPU_INT32U val); +void CPU_DECAR_Set (CPU_INT32U val); +CPU_INT32U CPU_HID0_Get (void); +void CPU_HID0_Set (CPU_INT32U val); +CPU_INT32U CPU_TBL_Get (void); +CPU_INT32U CPU_TBU_Get (void); +void CPU_TBL_Set (CPU_INT32U val); +void CPU_TBU_Set (CPU_INT32U val); +CPU_INT32U CPU_TCR_Get (void); +void CPU_TCR_Set (CPU_INT32U val); + +void CPU_IVOR0_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR1_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR2_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR3_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR4_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR5_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR6_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR7_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR8_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR9_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR10_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR11_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR12_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR13_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR14_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR15_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR32_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR33_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR34_Set(CPU_FNCT_VOID fnct); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC56xx-VLE/CodeWarrior/cpu_a.s b/MPC56xx-VLE/CodeWarrior/cpu_a.s new file mode 100644 index 0000000..3db0b1b --- /dev/null +++ b/MPC56xx-VLE/CodeWarrior/cpu_a.s @@ -0,0 +1,380 @@ +#********************************************************************************************************* +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#********************************************************************************************************* + +#********************************************************************************************************* +#* +#* CPU PORT FILE +#* +#* Freescale MPC56xx-VLE +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#********************************************************************************************************* + + +#********************************************************************************************************* +#* ASM HEADER +#********************************************************************************************************* + + .text_vle + +#********************************************************************************************************* +#* PUBLIC DECLARATIONS +#********************************************************************************************************* + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + .global CPU_DEC_Set + .global CPU_DECAR_Set + .global CPU_HID0_Get + .global CPU_HID0_Set + .global CPU_TBL_Get + .global CPU_TBU_Get + .global CPU_TBL_Set + .global CPU_TBU_Set + .global CPU_TCR_Get + .global CPU_TCR_Set + + .global CPU_IVOR0_Set + .global CPU_IVOR1_Set + .global CPU_IVOR2_Set + .global CPU_IVOR3_Set + .global CPU_IVOR4_Set + .global CPU_IVOR5_Set + .global CPU_IVOR6_Set + .global CPU_IVOR7_Set + .global CPU_IVOR8_Set + .global CPU_IVOR9_Set + .global CPU_IVOR10_Set + .global CPU_IVOR11_Set + .global CPU_IVOR12_Set + .global CPU_IVOR13_Set + .global CPU_IVOR14_Set + .global CPU_IVOR15_Set + .global CPU_IVOR32_Set + .global CPU_IVOR33_Set + .global CPU_IVOR34_Set + + +#********************************************************************************************************* +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#********************************************************************************************************* + +CPU_SR_Save: + mfmsr r3 + wrteei 0 + se_blr + +CPU_SR_Restore: + mtmsr r3 + se_blr + + +#********************************************************************************************************* +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#********************************************************************************************************* + +CPU_SR_Rd: + mfmsr r3 + se_blr + + +#********************************************************************************************************* +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#********************************************************************************************************* + +CPU_IntDis: + wrteei 0 + se_blr + + +CPU_IntEn: + wrteei 1 + se_blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer register with a given value. +#* +#* void CPU_DEC_Set (CPU_INT32U value) +#* Write value into DEC +#* Return +#********************************************************************************************************* + +CPU_DEC_Set: + mtDEC r3 + se_blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER AUTORELOAD REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer auto-reload register with a given value. +#* +#* void CPU_DECAR_Set (CPU_INT32U value) +#* Write value into DECAR +#* Return +#********************************************************************************************************* + +CPU_DECAR_Set: + mtDECAR r3 + se_blr + + +#********************************************************************************************************* +#* READ HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the hardware implementation dependent register value. +#* +#* CPU_INT32U CPU_HID0_Get (void) +#* Get current HID0 value +#* Return +#********************************************************************************************************* + +CPU_HID0_Get: + mfspr r3, 1008 + se_blr + + +#********************************************************************************************************* +#* WRITE HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to set the hardware implementation dependent register value. +#* +#* void CPU_HID0_Set (CPU_INT32U value) +#* Write value into HID0 +#* Return +#********************************************************************************************************* + +CPU_HID0_Set: + mtspr 1008, r3 + se_blr + + +#********************************************************************************************************* +#* READ TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base low register value. +#* +#* CPU_INT32U CPU_TBL_Get (void) +#* Get current TBL value +#* Return +#********************************************************************************************************* + +CPU_TBL_Get: + mfspr r3, 268 + se_blr + + +#********************************************************************************************************* +#* READ TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base high register value. +#* +#* CPU_INT32U CPU_TBU_Get (void) +#* Get current TBU value +#* Return +#********************************************************************************************************* + +CPU_TBU_Get: + mfspr r3, 269 + se_blr + + +#********************************************************************************************************* +#* WRITE TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to set the time base low register value. +#* +#* void CPU_TBL_Set (CPU_INT32U value) +#* Write value into TBL +#* Return +#********************************************************************************************************* + +CPU_TBL_Set: + mtspr 284, r3 + se_blr + + +#********************************************************************************************************* +#* WRITE TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to set the time base high register value. +#* +#* void CPU_TBU_Set (CPU_INT32U value) +#* Write value into TBU +#* Return +#********************************************************************************************************* + +CPU_TBU_Set: + mtspr 285, r3 + se_blr + + +#********************************************************************************************************* +#* READ TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the timer control register value. +#* +#* CPU_INT32U CPU_TCR_Get (void) +#* Get current TCR value +#* Return +#********************************************************************************************************* + +CPU_TCR_Get: + mfTCR r3 + se_blr + + +#********************************************************************************************************* +#* WRITE TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to set the timer control register value. +#* +#* void CPU_TCR_Set (CPU_INT32U value) +#* Write value into TCR +#* Return +#********************************************************************************************************* + +CPU_TCR_Set: + mtTCR r3 + se_blr + + +#********************************************************************************************************* +#* WRITE IVOR REGISTER FUNCTION +#* +#* Description : These functions are used to set the exception handler functions. +#* +#* void CPU_IVORx_Set (CPU_FNCT_VOID fnct) +#* Write fnct address into IVORx +#* Return +#********************************************************************************************************* + +CPU_IVOR0_Set: + mtIVOR0 r3 + se_blr + +CPU_IVOR1_Set: + mtIVOR1 r3 + se_blr + +CPU_IVOR2_Set: + mtIVOR2 r3 + se_blr + +CPU_IVOR3_Set: + mtIVOR3 r3 + se_blr + +CPU_IVOR4_Set: + mtIVOR4 r3 + se_blr + +CPU_IVOR5_Set: + mtIVOR5 r3 + se_blr + +CPU_IVOR6_Set: + mtIVOR6 r3 + se_blr + +CPU_IVOR7_Set: + mtIVOR7 r3 + se_blr + +CPU_IVOR8_Set: + mtIVOR8 r3 + se_blr + +CPU_IVOR9_Set: + mtIVOR9 r3 + se_blr + +CPU_IVOR10_Set: + mtIVOR10 r3 + se_blr + +CPU_IVOR11_Set: + mtIVOR11 r3 + se_blr + +CPU_IVOR12_Set: + mtIVOR12 r3 + se_blr + +CPU_IVOR13_Set: + mtIVOR13 r3 + se_blr + +CPU_IVOR14_Set: + mtIVOR14 r3 + se_blr + +CPU_IVOR15_Set: + mtIVOR15 r3 + se_blr + +CPU_IVOR32_Set: + mtIVOR32 r3 + se_blr + +CPU_IVOR33_Set: + mtIVOR33 r3 + se_blr + +CPU_IVOR34_Set: + mtIVOR34 r3 + se_blr + + +#********************************************************************************************************* +#* CPU ASSEMBLY PORT FILE END +#********************************************************************************************************* + .end diff --git a/MPC56xx/CodeWarrior/cpu.h b/MPC56xx/CodeWarrior/cpu.h new file mode 100644 index 0000000..f81945f --- /dev/null +++ b/MPC56xx/CodeWarrior/cpu.h @@ -0,0 +1,502 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MPC56xx +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +void CPU_DEC_Set (CPU_INT32U val); +void CPU_DECAR_Set (CPU_INT32U val); +CPU_INT32U CPU_HID0_Get (void); +void CPU_HID0_Set (CPU_INT32U val); +CPU_INT32U CPU_TBL_Get (void); +CPU_INT32U CPU_TBU_Get (void); +void CPU_TBL_Set (CPU_INT32U val); +void CPU_TBU_Set (CPU_INT32U val); +CPU_INT32U CPU_TCR_Get (void); +void CPU_TCR_Set (CPU_INT32U val); + +void CPU_IVOR0_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR1_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR2_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR3_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR4_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR5_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR6_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR7_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR8_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR9_Set (CPU_FNCT_VOID fnct); +void CPU_IVOR10_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR11_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR12_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR13_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR14_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR15_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR32_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR33_Set(CPU_FNCT_VOID fnct); +void CPU_IVOR34_Set(CPU_FNCT_VOID fnct); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC56xx/CodeWarrior/cpu_a.s b/MPC56xx/CodeWarrior/cpu_a.s new file mode 100644 index 0000000..aa42108 --- /dev/null +++ b/MPC56xx/CodeWarrior/cpu_a.s @@ -0,0 +1,380 @@ +#********************************************************************************************************* +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#********************************************************************************************************* + +#********************************************************************************************************* +#* +#* CPU PORT FILE +#* +#* Freescale MPC56xx +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#********************************************************************************************************* + + +#********************************************************************************************************* +#* ASM HEADER +#********************************************************************************************************* + + .text + +#********************************************************************************************************* +#* PUBLIC DECLARATIONS +#********************************************************************************************************* + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + .global CPU_DEC_Set + .global CPU_DECAR_Set + .global CPU_HID0_Get + .global CPU_HID0_Set + .global CPU_TBL_Get + .global CPU_TBU_Get + .global CPU_TBL_Set + .global CPU_TBU_Set + .global CPU_TCR_Get + .global CPU_TCR_Set + + .global CPU_IVOR0_Set + .global CPU_IVOR1_Set + .global CPU_IVOR2_Set + .global CPU_IVOR3_Set + .global CPU_IVOR4_Set + .global CPU_IVOR5_Set + .global CPU_IVOR6_Set + .global CPU_IVOR7_Set + .global CPU_IVOR8_Set + .global CPU_IVOR9_Set + .global CPU_IVOR10_Set + .global CPU_IVOR11_Set + .global CPU_IVOR12_Set + .global CPU_IVOR13_Set + .global CPU_IVOR14_Set + .global CPU_IVOR15_Set + .global CPU_IVOR32_Set + .global CPU_IVOR33_Set + .global CPU_IVOR34_Set + + +#********************************************************************************************************* +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#********************************************************************************************************* + +CPU_SR_Save: + mfmsr r3 + wrteei 0 + blr + +CPU_SR_Restore: + mtmsr r3 + blr + + +#********************************************************************************************************* +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#********************************************************************************************************* + +CPU_SR_Rd: + mfmsr r3 + blr + + +#********************************************************************************************************* +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#********************************************************************************************************* + +CPU_IntDis: + wrteei 0 + blr + + +CPU_IntEn: + wrteei 1 + blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer register with a given value. +#* +#* void CPU_DEC_Set (CPU_INT32U value) +#* Write value into DEC +#* Return +#********************************************************************************************************* + +CPU_DEC_Set: + mtDEC r3 + blr + + +#********************************************************************************************************* +#* WRITE DECREMENTER AUTORELOAD REGISTER FUNCTION +#* +#* Description : This function is used to set the decrementer auto-reload register with a given value. +#* +#* void CPU_DECAR_Set (CPU_INT32U value) +#* Write value into DECAR +#* Return +#********************************************************************************************************* + +CPU_DECAR_Set: + mtDECAR r3 + blr + + +#********************************************************************************************************* +#* READ HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the hardware implementation dependent register value. +#* +#* CPU_INT32U CPU_HID0_Get (void) +#* Get current HID0 value +#* Return +#********************************************************************************************************* + +CPU_HID0_Get: + mfspr r3, 1008 + blr + + +#********************************************************************************************************* +#* WRITE HARDWARE IMPLEMENTATION DEPENDENT REGISTER FUNCTION +#* +#* Description : This function is used to set the hardware implementation dependent register value. +#* +#* void CPU_HID0_Set (CPU_INT32U value) +#* Write value into HID0 +#* Return +#********************************************************************************************************* + +CPU_HID0_Set: + mtspr 1008, r3 + blr + + +#********************************************************************************************************* +#* READ TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base low register value. +#* +#* CPU_INT32U CPU_TBL_Get (void) +#* Get current TBL value +#* Return +#********************************************************************************************************* + +CPU_TBL_Get: + mfspr r3, 268 + blr + + +#********************************************************************************************************* +#* READ TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base high register value. +#* +#* CPU_INT32U CPU_TBU_Get (void) +#* Get current TBU value +#* Return +#********************************************************************************************************* + +CPU_TBU_Get: + mfspr r3, 269 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to set the time base low register value. +#* +#* void CPU_TBL_Set (CPU_INT32U value) +#* Write value into TBL +#* Return +#********************************************************************************************************* + +CPU_TBL_Set: + mtspr 284, r3 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to set the time base high register value. +#* +#* void CPU_TBU_Set (CPU_INT32U value) +#* Write value into TBU +#* Return +#********************************************************************************************************* + +CPU_TBU_Set: + mtspr 285, r3 + blr + + +#********************************************************************************************************* +#* READ TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the timer control register value. +#* +#* CPU_INT32U CPU_TCR_Get (void) +#* Get current TCR value +#* Return +#********************************************************************************************************* + +CPU_TCR_Get: + mfTCR r3 + blr + + +#********************************************************************************************************* +#* WRITE TIMER CONTROL REGISTER FUNCTION +#* +#* Description : This function is used to set the timer control register value. +#* +#* void CPU_TCR_Set (CPU_INT32U value) +#* Write value into TCR +#* Return +#********************************************************************************************************* + +CPU_TCR_Set: + mtTCR r3 + blr + + +#********************************************************************************************************* +#* WRITE IVOR REGISTER FUNCTION +#* +#* Description : These functions are used to set the exception handler functions. +#* +#* void CPU_IVORx_Set (CPU_FNCT_VOID fnct) +#* Write fnct address into IVORx +#* Return +#********************************************************************************************************* + +CPU_IVOR0_Set: + mtIVOR0 r3 + blr + +CPU_IVOR1_Set: + mtIVOR1 r3 + blr + +CPU_IVOR2_Set: + mtIVOR2 r3 + blr + +CPU_IVOR3_Set: + mtIVOR3 r3 + blr + +CPU_IVOR4_Set: + mtIVOR4 r3 + blr + +CPU_IVOR5_Set: + mtIVOR5 r3 + blr + +CPU_IVOR6_Set: + mtIVOR6 r3 + blr + +CPU_IVOR7_Set: + mtIVOR7 r3 + blr + +CPU_IVOR8_Set: + mtIVOR8 r3 + blr + +CPU_IVOR9_Set: + mtIVOR9 r3 + blr + +CPU_IVOR10_Set: + mtIVOR10 r3 + blr + +CPU_IVOR11_Set: + mtIVOR11 r3 + blr + +CPU_IVOR12_Set: + mtIVOR12 r3 + blr + +CPU_IVOR13_Set: + mtIVOR13 r3 + blr + +CPU_IVOR14_Set: + mtIVOR14 r3 + blr + +CPU_IVOR15_Set: + mtIVOR15 r3 + blr + +CPU_IVOR32_Set: + mtIVOR32 r3 + blr + +CPU_IVOR33_Set: + mtIVOR33 r3 + blr + +CPU_IVOR34_Set: + mtIVOR34 r3 + blr + + +#********************************************************************************************************* +#* CPU ASSEMBLY PORT FILE END +#********************************************************************************************************* + .end diff --git a/MPC57xx-VLE/GNU/cpu.h b/MPC57xx-VLE/GNU/cpu.h new file mode 100644 index 0000000..4108af1 --- /dev/null +++ b/MPC57xx-VLE/GNU/cpu.h @@ -0,0 +1,495 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* NXP MPC57xx-VLE +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm("mbar 0") + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Rd (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* NO-OP +********************************************************************************************************* +*/ + +#define CPU_NOP() __asm("e_xori 0,0,0"); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC57xx-VLE/GNU/cpu_a.S b/MPC57xx-VLE/GNU/cpu_a.S new file mode 100644 index 0000000..d3daf81 --- /dev/null +++ b/MPC57xx-VLE/GNU/cpu_a.S @@ -0,0 +1,113 @@ +#******************************************************************************************************** +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#******************************************************************************************************** + +#******************************************************************************************************** +#* +#* CPU PORT FILE +#* +#* NXP MPC57xx-VLE +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#******************************************************************************************************** + + +#******************************************************************************************************** +#* ASM HEADER +#******************************************************************************************************** + + .text + +#******************************************************************************************************** +# PUBLIC DECLARATIONS +#******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + + +#******************************************************************************************************** +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#******************************************************************************************************** + +CPU_SR_Save: + mfmsr r3 + wrteei 0 + se_blr + +CPU_SR_Restore: + wrtee r3 + se_blr + + +#******************************************************************************************************** +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#******************************************************************************************************** + +CPU_SR_Rd: + mfmsr r3 + se_blr + + +#******************************************************************************************************** +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#******************************************************************************************************** + +CPU_IntDis: + wrteei 0 + se_blr + + +CPU_IntEn: + wrteei 1 + se_blr + + +#******************************************************************************************************** +#* CPU ASSEMBLY PORT FILE END +#******************************************************************************************************** + .end diff --git a/MPC8349E/CodeWarrior/cpu.h b/MPC8349E/CodeWarrior/cpu.h new file mode 100644 index 0000000..816d4c6 --- /dev/null +++ b/MPC8349E/CodeWarrior/cpu.h @@ -0,0 +1,480 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Freescale MPC8349E +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + /* MSR (Machine State Register) handling. */ +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Rd (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + /* Time Base for the timer of uC/Probe. */ +CPU_INT32U CPU_TBL_Get (void); +CPU_INT32U CPU_TBU_Get (void); +void CPU_TBL_Set (CPU_INT32U val); +void CPU_TBU_Set (CPU_INT32U val); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MPC8349E/CodeWarrior/cpu_a.s b/MPC8349E/CodeWarrior/cpu_a.s new file mode 100644 index 0000000..7c62187 --- /dev/null +++ b/MPC8349E/CodeWarrior/cpu_a.s @@ -0,0 +1,183 @@ +#********************************************************************************************************* +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#********************************************************************************************************* + +#********************************************************************************************************* +#* +#* CPU PORT FILE +#* +#* Freescale MPC8349E +#* +#* Filename : cpu_a.s +#* Version : v1.32.00 +#********************************************************************************************************* + + +#********************************************************************************************************* +#* ASM HEADER +#********************************************************************************************************* + + .text + +#********************************************************************************************************* +#* PUBLIC DECLARATIONS +#********************************************************************************************************* + + .global CPU_SR_Save + .global CPU_SR_Restore + .global CPU_SR_Rd + .global CPU_IntDis + .global CPU_IntEn + .global CPU_TBL_Get + .global CPU_TBU_Get + .global CPU_TBL_Set + .global CPU_TBU_Set + + +#********************************************************************************************************* +#* CRITICAL SECTION FUNCTIONS +#* +#* Description : These functions are used to enter and exit critical sections using Critical Method #3. +#* +#* CPU_SR CPU_SR_Save (void) +#* Get current global interrupt mask bit value from MSR +#* Disable interrupts +#* Return global interrupt mask bit +#* +#* void CPU_SR_Restore (CPU_SR cpu_sr) +#* Set global interrupt mask bit on MSR according to parameter cpu_sr +#* Return +#* +#* Argument(s) : cpu_sr global interrupt mask status. +#********************************************************************************************************* + +CPU_SR_Save: + mfmsr r3 + mfmsr r5 # Preparation for disabling interrupts (1) + andi. r5,r5,0x7fff # Preparation for disabling interrupts : set EE (bit #16) to '0' (2) + mtmsr r5 # Disable interrupts + blr + +CPU_SR_Restore: + mtmsr r3 + blr + + +#********************************************************************************************************* +#* READ STATUS REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the status register value. +#* +#* CPU_SR CPU_SR_Rd (void) +#* Get current MSR value +#* Return +#********************************************************************************************************* + +CPU_SR_Rd: + mfmsr r3 + blr + + +#********************************************************************************************************* +#* DISABLE/ENABLE INTERRUPTS +#* +#* Description : Disable/Enable interrupts by setting or clearing the global interrupt mask in the cpu +#* status register. +#* +#* void CPU_IntDis (void) +#* Set global interrupt mask bit on MSR +#* Return +#* +#* void CPU_IntEn (void) +#* Clear global interrupt mask bit on MSR +#* Return +#********************************************************************************************************* + +CPU_IntDis: + mfmsr r5 # Preparation for disabling interrupts (1) + andi. r5,r5,0x7fff # Preparation for disabling interrupts : set EE (bit #16) to '0' (2) + mtmsr r5 # Disable interrupts + blr + + +CPU_IntEn: + mfmsr r5 # Preparation for enabling interrupts (1) + ori r5,r5,0x8000 # Preparation for enabling interrupts : set EE (bit #16) to '1'(2) + mtmsr r5 # Enable interrupts + blr + + +#********************************************************************************************************* +#* READ TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base low register value. +#* +#* CPU_INT32U CPU_TBL_Get (void) +#* Get current TBL value +#* Return +#********************************************************************************************************* + +CPU_TBL_Get: + mfspr r3, 268 + blr + + +#********************************************************************************************************* +#* READ TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to retrieve the time base high register value. +#* +#* CPU_INT32U CPU_TBU_Get (void) +#* Get current TBU value +#* Return +#********************************************************************************************************* + +CPU_TBU_Get: + mfspr r3, 269 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE LOW REGISTER FUNCTION +#* +#* Description : This function is used to set the time base low register value. +#* +#* void CPU_TBL_Set (CPU_INT32U value) +#* Write value into TBL +#* Return +#********************************************************************************************************* + +CPU_TBL_Set: + mtspr 284, r3 + blr + + +#********************************************************************************************************* +#* WRITE TIME BASE HIGH REGISTER FUNCTION +#* +#* Description : This function is used to set the time base high register value. +#* +#* void CPU_TBU_Set (CPU_INT32U value) +#* Write value into TBU +#* Return +#********************************************************************************************************* + +CPU_TBU_Set: + mtspr 285, r3 + blr + + +#********************************************************************************************************* +#* CPU ASSEMBLY PORT FILE END +#********************************************************************************************************* + .end diff --git a/MSP430X/CCS/cpu.h b/MSP430X/CCS/cpu.h new file mode 100644 index 0000000..826d24c --- /dev/null +++ b/MSP430X/CCS/cpu.h @@ -0,0 +1,473 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* TI MSP430X +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MSP430X/CCS/cpu_a.s43 b/MSP430X/CCS/cpu_a.s43 new file mode 100644 index 0000000..dffb3a3 --- /dev/null +++ b/MSP430X/CCS/cpu_a.s43 @@ -0,0 +1,100 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; TI MSP430X +; MSP430x5xx +; +; Filename : cpu_a.s43 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + .text ; Program code + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) R12 is assumed to hold the argument passed to CPU_SR_Save() & also the value returned +; by CPU_SR_Restore(). +;******************************************************************************************************** + + .asmfunc +CPU_SR_Save: + MOV.W SR, R12 + DINT + NOP + RETA + .endasmfunc + + .asmfunc +CPU_SR_Restore: + MOV.W R12, SR + NOP + RETA + .endasmfunc + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .end + diff --git a/MSP430X/IAR/cpu.h b/MSP430X/IAR/cpu.h new file mode 100644 index 0000000..826d24c --- /dev/null +++ b/MSP430X/IAR/cpu.h @@ -0,0 +1,473 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* TI MSP430X +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MSP430X/IAR/cpu_a.s43 b/MSP430X/IAR/cpu_a.s43 new file mode 100644 index 0000000..ad18c95 --- /dev/null +++ b/MSP430X/IAR/cpu_a.s43 @@ -0,0 +1,95 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; TI MSP430X +; MSP430x5xx +; +; Filename : cpu_a.s43 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE ; Program code + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +; +; (2) R12 is assumed to hold the argument passed to CPU_SR_Save() & also the value returned +; by CPU_SR_Restore(). +;******************************************************************************************************** + +CPU_SR_Save + MOV.W SR, R12 + DINT + RETA + + +CPU_SR_Restore + MOV.W R12, SR + RETA + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/MicroBlaze/GNU/cpu.h b/MicroBlaze/GNU/cpu.h new file mode 100644 index 0000000..c1aca89 --- /dev/null +++ b/MicroBlaze/GNU/cpu.h @@ -0,0 +1,496 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MicroBlaze +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + + /* Defines CPU data word-memory order (see Note #2). */ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("mbar 1" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("mbar 1" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("mbar 1" : : : "memory") + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore (CPU_SR cpu_sr); + +void CPU_CacheDataFlush (void *addr, CPU_INT32U len); +void CPU_CacheDataInvalidate (void *addr, CPU_INT32U len); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/MicroBlaze/GNU/cpu_a.S b/MicroBlaze/GNU/cpu_a.S new file mode 100644 index 0000000..69d8baf --- /dev/null +++ b/MicroBlaze/GNU/cpu_a.S @@ -0,0 +1,162 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* MicroBlaze +* GNU C Compiler +* +* Filename : cpu_a.S +* Version : v1.32.00 +********************************************************************************************************* +*/ + +#define _ASMLANGUAGE + +#include + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + + .globl CPU_SR_Save + .globl CPU_SR_Restore + +/* +********************************************************************************************************* +* EQUATES +********************************************************************************************************* +*/ + +.equ CPU_IE_BIT, 0x02 + +.text + + +/* +********************************************************************************************************* +* DISABLE INTERRUPTS +* CPU_SR CPU_SR_Save(void); +* +* Description : Disables the interrupts and returns the RMSR contents. This allows the IE state to be +* restored at a subsequent time. +* +* The variable in the calling routine which the return is set to MUST be declared 'volatile' +* for proper operation. There is no guarantee that the proper register will be scheduled +* for the subsequent 'CPU_SR_Save()' function call if the variable is not declared +* 'volatile'. +* +* Arguments : None +* +* Returns : Current RMSR contents in R3 +* +* Note(s) : This function uses the MSRCLR instruction, which is not, by default, recognized by +* MicroBlaze processors. Setting the paramter C_USE_MSR_INSTR to '1' in the MHS file +* allows the processor to recognize this instruction. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_MB_HAS_MSR_INST +CPU_SR_Save: + RTSD r15, 8 + MSRCLR r3, CPU_IE_BIT /* Save MSR in r3 and disable interrupts */ +#else +CPU_SR_Save: + ADDIK r1, r1, -4 /* Save R4 since it's used as a scratchpad register */ + SW r4, r1, r0 + + MFS r3, RMSR /* Read the MSR. r3 is used as the return value */ + ANDNI r4, r3, CPU_IE_BIT /* Mask off the IE bit */ + MTS RMSR, r4 /* Store the MSR */ + + LW r4, r1, r0 /* Restore R4 */ + ADDIK r1, r1, 4 + + AND r0, r0, r0 /* NO-OP - pipeline flush */ + AND r0, r0, r0 /* NO-OP - pipeline flush */ + AND r0, r0, r0 /* NO-OP - pipeline flush */ + + RTSD r15, 8 /* Return to caller with R3 containing original RMSR */ + AND r0, r0, r0 /* NO-OP */ +#endif + + +/* +********************************************************************************************************* +* ENABLE INTERRUPTS +* void CPU_SR_Restore(CPU_SR sr); +* +* Description: Enables the interrupts using the provided data. If the IE bit is set in the argument, the +* RTID opcode is used to return. If the IE bis is clear, the standard RTSD is used leaving +* the interrupts disabled. +* +* The argument from the calling routine MUST be declared 'volatile' for proper operation. +* There is no guarantee that the proper register will be scheduled for the 'CPU_SR_Restore()' +* function call if the variable is not declared 'volatile'. +* +* Arguments : Saved RMSR contents in R5 +* +* Returns : None +* +* Note(s) : None +********************************************************************************************************* +*/ + +CPU_SR_Restore: + RTSD r15, 8 + MTS rMSR, r5 /* Move the saved status from r5 into rMSR */ + + +/* +******************************************************************************************************** +* CPU_CntLeadZeros() +* COUNT LEADING ZEROS +* +* Description : Counts the number of contiguous, most-significant, leading zero bits before the first +* binary one bit in a data value. +* +* Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) If the argument is zero, the value 32 is returned. +* +* (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is +* #define'd in 'cpu_cfg.h' or 'cpu.h'. +******************************************************************************************************** +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +.globl CPU_CntLeadZeros +CPU_CntLeadZeros: + RTSD r15, 8 + CLZ r3, r5 +#endif + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/MicroBlaze/GNU/cpu_c.c b/MicroBlaze/GNU/cpu_c.c new file mode 100644 index 0000000..d5adb9a --- /dev/null +++ b/MicroBlaze/GNU/cpu_c.c @@ -0,0 +1,97 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microblaze +* GNU +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_FlushDCache() +* +* Description : Flush a specific range in the cache memory +* +* Argument(s) : addr the start address of the memory area to flush +* len the size of the memory area to flush +* +* Return(s) : none. +* +* Note(s) : The function uses microblaze_flush_dcache_range() which is part of Xilinx libraries +********************************************************************************************************* +*/ + +void CPU_CacheDataFlush (void *addr, + CPU_INT32U len) +{ + microblaze_flush_dcache_range((CPU_INT32S)addr, len); +} + +/* +********************************************************************************************************* +* CPU_InvalidateDCache() +* +* Description : Invalide a specific range in the cache memory +* +* Argument(s) : addr the start address of the memory area to invalidate +* len the size of the memory area to invalidate +* +* Return(s) : none. +* +* Note(s) : The function uses microblaze_invalidate_dcache_range() which is part of Xilinx libraries +********************************************************************************************************* +*/ + +void CPU_CacheDataInvalidate (void *addr, + CPU_INT32U len) +{ + microblaze_invalidate_dcache_range((CPU_INT32S)addr, len); +} + +#ifdef __cplusplus +} +#endif + diff --git a/NiosII/GNU/cpu.h b/NiosII/GNU/cpu.h new file mode 100644 index 0000000..8706501 --- /dev/null +++ b/NiosII/GNU/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Nios II +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include "sys/alt_irq.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/NiosII/GNU/cpu_c.c b/NiosII/GNU/cpu_c.c new file mode 100644 index 0000000..3a7abea --- /dev/null +++ b/NiosII/GNU/cpu_c.c @@ -0,0 +1,87 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Nios II +* GNU C Compiler +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CPU_SR_Save() +* +* Description : This function disables interrupts for critical sections of code. +* +* Argument(s) : none. +* +* Return(s) : The CPU's status register, so that interrupts can later be returned to their original +* state. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void) +{ + return (alt_irq_disable_all()); +} + + +/* +********************************************************************************************************* +* CPU_SR_Restore() +* +* Description : Restores interrupts after critical sections of code. +* +* Argument(s) : cpu_sr The interrupt status that will be restored. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_SR_Restore (CPU_SR cpu_sr) +{ + alt_irq_enable_all(cpu_sr); +} + +#ifdef __cplusplus +} +#endif diff --git a/PIC24FJ128/C30/cpu.h b/PIC24FJ128/C30/cpu.h new file mode 100644 index 0000000..092346d --- /dev/null +++ b/PIC24FJ128/C30/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip PIC24FJ +* Microchip C30 Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { SRbits.IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { SRbits.IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + SRbits.IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC24FJ128/DSPICC/cpu.h b/PIC24FJ128/DSPICC/cpu.h new file mode 100644 index 0000000..3a4fc7a --- /dev/null +++ b/PIC24FJ128/DSPICC/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip PIC24FJ +* Hi-Tech dsPICC Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { SRbits.IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { SRbits.IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + SRbits.IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC24FJ128/ICCDSPIC/cpu.h b/PIC24FJ128/ICCDSPIC/cpu.h new file mode 100644 index 0000000..040922b --- /dev/null +++ b/PIC24FJ128/ICCDSPIC/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip PIC24FJ +* ICCDSPIC +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC30F6014/C30/cpu.h b/PIC30F6014/C30/cpu.h new file mode 100644 index 0000000..0b9ff6e --- /dev/null +++ b/PIC30F6014/C30/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip dsPIC33FJ +* Microchip C30 Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { SRbits.IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { SRbits.IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + SRbits.IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC33FJ256/C30/cpu.h b/PIC33FJ256/C30/cpu.h new file mode 100644 index 0000000..95c7f82 --- /dev/null +++ b/PIC33FJ256/C30/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip dsPIC33FJ +* Microchip C30 Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { SRbits.IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { SRbits.IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + SRbits.IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC33FJ256/DSPICC/cpu.h b/PIC33FJ256/DSPICC/cpu.h new file mode 100644 index 0000000..e66ac83 --- /dev/null +++ b/PIC33FJ256/DSPICC/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip dsPIC33FJ +* Hi-Tech dsPICC Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { SRbits.IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { SRbits.IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + SRbits.IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PIC33FJ256/ICCDSPIC/cpu.h b/PIC33FJ256/ICCDSPIC/cpu.h new file mode 100644 index 0000000..1b0a8a2 --- /dev/null +++ b/PIC33FJ256/ICCDSPIC/cpu.h @@ -0,0 +1,470 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Microchip dsPIC33FJ +* ICCDSPIC +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer (ANSI89-EXTENSION) */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer (ANSI89-EXTENSION) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_LO_TO_HI /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { IPL = 7; } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { IPL = 0; } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = SR; \ + IPL = 7; } while (0) +#define CPU_INT_EN() do { SR = cpu_sr; } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/PPC405/GNU/cpu.h b/PPC405/GNU/cpu.h new file mode 100644 index 0000000..799a852 --- /dev/null +++ b/PPC405/GNU/cpu.h @@ -0,0 +1,469 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* PPC405 +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (16u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/PPC405/GNU/cpu_a.s b/PPC405/GNU/cpu_a.s new file mode 100644 index 0000000..609cc2d --- /dev/null +++ b/PPC405/GNU/cpu_a.s @@ -0,0 +1,131 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* PPC405 +* GNU C Compiler +* +* Filename : cpu_a.s +* Version : v1.32.00 +********************************************************************************************************* +*/ + +#define _ASMLANGUAGE + +/* +********************************************************************************************************* +* PUBLIC FUNCTIONS +********************************************************************************************************* +*/ + + .globl CPU_SR_Save + .globl CPU_SR_Restore + + +.text + + +/* +********************************************************************************************************* +* CRITICAL SECTION FUNCTIONS +* +* Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +* state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +* are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +* The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +* +* Prototypes : CPU_SR CPU_SR_Save (void); +* void CPU_SR_Restore(CPU_SR cpu_sr); +* +* Note(s) : (1) These functions are used in general like this : +* +* void Task (void *p_arg) +* { +* CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +* : +* : +* CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +* : +* : +* CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +* : +* } +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* DISABLE INTERRUPTS +* CPU_SR CPU_SR_Save(void); +* +* Description : Sets the MSR, disabling interrupts, and returns the previous MSR contents. This allows +* the machine state to be restored at a subsequent time. +* +* Arguments : None +* +* Returns : Current MSR contents in GPR3 +* +* Note(s) : 1) The variable in the calling routine that will hold the return value MUST be declared +* volatile for proper operation. There is no guarantee that the proper register will +* be scheduled for the subsequent 'CPU_SR_Save()' function call if the variable is +* not declared volatile. +********************************************************************************************************* +*/ + +CPU_SR_Save: + + addis 4, 0, 0xFFFD + ori 4, 4, 0x7FFF + mfmsr 3 + and 4, 4, 3 /* Clear bits 14 and 16, corresponding to... */ + mtmsr 4 /* ...critical and non-critical interrupts */ + blr + + +/* +********************************************************************************************************* +* ENABLE INTERRUPTS +* void CPU_SR_Restore(CPU_SR sr); +* +* Description : Sets the MSR, possibly enabling interrupts, using the value passed in GPR3. +* +* Arguments : Saved MSR contents in GPR3 +* +* Returns : None +* +* Note(s) : 1) The argument from the calling routine MUST be declared volatile for proper operation. +* There is no guarantee that the proper register will be scheduled for the call to +* CPU_SR_Restore() if the variable is not declared 'volatile'. +********************************************************************************************************* +*/ + +CPU_SR_Restore: + + mtmsr 3 /* Restore the saved MSR */ + blr + + +/* +********************************************************************************************************* +* CPU ASSEMBLY PORT FILE END +********************************************************************************************************* +*/ + diff --git a/Posix/GNU/cpu.h b/Posix/GNU/cpu.h new file mode 100644 index 0000000..d276253 --- /dev/null +++ b/Posix/GNU/cpu.h @@ -0,0 +1,535 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Linux i86pc & amd64 +* GNU Toolchain +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include +#include + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef uint8_t CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef uint8_t CPU_INT08U; /* 8-bit unsigned integer */ +typedef int8_t CPU_INT08S; /* 8-bit signed integer */ +typedef uint16_t CPU_INT16U; /* 16-bit unsigned integer */ +typedef int16_t CPU_INT16S; /* 16-bit signed integer */ +typedef uint32_t CPU_INT32U; /* 32-bit unsigned integer */ +typedef int32_t CPU_INT32S; /* 32-bit signed integer */ +typedef uint64_t CPU_INT64U; /* 64-bit unsigned integer */ +typedef int64_t CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + + +typedef struct CPU_Interrupt CPU_INTERRUPT; + +struct CPU_Interrupt { + void (*ISR_Fnct)(void); + CPU_INT08U Prio; + CPU_BOOLEAN En; + CPU_CHAR *NamePtr; + CPU_BOOLEAN TraceEn; +}; + + +typedef struct CPU_Tmr_Interrupt CPU_TMR_INTERRUPT; + +struct CPU_Tmr_Interrupt { + CPU_INTERRUPT Interrupt; + CPU_BOOLEAN OneShot; + CPU_INT32U PeriodSec; + CPU_INT32U PeriodMuSec; +}; + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#ifdef _LP64 +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_64 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_64 /* Defines CPU data word size (in octets). */ +#else +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#endif + + +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#else +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef size_t CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_INT_DIS_EN + +typedef CPU_BOOLEAN CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntInit (void); +void CPU_IntEnd (void); + +void CPU_IntDis (void); +void CPU_IntEn (void); + +void CPU_ISR_End (void); + +void CPU_TmrInterruptCreate (CPU_TMR_INTERRUPT *p_tmr_interrupt); + +void CPU_InterruptTrigger (CPU_INTERRUPT *p_interrupt); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/Posix/GNU/cpu_c.c b/Posix/GNU/cpu_c.c new file mode 100644 index 0000000..73dd77d --- /dev/null +++ b/Posix/GNU/cpu_c.c @@ -0,0 +1,885 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* POSIX +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +* Notes : (1) Requires a Single UNIX Specification, Version 3 compliant operating environment. +* On Linux _XOPEN_SOURCE must be defined to at least 600, generally by passing the +* -D_XOPEN_SOURCE=600 command line option to GCC. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + +#define CPU_TMR_INT_TASK_PRIO sched_get_priority_max(SCHED_RR) /* Tmr interrupt task priority. */ +#define CPU_IRQ_SIG (SIGURG) /* IRQ trigger signal. */ + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + +typedef struct cpu_interrupt_node CPU_INTERRUPT_NODE; + +struct cpu_interrupt_node { + CPU_INTERRUPT *InterruptPtr; + CPU_INTERRUPT_NODE *NextPtr; +}; + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +static pthread_mutex_t CPU_InterruptQueueMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutexattr_t CPU_InterruptQueueMutexAttr; + +static CPU_INTERRUPT_NODE *CPU_InterruptPendListHeadPtr; +static CPU_INTERRUPT_NODE *CPU_InterruptRunningListHeadPtr; + +static sigset_t CPU_IRQ_SigMask; + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +#if (_POSIX_C_SOURCE < 199309L) +#error "_POSIX_C_SOURCE is required to be at least 199309L" +#endif + +static void CPU_IRQ_Handler (int sig); + +static void CPU_InterruptTriggerInternal (CPU_INTERRUPT *p_interrupt); + +static void CPU_InterruptQueue (CPU_INTERRUPT *p_isr); + +static void *CPU_TmrInterruptTask (void *p_arg); + +static void CPU_ISR_Sched (void); + + +/* +********************************************************************************************************* +* CPU_IntInit() +* +* Description : This function initializes the critical section. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : 1) CPU_IntInit() MUST be called prior to use any of the CPU_IntEn(), and CPU_IntDis() +* functions. +********************************************************************************************************* +*/ + +void CPU_IntInit (void) +{ + struct sigaction on_isr_trigger_sig_action; + int res; + + + CPU_InterruptPendListHeadPtr = DEF_NULL; + CPU_InterruptRunningListHeadPtr = DEF_NULL; + + sigemptyset(&CPU_IRQ_SigMask); + sigaddset(&CPU_IRQ_SigMask, CPU_IRQ_SIG);; + + pthread_mutexattr_init(&CPU_InterruptQueueMutexAttr); + pthread_mutexattr_settype(&CPU_InterruptQueueMutexAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&CPU_InterruptQueueMutex, &CPU_InterruptQueueMutexAttr); + + /* Register interrupt trigger signal handler. */ + memset(&on_isr_trigger_sig_action, 0, sizeof(on_isr_trigger_sig_action)); + res = sigemptyset(&on_isr_trigger_sig_action.sa_mask); + if (res != 0u) { + raise(SIGABRT); + } + on_isr_trigger_sig_action.sa_flags = SA_NODEFER; + on_isr_trigger_sig_action.sa_handler = CPU_IRQ_Handler; + res = sigaction(CPU_IRQ_SIG, &on_isr_trigger_sig_action, NULL); + if (res != 0u) { + raise(SIGABRT); + } +} + + +/* +********************************************************************************************************* +* CPU_IntDis() +* +* Description : This function disables interrupts for critical sections of code. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntDis (void) +{ + pthread_sigmask(SIG_BLOCK, &CPU_IRQ_SigMask, DEF_NULL); +} + + +/* +********************************************************************************************************* +* CPU_IntEn() +* +* Description : This function enables interrupts after critical sections of code. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntEn (void) +{ + pthread_sigmask(SIG_UNBLOCK, &CPU_IRQ_SigMask, DEF_NULL); +} + + +/* +********************************************************************************************************* +* CPU_ISR_End() +* +* Description : Ends an ISR. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) This function MUST be called at the end of an ISR. +* +********************************************************************************************************* +*/ + +void CPU_ISR_End (void) +{ + CPU_INTERRUPT_NODE *p_interrupt_node; + + + CPU_INT_DIS(); + pthread_mutex_lock(&CPU_InterruptQueueMutex); + if (CPU_InterruptRunningListHeadPtr == DEF_NULL) { + raise(SIGABRT); + } + p_interrupt_node = CPU_InterruptRunningListHeadPtr; + CPU_InterruptRunningListHeadPtr = CPU_InterruptRunningListHeadPtr->NextPtr; + pthread_mutex_unlock(&CPU_InterruptQueueMutex); + CPU_INT_EN(); + + free(p_interrupt_node); + + CPU_ISR_Sched(); +} + + +/* +********************************************************************************************************* +* CPU_TmrInterruptCreate() +* +* Description : Simulated hardware timer instance creation. +* +* Argument(s) : p_tmr_interrupt Pointer to a timer interrupt descriptor. +* +* Return(s) : none. +* +* Note(s) : none. +* +********************************************************************************************************* +*/ + +void CPU_TmrInterruptCreate (CPU_TMR_INTERRUPT *p_tmr_interrupt) +{ + pthread_t thread; + pthread_attr_t attr; + struct sched_param param; + int res; + + + res = pthread_attr_init(&attr); + if (res != 0u) { + raise(SIGABRT); + } + res = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + if (res != 0u) { + raise(SIGABRT); + } + param.__sched_priority = CPU_TMR_INT_TASK_PRIO; + pthread_attr_setschedpolicy(&attr, SCHED_RR); + if (res != 0u) { + raise(SIGABRT); + } + pthread_attr_setschedparam(&attr, ¶m); + if (res != 0u) { + raise(SIGABRT); + } + + pthread_create(&thread, &attr, CPU_TmrInterruptTask, p_tmr_interrupt); +} + + +/* +********************************************************************************************************* +* CPU_InterruptTrigger() +* +* Description : Queue an interrupt and send the IRQ signal. +* +* Argument(s) : p_interrupt Interrupt to be queued. +* +* Return(s) : none. +* +* Note(s) : none. +* +********************************************************************************************************* +*/ + +void CPU_InterruptTrigger (CPU_INTERRUPT *p_interrupt) +{ + CPU_INT_DIS(); + CPU_InterruptTriggerInternal(p_interrupt); /* Signal are now blocked: rest of Trigger is internal. */ + CPU_INT_EN(); +} + + +/* +********************************************************************************************************* +* CPU_Printf() +* +* Description: This function is analog of printf. +* +* Arguments : p_str Pointer to format string output. +* +* Returns : Number of characters written. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_MSG_TRACE_EN +static int CPU_Printf (char *p_str, ...) +{ + +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s). +* +* 0, otherwise. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* 0 0 0 1 x x x x 3 +* 0 0 0 0 1 x x x 4 +* 0 0 0 0 0 1 x x 5 +* 0 0 0 0 0 0 1 x 6 +* 0 0 0 0 0 0 0 1 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 11 +* 0 0 0 0 1 x x x 12 +* 0 0 0 0 0 1 x x 13 +* 0 0 0 0 0 0 1 x 14 +* 0 0 0 0 0 0 0 1 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +* +* (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntLeadZeros (CPU_DATA val) +{ + +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* (4) 64-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* x x x x 1 0 0 0 3 +* x x x 1 0 0 0 0 4 +* x x 1 0 0 0 0 0 5 +* x 1 0 0 0 0 0 0 6 +* 1 0 0 0 0 0 0 0 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 11 +* x x x 1 0 0 0 0 12 +* x x 1 0 0 0 0 0 13 +* x 1 0 0 0 0 0 0 14 +* 1 0 0 0 0 0 0 0 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 27 +* x x x 1 0 0 0 0 28 +* x x 1 0 0 0 0 0 29 +* x 1 0 0 0 0 0 0 30 +* 1 0 0 0 0 0 0 0 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (4) For 64-bit values : +* +* b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 59 +* x x x 1 0 0 0 0 60 +* x x 1 0 0 0 0 0 61 +* x 1 0 0 0 0 0 0 62 +* 1 0 0 0 0 0 0 0 63 +* 0 0 0 0 0 0 0 0 64 +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) CPU_CntTrailZeros()'s final conditional statement calculates 'val's number of +* trailing zeros based on its return data size, 'CPU_CFG_DATA_SIZE', & 'val's +* calculated number of lead zeros ONLY if the initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final statement. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntTrailZeros (CPU_DATA val) +{ + +} +#endif + +/* +********************************************************************************************************* +* CPU_TS_TmrInit() +* +* Description : Initialize & start CPU timestamp timer. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (c) When applicable, timer period SHOULD be less than the typical measured time +* but MUST be less than the maximum measured time; otherwise, timer resolution +* inadequate to measure desired times. +* +* See also 'CPU_TS_TmrRd() Note #2'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +void CPU_TS_TmrInit (void) +{ + struct timespec res; + + + res.tv_sec = 0; + res.tv_nsec = 0; + + (void)clock_settime(CLOCK_MONOTONIC, &res); + + CPU_TS_TmrFreqSet(1000000000); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrRd() +* +* Description : Get current CPU timestamp timer count value. +* +* Argument(s) : none. +* +* Return(s) : Timestamp timer count (see Notes #2a & #2b). +* +* Note(s) : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (1) If timer is a 'down' counter whose values decrease with each time count, +* then the returned timer value MUST be ones-complemented. +* +* (c) (1) When applicable, the amount of time measured by CPU timestamps is +* calculated by either of the following equations : +* +* (A) Time measured = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Time measured Amount of time measured, in same +* units of (fractional) seconds +* as the Timer period +* +* Number timer counts +* (B) Time measured = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Time measured Amount of time measured, in seconds +* +* (2) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_TS_TMR CPU_TS_TmrRd (void) +{ + struct timespec res; + CPU_TS_TMR ts; + + + (void)clock_gettime(CLOCK_MONOTONIC, &res); + + ts = (CPU_TS_TMR)(res.tv_sec * 1000000000u + res.tv_nsec); + + return (ts); +} +#endif + + +#ifdef __cplusplus +} +#endif + + +/* +********************************************************************************************************* +********************************************************************************************************* +* LOCAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_IRQ_Handler() +* +* Description : CPU_IRQ_SIG signal handler. +* +* Argument(s) : sig Signal that triggered the handler (unused). +* +* Return(s) : none. +* +* Note(s) : none. +* +********************************************************************************************************* +*/ + +static void CPU_IRQ_Handler (int sig) +{ + (void)&sig; + CPU_ISR_Sched(); +} + + +/* +********************************************************************************************************* +* CPU_InterruptTriggerInternal() +* +* Description : Queue an interrupt and send the IRQ signal. +* +* Argument(s) : p_interrupt Interrupt to be queued. +* +* Return(s) : none. +* +* Note(s) : (1) The Interrupt signal must be blocked before calling this function. +********************************************************************************************************* +*/ + +void CPU_InterruptTriggerInternal (CPU_INTERRUPT *p_interrupt) +{ + if (p_interrupt->En == DEF_NO) { + return; + } + + CPU_InterruptQueue(p_interrupt); + + kill(getpid(), CPU_IRQ_SIG); + + if (p_interrupt->TraceEn == DEF_ENABLED) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + printf("@ %lu:%06lu", ts.tv_sec, ts.tv_nsec / 1000u); + printf(" %s interrupt fired.\r\n", p_interrupt->NamePtr); + } +} + + +/* +********************************************************************************************************* +* CPU_InterruptQueue() +* +* Description : Queue an interrupt. +* +* Argument(s) : p_interrupt Pointer to the interrupt to be queued. +* +* Return(s) : none. +* +* Note(s) : (1) The signals for this thread are already blocked during this function call. +* +* (2) Since the signal are already blocked, it is safe to lock and release the mutex. +********************************************************************************************************* +*/ + +static void CPU_InterruptQueue (CPU_INTERRUPT *p_interrupt) +{ + CPU_INTERRUPT_NODE *p_cur_interrupt_node; + CPU_INTERRUPT_NODE *p_prev_interrupt_node; + CPU_INTERRUPT_NODE *p_interrupt_node; + + + p_interrupt_node = (CPU_INTERRUPT_NODE *)malloc(sizeof(CPU_INTERRUPT_NODE)); + p_interrupt_node->InterruptPtr = p_interrupt; + + pthread_mutex_lock(&CPU_InterruptQueueMutex); + if ((CPU_InterruptPendListHeadPtr == DEF_NULL) || + (CPU_InterruptPendListHeadPtr->InterruptPtr->Prio < p_interrupt->Prio)) { + p_interrupt_node->NextPtr = CPU_InterruptPendListHeadPtr; + CPU_InterruptPendListHeadPtr = p_interrupt_node; + } else { + p_cur_interrupt_node = CPU_InterruptPendListHeadPtr; + while ((p_cur_interrupt_node != DEF_NULL) && + (p_cur_interrupt_node->InterruptPtr->Prio >= p_interrupt->Prio)) { + p_prev_interrupt_node = p_cur_interrupt_node; + p_cur_interrupt_node = p_cur_interrupt_node->NextPtr; + } + p_prev_interrupt_node->NextPtr = p_interrupt_node; + p_interrupt_node->NextPtr = p_cur_interrupt_node; + } + pthread_mutex_unlock(&CPU_InterruptQueueMutex); +} + + +/* +********************************************************************************************************* +* CPU_ISR_Sched() +* +* Description : Schedules the highest priority pending interrupt. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +* +********************************************************************************************************* +*/ + +static void CPU_ISR_Sched (void) +{ + CPU_INTERRUPT_NODE *p_isr_node; + + + CPU_INT_DIS(); + pthread_mutex_lock(&CPU_InterruptQueueMutex); + p_isr_node = CPU_InterruptPendListHeadPtr; + if ((p_isr_node != DEF_NULL) && + ((CPU_InterruptRunningListHeadPtr == DEF_NULL) || + (p_isr_node->InterruptPtr->Prio > CPU_InterruptRunningListHeadPtr->InterruptPtr->Prio))) { + CPU_InterruptPendListHeadPtr = CPU_InterruptPendListHeadPtr->NextPtr; + p_isr_node->NextPtr = CPU_InterruptRunningListHeadPtr; + CPU_InterruptRunningListHeadPtr = p_isr_node; + pthread_mutex_unlock(&CPU_InterruptQueueMutex); + CPU_INT_EN(); + p_isr_node->InterruptPtr->ISR_Fnct(); + } else { + pthread_mutex_unlock(&CPU_InterruptQueueMutex); + CPU_INT_EN(); + } +} + + +/* +********************************************************************************************************* +* CPU_TmrInterruptTask() +* +* Description : Hardware timer interrupt simulation function. +* +* Argument(s) : p_arg Pointer to a timer interrupt descriptor. +* +* Return(s) : none. +* +* Note(s) : none. +* +********************************************************************************************************* +*/ + +static void *CPU_TmrInterruptTask (void *p_arg) { + + struct timespec tspec, tspec_rem; + int res; + CPU_TMR_INTERRUPT *p_tmr_int; + CPU_BOOLEAN one_shot; + + CPU_INT_DIS(); + + p_tmr_int = (CPU_TMR_INTERRUPT *)p_arg; + + tspec.tv_nsec = p_tmr_int->PeriodMuSec * 1000u; + tspec.tv_sec = p_tmr_int->PeriodSec; + + one_shot = p_tmr_int->OneShot; + + do { + tspec_rem = tspec; + do {res = clock_nanosleep(CLOCK_MONOTONIC, 0u, &tspec_rem, &tspec_rem); } while (res == EINTR); + if (res != 0u) { raise(SIGABRT); } + CPU_InterruptTriggerInternal(&(p_tmr_int->Interrupt)); /* See Note #2. */ + } while (one_shot != DEF_YES); + + pthread_exit(DEF_NULL); + + return (NULL); +} diff --git a/R32C/HEW/cpu.h b/R32C/HEW/cpu.h new file mode 100644 index 0000000..9d9d31d --- /dev/null +++ b/R32C/HEW/cpu.h @@ -0,0 +1,490 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* R32C +* Renesas HEW w/NC30 C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { asm("FCLR I"); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { asm("FSET I"); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { asm("PUSHC FLG"); \ + asm("FCLR I"); } while (0) +#define CPU_INT_EN() do { asm("POPC FLG"); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { asm("STC FLG, $@", cpu_sr); \ + asm("FCLR I"); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { asm("LDC $@, FLG", cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/R32C/HEW/cpu_a.a30 b/R32C/HEW/cpu_a.a30 new file mode 100644 index 0000000..aa3dde9 --- /dev/null +++ b/R32C/HEW/cpu_a.a30 @@ -0,0 +1,112 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; R32C +; Renesas HEW w/NC30 C Compiler +; +; Filename : cpu_a.a30 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_IntDis +_CPU_IntDis: + FCLR I + RTS + + + .SECTION program + .GLB _CPU_IntEn +_CPU_IntEn: + FSET I + RTS + + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + + .SECTION program + .GLB _CPU_SR_Save +_CPU_SR_Save: + STC FLG, R2R0 + FCLR I + RTS + + + .SECTION program + .GLB _CPU_SR_Restore + +_CPU_SR_Restore: + LDC R2R0, FLG + RTS + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + .END + diff --git a/R32C/IAR/cpu.h b/R32C/IAR/cpu.h new file mode 100644 index 0000000..b454804 --- /dev/null +++ b/R32C/IAR/cpu.h @@ -0,0 +1,490 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* R32C +* IAR C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned int CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed int CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef long double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT16U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { asm("FCLR I"); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { asm("FSET I"); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) + /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { asm("PUSHC FLG"); \ + asm("FCLR I"); } while (0) +#define CPU_INT_EN() do { asm("POPC FLG"); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { asm("STC FLG, $@", cpu_sr); \ + asm("FCLR I"); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { asm("LDC $@, FLG", cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); +void CPU_IntEn (void); + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/R32C/IAR/cpu_a.s53 b/R32C/IAR/cpu_a.s53 new file mode 100644 index 0000000..383c88d --- /dev/null +++ b/R32C/IAR/cpu_a.s53 @@ -0,0 +1,103 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; R32C +; IAR C Compiler +; +; Filename : cpu_a.s53 +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_IntDis ; Public functions + PUBLIC CPU_IntEn + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + +;********************************************************************************************************* +; DISABLE and ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;********************************************************************************************************* + +CPU_IntDis: + FCLR I + RTS + +CPU_IntEn: + FSET I + RTS + +;********************************************************************************************************* +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;********************************************************************************************************* + +CPU_SR_Save: + STC FLG, R2R0 + FCLR I + RTS + +CPU_SR_Restore: + LDC R2R0, FLG + RTS + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/RISC-V/GCC/cpu.h b/RISC-V/GCC/cpu.h new file mode 100644 index 0000000..8b61097 --- /dev/null +++ b/RISC-V/GCC/cpu.h @@ -0,0 +1,525 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* RISC-V +* GNU C Compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 0 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + /* $$$$ Prototype CPU port functions (if required) : */ +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ diff --git a/RISC-V/GCC/cpu_a.S b/RISC-V/GCC/cpu_a.S new file mode 100644 index 0000000..89351af --- /dev/null +++ b/RISC-V/GCC/cpu_a.S @@ -0,0 +1,123 @@ +#******************************************************************************************************** +# uC/CPU +# CPU CONFIGURATION & PORT LAYER +# +# Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +# +# SPDX-License-Identifier: APACHE-2.0 +# +# This software is subject to an open source license and is distributed by +# Silicon Laboratories Inc. pursuant to the terms of the Apache License, +# Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +# +#******************************************************************************************************** + +#******************************************************************************************************** +# +# CPU PORT FILE +# +# RISC-V +# GNU C Compiler +# +# Filename : cpu_a.S +# Version : v1.32.00 +#******************************************************************************************************** + + +#******************************************************************************************************** +# PUBLIC FUNCTIONS +#******************************************************************************************************** + + .global CPU_SR_Save + .global CPU_SR_Restore + + .global CPU_IntDis + .global CPU_IntEn + + +#******************************************************************************************************** +# EQUATES +#******************************************************************************************************** + + .equ CPU_MSTATUS_MIE, 0x08 + + +#******************************************************************************************************** +# CODE GENERATION DIRECTIVES +#******************************************************************************************************** + + .section .text + + +#******************************************************************************************************** +# DISABLE/ENABLE INTERRUPTS +# +# Description : Disable/Enable interrupts. +# +# (1) (a) For CPU_CRITICAL_METHOD_INT_DIS_EN, interrupts are enabled/disabled WITHOUT saving +# or restoring the state of the interrupt status. +# +# +# Prototypes : void CPU_IntDis(void); +# void CPU_IntEn (void); +#******************************************************************************************************** + +CPU_IntDis: +# Disable global interupt + li t0, CPU_MSTATUS_MIE + csrrc zero, mstatus, t0 + ret + + +CPU_IntEn: +# Enable global interupt + li t0, CPU_MSTATUS_MIE + csrrs zero, mstatus, t0 + ret + + + +#******************************************************************************************************** +# CRITICAL SECTION FUNCTIONS +# +# Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +# state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +# are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +# The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +# +# Prototypes : CPU_SR CPU_SR_Save (void); +# void CPU_SR_Restore(CPU_SR cpu_sr); +# +# Note(s) : (1) These functions are used in general like this : +# +# void Task (void *p_arg) +# { +# CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +# : +# : +# CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save()# */ +# : +# : +# CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr)# */ +# : +# } +#******************************************************************************************************** + +CPU_SR_Save: +# Save the Machine status register + csrr a0, mstatus +# Disable global interupt + li t0, CPU_MSTATUS_MIE + csrrc zero, mstatus, t0 + ret + + +CPU_SR_Restore: +# restore the Machine status register previous state + csrw mstatus, a0 + ret + + +#******************************************************************************************************** +# CPU ASSEMBLY PORT FILE END +#******************************************************************************************************** diff --git a/RL78/GNURL78/cpu.h b/RL78/GNURL78/cpu.h new file mode 100644 index 0000000..4eee878 --- /dev/null +++ b/RL78/GNURL78/cpu.h @@ -0,0 +1,484 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* RL78 +* IAR compiler for RL78 +* e2studio compiler for GNURL78 +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack word size (in octets). */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size (in number of CPU_STKs). */ + + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + +#define SET_INTERRUPT(cpu_sr) __set_interrupt_state(cpu_sr) +#define GET_INTERRUPT() __get_interrupt_state() + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __asm("DI"); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __asm("EI"); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = GET_INTERRUPT(); \ + __asm("DI"); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { SET_INTERRUPT(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + +CPU_INT08U __get_interrupt_state(); +void __set_interrupt_state(CPU_INT08U); + + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/RL78/GNURL78/cpu_c.c b/RL78/GNURL78/cpu_c.c new file mode 100644 index 0000000..11ff1b6 --- /dev/null +++ b/RL78/GNURL78/cpu_c.c @@ -0,0 +1,58 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/******************************************************************************************************** +* +* CPU PORT FILE +* +* Renesas RL78 Specific code +* GNU RL78 C Compiler +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + +#include + + +/******************************************************************************************************** +* set_interrupt_state & get_interrupt_state +* +* Description: Set or retrieve interrupt priority level. +* KPIT GNU Work around for set and get interrupt states +********************************************************************************************************* +*/ + +void __set_interrupt_state(CPU_INT08U cpu_sr){ + if (cpu_sr) + asm("EI"); + else + asm("DI"); +} + +CPU_INT08U __get_interrupt_state(void){ + + CPU_INT08U cpu_sr; + + + asm(" MOV A, PSW"); /* Get Process Status Word Register PSW value */ + asm(" SHR A, 7"); /* Save only the Interrupt Enabled (IE) Bit */ + asm(" MOV %0, A" : "=r"(cpu_sr)); /* Save IE bit value into cpu_sr */ //__asm + + return(cpu_sr); +} + diff --git a/RL78/IAR/cpu.h b/RL78/IAR/cpu.h new file mode 100644 index 0000000..7f1d9f8 --- /dev/null +++ b/RL78/IAR/cpu.h @@ -0,0 +1,497 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* RL78 +* IAR compiler for RL78 +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +* +* (3) 64-bit data types are NOT (or might NOT) be supported by this CPU/compiler. However, +* in order to compile functionality/features requiring 64-bit support; 64-bit data types +* MUST be defined even if defined with a precision lower than 64-bits (e.g. with 32-bits +* of precision). +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer NOT supported (see Note #3) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer NOT supported (see Note #3) */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef float CPU_FP64; /* 64-bit floating point NOT supported (see Note #3) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register NOT supported (see Note #3) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_16 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_16 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT16U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { __disable_interrupt(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { __enable_interrupt(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_state(); \ + __disable_interrupt(); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { __set_interrupt_state(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/RX/GNURX/cpu.h b/RX/GNURX/cpu.h new file mode 100644 index 0000000..375a717 --- /dev/null +++ b/RX/GNURX/cpu.h @@ -0,0 +1,525 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX Specific code +* GNU RX C compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to 'CPU_CFG_KA_IPL_BOUNDARY' to allow non-kernel aware ISRs +* CPU_CFG_KA_IPL_BOUNDARY+1, CPU_CFG_KA_IPL_BOUNDARY+2 ... '15'. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 12u +#endif + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_IntDis() do { set_ipl(CPU_CFG_KA_IPL_BOUNDARY); } while (0) /* Disable interrupts. */ +#else +#define CPU_IntDis() do { set_ipl(12); } while (0) +#endif +#define CPU_IntEn() do { set_ipl(0); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(CPU_CFG_KA_IPL_BOUNDARY); } while (0) +#else +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(12); } while (0) +#endif +#define CPU_INT_EN() do { set_ipl(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +#define CPU_INT_GLOBAL_EN(void) __asm__ __volatile__ ("SETPSW I" : : : "memory"); + +#define CPU_INT_VECT_TBL_BASE_SET(p_vect_tbl) set_intb(p_vect_tbl) + +#define CPU_ISR void __attribute__ ((interrupt)) + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/RX/GNURX/cpu_a.s b/RX/GNURX/cpu_a.s new file mode 100644 index 0000000..4f2ca1f --- /dev/null +++ b/RX/GNURX/cpu_a.s @@ -0,0 +1,76 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Renesas RX Specific code +; GNU RX C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global _set_ipl + .global _get_ipl + .global _set_intb + + .text + + +;******************************************************************************************************** +; set_ipl() & get_ipl() +; +; Description: Set or retrieve interrupt priority level. +;******************************************************************************************************** + +_set_ipl: + PUSH R2 + MVFC PSW, R2 + AND #-0F000001H, R2 + SHLL #24, R1 + OR R1, R2 + MVTC R2, PSW + POP R2 + RTS + + +_get_ipl: + MVFC PSW, R1 + SHLR #24, R1 + AND #15, R1 + RTS + + +;******************************************************************************************************** +; set_intb() +; +; Description: Set the interrupt base register +;******************************************************************************************************** + +_set_intb: + PUSH R2 + mvtc R1, intb + POP R2 + RTS + + + .END + diff --git a/RX/IAR/cpu.h b/RX/IAR/cpu.h new file mode 100644 index 0000000..52f69ef --- /dev/null +++ b/RX/IAR/cpu.h @@ -0,0 +1,520 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX Specific code +* IAR RX C compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to CPU_CFG_KA_IPL_BOUNDARY to allow non-kernel aware ISRs at +* CPU_CFG_KA_IPL_BOUNDARY+1, CPU_CFG_KA_IPL_BOUNDARY+2 .. 15. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 12u +#endif + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + /* Disable interrupts. */ +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_IntDis() do { __set_interrupt_level(CPU_CFG_KA_IPL_BOUNDARY); } while (0) +#else +#define CPU_IntDis() do { __set_interrupt_level(12); } while (0) +#endif + /* Enable interrupts. */ +#define CPU_IntEn() do { __set_interrupt_level(0); } while (0) + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_level(); \ + __set_interrupt_level(CPU_CFG_KA_IPL_BOUNDARY); } while (0) +#else +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_level(); \ + __set_interrupt_level(12); } while (0) +#endif + /* Restore CPU status word. */ +#define CPU_INT_EN() do { __set_interrupt_level(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +#define CPU_INT_GLOBAL_EN() asm(" SETPSW I") +#define CPU_INT_VECT_TBL_BASE_SET(p_vect_tbl) __set_interrupt_table(p_vect_tbl) +#define CPU_ISR __interrupt void + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/RX/RXC/cpu.h b/RX/RXC/cpu.h new file mode 100644 index 0000000..2213e1f --- /dev/null +++ b/RX/RXC/cpu.h @@ -0,0 +1,518 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX Specific code +* Renesas RXC compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef __evenaccess volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef __evenaccess volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef __evenaccess volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef __evenaccess volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to CPU_CFG_KA_IPL_BOUNDARY to allow non-kernel aware ISRs at +* CPU_CFG_KA_IPL_BOUNDARY+1, CPU_CFG_KA_IPL_BOUNDARY+2 ... 15. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 12u +#endif + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_IntDis() do { set_ipl(CPU_CFG_KA_IPL_BOUNDARY); } while (0) /* Disable interrupts. */ +#else +#define CPU_IntDis() do { set_ipl(12); } while (0) +#endif +#define CPU_IntEn() do { set_ipl(0); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#ifdef CPU_CFG_KA_IPL_BOUNDARY +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(CPU_CFG_KA_IPL_BOUNDARY); } while (0) +#else +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(12); } while (0) +#endif +#define CPU_INT_EN() do { set_ipl(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +#define CPU_INT_GLOBAL_EN(void) setpsw_i() +#define CPU_INT_VECT_TBL_BASE_SET(p_vect_tbl) set_intb((void *)p_vect_tbl) +#define CPU_ISR void + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/RX610/GNURX/cpu.h b/RX610/GNURX/cpu.h new file mode 100644 index 0000000..b8ac38a --- /dev/null +++ b/RX610/GNURX/cpu.h @@ -0,0 +1,507 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX610 Specific code +* GNU RX C compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to '12' to allow non-kernel aware ISRs at levels '13' to '15'. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 5u +#endif + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_IntDis() do { set_ipl(12); } while (0) /* Disable interrupts. */ +#define CPU_IntEn() do { set_ipl(0); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(5); } while (0) +#define CPU_INT_EN() do { set_ipl(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/RX610/GNURX/cpu_a.s b/RX610/GNURX/cpu_a.s new file mode 100644 index 0000000..1fd1a10 --- /dev/null +++ b/RX610/GNURX/cpu_a.s @@ -0,0 +1,61 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; Renesas RX610 Specific code +; GNU RX C Compiler +; +; Filename : cpu_a.s +; Version : v1.32.00 +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .global _set_ipl + .global _get_ipl + + .text + + +;******************************************************************************************************** +; set_ipl() & get_ipl() +; +; Description: Set or retrieve interrupt priority level. +;******************************************************************************************************** + +_set_ipl: + PUSH R2 + MVFC PSW, R2 + AND #-0F000001H, R2 + SHLL #24, R1 + OR R1, R2 + MVTC R2, PSW + POP R2 + RTS + +_get_ipl: + MVFC PSW, R1 + SHLR #24, R1 + AND #15, R1 + RTS + + + .END + diff --git a/RX610/IAR/cpu.h b/RX610/IAR/cpu.h new file mode 100644 index 0000000..23c2f11 --- /dev/null +++ b/RX610/IAR/cpu.h @@ -0,0 +1,505 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX610 Specific code +* IAR RX C compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to '5' to allow non-kernel aware ISRs at levels '6' and '7'. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 5u +#endif + + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_IntDis() do { __set_interrupt_state(5); } while (0) /* Disable interrupts. */ +#define CPU_IntEn() do { __enable_interrupt(); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = __get_interrupt_state(); \ + __set_interrupt_state(5); } while (0) + /* Restore CPU status word. */ +#define CPU_INT_EN() do { __set_interrupt_state(cpu_sr); } while (0) +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/RX610/RXC/cpu.h b/RX610/RXC/cpu.h new file mode 100644 index 0000000..f09112b --- /dev/null +++ b/RX610/RXC/cpu.h @@ -0,0 +1,503 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Renesas RX610 Specific code +* Renesas RXC compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef __evenaccess volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef __evenaccess volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef __evenaccess volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef __evenaccess volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (3) The default endianness can be overridden by setting the CPU_CFG_ENDIAN_TYPE inside +* cpu_cfg.h. +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#ifndef CPU_CFG_ENDIAN_TYPE +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +* +* (4) Interrupt mask level is set to '5' to allow non-kernel aware ISRs at levels '6' and '7'. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_KA_IPL_BOUNDARY /* Configure default IPL boundary if undefined. */ +#define CPU_CFG_KA_IPL_BOUNDARY 5u +#endif + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT08U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_IntDis() do { set_ipl(5); } while (0) /* Disable interrupts. */ +#define CPU_IntEn() do { set_ipl(0); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_ipl(); \ + set_ipl(5); } while (0) +#define CPU_INT_EN() do { set_ipl(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/SH-2/HEW/cpu.h b/SH-2/HEW/cpu.h new file mode 100644 index 0000000..bd6b9fd --- /dev/null +++ b/SH-2/HEW/cpu.h @@ -0,0 +1,474 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* SH-2/SH-2A/SH-2A FPU +* Renesas HEW w/ SH C compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#include + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned long CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed long CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_IntDis() do { set_imask(15); } while (0) /* Disable interrupts. */ +#define CPU_IntEn() do { set_imask(0); } while (0) /* Enable interrupts. */ + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) + /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_DIS() do { cpu_sr = get_cr(); \ + set_imask(15); } while (0) +#define CPU_INT_EN() do { set_cr(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU module include. */ + diff --git a/Template/cpu.h b/Template/cpu.h new file mode 100644 index 0000000..47ab724 --- /dev/null +++ b/Template/cpu.h @@ -0,0 +1,552 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* TEMPLATE +* +* $$$$ Insert CPU Name +* $$$$ Insert Compiler Name +* +* Filename : cpu.h +* Version : v1.32.00 $$$$ Insert CPU header port file version number +********************************************************************************************************* +* Note(s) : (1) To provide the required CPU port functionality, insert the appropriate CPU- &/or +* compiler-specific code to perform the stated actions wherever '$$$$' comments are +* found. +* +* #### This note MAY be entirely removed for specific CPU port files. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + /* $$$$ Configure CPU data types (see Note #1) : */ +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer ($$$$ if available) */ +typedef signed long CPU_INT64S; /* 64-bit signed integer ($$$$ if available) */ + +typedef float CPU_FP32; /* 32-bit floating point ($$$$ if available) */ +typedef double CPU_FP64; /* 64-bit floating point ($$$$ if available) */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register ($$$$ if available) */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + /* $$$$ Configure CPU word sizes : */ + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_32 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + /* $$$$ Configure CPU data types : */ + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* $$$$ Configure CPU critical section : */ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 0 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + /* $$$$ Prototype CPU port functions (if required) : */ +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/Template/cpu_a.asm b/Template/cpu_a.asm new file mode 100644 index 0000000..131cbda --- /dev/null +++ b/Template/cpu_a.asm @@ -0,0 +1,377 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; TEMPLATE +; +; $$$$ Insert CPU Name +; $$$$ Insert Compiler Name +; +; Filename : cpu_a.asm $$$$ Insert CPU assembly port file name +; Version : v1.32.00 $$$$ Insert CPU assembly port file version number +;******************************************************************************************************** +; Note(s) : (1) To provide the required CPU port functionality, insert the appropriate CPU- &/or +; compiler-specific code to perform the stated actions wherever '$$$$' comments are +; found. +; +; #### This note MAY be entirely removed for specific CPU port files. +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + ; $$$$ Extern required CPU port functions : + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + + PUBLIC CPU_SR_Push + PUBLIC CPU_SR_Pop + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + + PUBLIC CPU_CntLeadZeros + PUBLIC CPU_CntTrailZeros + PUBLIC CPU_RevBits + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + ; $$$$ Define possible required CPU equates : + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + ; $$$$ Insert possible required CPU-compiler code generation directives : + + +;******************************************************************************************************** +; DISABLE/ENABLE INTERRUPTS +; +; Description : Disable/Enable interrupts. +; +; (1) (a) For CPU_CRITICAL_METHOD_INT_DIS_EN, interrupts are enabled/disabled WITHOUT saving +; or restoring the state of the interrupt status. +; +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis + ; $$$$ Insert code to disable CPU interrupts + + +CPU_IntEn + ; $$$$ Insert code to enable CPU interrupts + + +;******************************************************************************************************** +; PUSH/POP CPU STATUS REGISTER +; +; Description : Push/Pop the state of CPU interrupts onto the local stack, if possible. +; +; (1) (b) For CPU_CRITICAL_METHOD_STATUS_STK, the state of the interrupt status flag is +; stored in onto the local stack & interrupts are then disabled. The previous +; interrupt status state is restored from the local stack into the CPU's status +; register. +; +; +; Prototypes : void CPU_SR_Push(void); +; void CPU_SR_Pop (void); +;******************************************************************************************************** + +CPU_SR_Push + ; $$$$ Insert code to push CPU status onto local stack & disable interrupts + + +CPU_SR_Pop + ; $$$$ Insert code to pop CPU status from local stack + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save + ; $$$$ Insert code to save CPU status register(s) & disable interrupts + + +CPU_SR_Restore + ; $$$$ Insert code to restore CPU status register(s) + + +;******************************************************************************************************** +; CPU_CntLeadZeros() +; COUNT LEADING ZEROS +; +; Description : Counts the number of contiguous, most-significant, leading zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count leading zero bits. +; +; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +; +; Note(s) : (1) (a) Supports up to the following data value sizes, depending on the configured +; size of 'CPU_DATA' (see 'cpu.h CPU WORD CONFIGURATION Note #1') : +; +; (1) 8-bits +; (2) 16-bits +; (3) 32-bits +; (4) 64-bits +; +; (b) (1) For 8-bit values : +; +; b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; 0 0 0 1 x x x x 3 +; 0 0 0 0 1 x x x 4 +; 0 0 0 0 0 1 x x 5 +; 0 0 0 0 0 0 1 x 6 +; 0 0 0 0 0 0 0 1 7 +; 0 0 0 0 0 0 0 0 8 +; +; +; (2) For 16-bit values : +; +; b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 11 +; 0 0 0 0 1 x x x 12 +; 0 0 0 0 0 1 x x 13 +; 0 0 0 0 0 0 1 x 14 +; 0 0 0 0 0 0 0 1 15 +; 0 0 0 0 0 0 0 0 16 +; +; +; (3) For 32-bit values : +; +; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 27 +; 0 0 0 0 1 x x x 28 +; 0 0 0 0 0 1 x x 29 +; 0 0 0 0 0 0 1 x 30 +; 0 0 0 0 0 0 0 1 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (4) For 64-bit values : +; +; b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros +; --- --- --- --- --- --- --- --- --------------- +; 1 x x x x x x x 0 +; 0 1 x x x x x x 1 +; 0 0 1 x x x x x 2 +; : : : : : : : : : +; : : : : : : : : : +; 0 0 0 1 x x x x 59 +; 0 0 0 0 1 x x x 60 +; 0 0 0 0 0 1 x x 61 +; 0 0 0 0 0 0 1 x 62 +; 0 0 0 0 0 0 0 1 63 +; 0 0 0 0 0 0 0 0 64 +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +; is #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntLeadZeros + + ; $$$$ Insert code to count the number of contiguous, most-significant, ... + ; ... leading zero bits in 'val' (see Note #1b) + + +;******************************************************************************************************** +; CPU_CntTrailZeros() +; COUNT TRAILING ZEROS +; +; Description : Counts the number of contiguous, least-significant, trailing zero bits before the +; first binary one bit in a data value. +; +; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val); +; +; Argument(s) : val Data value to count trailing zero bits. +; +; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +; +; Note(s) : (1) (a) Supports up to the following data value sizes, depending on the configured +; size of 'CPU_DATA' (see 'cpu.h CPU WORD CONFIGURATION Note #1') : +; +; (1) 8-bits +; (2) 16-bits +; (3) 32-bits +; (4) 64-bits +; +; (b) (1) For 8-bit values : +; +; b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; x x x x 1 0 0 0 3 +; x x x 1 0 0 0 0 4 +; x x 1 0 0 0 0 0 5 +; x 1 0 0 0 0 0 0 6 +; 1 0 0 0 0 0 0 0 7 +; 0 0 0 0 0 0 0 0 8 +; +; +; (2) For 16-bit values : +; +; b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 11 +; x x x 1 0 0 0 0 12 +; x x 1 0 0 0 0 0 13 +; x 1 0 0 0 0 0 0 14 +; 1 0 0 0 0 0 0 0 15 +; 0 0 0 0 0 0 0 0 16 +; +; +; (3) For 32-bit values : +; +; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 27 +; x x x 1 0 0 0 0 28 +; x x 1 0 0 0 0 0 29 +; x 1 0 0 0 0 0 0 30 +; 1 0 0 0 0 0 0 0 31 +; 0 0 0 0 0 0 0 0 32 +; +; +; (4) For 64-bit values : +; +; b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros +; --- --- --- --- --- --- --- --- ---------------- +; x x x x x x x 1 0 +; x x x x x x 1 0 1 +; x x x x x 1 0 0 2 +; : : : : : : : : : +; : : : : : : : : : +; x x x x 1 0 0 0 59 +; x x x 1 0 0 0 0 60 +; x x 1 0 0 0 0 0 61 +; x 1 0 0 0 0 0 0 62 +; 1 0 0 0 0 0 0 0 63 +; 0 0 0 0 0 0 0 0 64 +; +; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT +; is #define'd in 'cpu_cfg.h' or 'cpu.h'. +;******************************************************************************************************** + +CPU_CntTrailZeros + + ; $$$$ Insert code to count the number of contiguous, least-significant, ... + ; ... trailing zero bits in 'val' (see Note #1b) + + +;******************************************************************************************************** +; CPU_RevBits() +; REVERSE BITS +; +; Description : Reverses the bits in a data value. +; +; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val); +; +; Argument(s) : val Data value to reverse bits. +; +; Return(s) : Value with all bits in 'val' reversed (see Note #1). +; +; Note(s) : (1) The final, reversed data value for 'val' is such that : +; +; 'val's final bit 0 = 'val's original bit N +; 'val's final bit 1 = 'val's original bit (N - 1) +; 'val's final bit 2 = 'val's original bit (N - 2) +; +; ... ... +; +; 'val's final bit (N - 2) = 'val's original bit 2 +; 'val's final bit (N - 1) = 'val's original bit 1 +; 'val's final bit N = 'val's original bit 0 +;******************************************************************************************************** + +CPU_RevBits + + ; $$$$ Insert code to reverse the bits in 'val' (see Note #1) + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + ; $$$$ Insert assembly end-of-file directive, if any + diff --git a/V850E2M/CubeSuite+/cpu.h b/V850E2M/CubeSuite+/cpu.h new file mode 100644 index 0000000..267467d --- /dev/null +++ b/V850E2M/CubeSuite+/cpu.h @@ -0,0 +1,490 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850E2M +* Renesas CX compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_EIIC_Rd (void); /* Reads CPU EI Level Exception Code Register(EIIC). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ diff --git a/V850E2M/CubeSuite+/cpu_a.asm b/V850E2M/CubeSuite+/cpu_a.asm new file mode 100644 index 0000000..f0ceebb --- /dev/null +++ b/V850E2M/CubeSuite+/cpu_a.asm @@ -0,0 +1,131 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; V850E2M +; Renesas CX Compiler +; +; Filename : cpu_a.asm +; Version : v1.32.00 +;******************************************************************************************************** + + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + .extern _CPU_SR_Save + .extern _CPU_SR_Restore + .extern _CPU_IntDis + .extern _CPU_IntEn + .extern _CPU_EIIC_Rd + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + + PSW .set 5 + EIIC .set 13 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + .cseg text + .align 4 + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +_CPU_SR_Save: + stsr PSW, r10 ; Store PSW + di + jmp [lp] + +_CPU_SR_Restore: + ldsr r6 , PSW + jmp [lp] + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description: Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +_CPU_IntDis: + di + jmp [lp] + +_CPU_IntEn: + ei + jmp [lp] + + +;******************************************************************************************************** +; READS CPU EXCEPTION CAUSE REGISTER +; +; Description : Reads CPU EI level exception code register(EIIC), which retains the cause of any EI level +; exception that occurs. +; +; Prototypes : CPU_DATA CPU_EIIC_Rd (void); +; +; Note(s) : None. +; +;******************************************************************************************************** + +_CPU_EIIC_Rd: + stsr EIIC, r10 + jmp [lp] + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** diff --git a/V850E2M/IAR/cpu.h b/V850E2M/IAR/cpu.h new file mode 100644 index 0000000..2a123ae --- /dev/null +++ b/V850E2M/IAR/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850E2M +* IAR compiler for V850 +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_EIIC_Rd (void); /* Reads CPU EI Level Exception Code Register(EIIC). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/V850E2M/IAR/cpu_a.s85 b/V850E2M/IAR/cpu_a.s85 new file mode 100644 index 0000000..4d12f22 --- /dev/null +++ b/V850E2M/IAR/cpu_a.s85 @@ -0,0 +1,131 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; V850E2M +; IAR compiler for V850 +; +; Filename : cpu_a.s85 +; Version : v1.32.00 +;******************************************************************************************************** + + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + PUBLIC CPU_EIIC_Rd + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +PSW EQU 5 +EIIC EQU 13 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save: + stsr PSW, r1 ; Store PSW + di + jmp [lp] + +CPU_SR_Restore: + ldsr r1 , PSW + jmp [lp] + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description: Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis: + di + jmp [lp] + +CPU_IntEn: + ei + jmp [lp] + + +;******************************************************************************************************** +; READS CPU EXCEPTION CAUSE REGISTER +; +; Description : Reads CPU EI level exception code register(EIIC), which retains the cause of any EI level +; exception that occurs. +; +; Prototypes : CPU_DATA CPU_EIIC_Rd (void); +; +; Note(s) : None. +; +;******************************************************************************************************** + +CPU_EIIC_Rd: + stsr EIIC, r1 + jmp [lp] + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END diff --git a/V850E2S/IAR/cpu.h b/V850E2S/IAR/cpu.h new file mode 100644 index 0000000..5d0b710 --- /dev/null +++ b/V850E2S/IAR/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850E2S +* IAR compiler for V850 +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_EIIC_Rd (void); /* Reads CPU EI Level Exception Code Register(EIIC). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/V850E2S/IAR/cpu_a.s85 b/V850E2S/IAR/cpu_a.s85 new file mode 100644 index 0000000..b4c0aa5 --- /dev/null +++ b/V850E2S/IAR/cpu_a.s85 @@ -0,0 +1,132 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; V850E2S +; IAR compiler for V850 +; +; Filename : cpu_a.s85 +; Version : v1.32.00 +;******************************************************************************************************** + + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + PUBLIC CPU_EIIC_Rd + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +PSW EQU 5 +EIIC EQU 13 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save: + stsr PSW, r1 ; Store PSW + di + jmp [lp] + +CPU_SR_Restore: + ldsr r1 , PSW + jmp [lp] + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description: Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis: + di + jmp [lp] + +CPU_IntEn: + ei + jmp [lp] + + +;******************************************************************************************************** +; READS CPU EXCEPTION CAUSE REGISTER +; +; Description : Reads CPU EI level exception code register(EIIC), which retains the cause of any EI level +; exception that occurs. +; +; Prototypes : CPU_DATA CPU_EIIC_Rd (void); +; +; Note(s) : None. +; +;******************************************************************************************************** + +CPU_EIIC_Rd: + stsr EIIC, r1 + jmp [lp] + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END diff --git a/V850ES/CubeSuite/cpu.h b/V850ES/CubeSuite/cpu.h new file mode 100644 index 0000000..b089c88 --- /dev/null +++ b/V850ES/CubeSuite/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850ES +* Renesas CA850 compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_ECR_Rd (void); /* Reads CPU Exception Code Register(ECR). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/V850ES/CubeSuite/cpu_a.s b/V850ES/CubeSuite/cpu_a.s new file mode 100644 index 0000000..a460944 --- /dev/null +++ b/V850ES/CubeSuite/cpu_a.s @@ -0,0 +1,127 @@ +#******************************************************************************************************** +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#******************************************************************************************************** + +#******************************************************************************************************** +# +# CPU PORT FILE +# +# V850ES +# Renesas CA850 +# +# Filename : cpu_a.s +# Version : v1.32.00 +#******************************************************************************************************** + + + +#******************************************************************************************************** +# PUBLIC FUNCTIONS +#******************************************************************************************************** + + + .extern _CPU_SR_Save + .extern _CPU_SR_Restore + .extern _CPU_IntDis + .extern _CPU_IntEn + .extern _CPU_ECR_Rd + + +#******************************************************************************************************** +# EQUATES +#******************************************************************************************************** + + .set ECR, 4 + .set PSW, 5 + +#******************************************************************************************************** +# CODE GENERATION DIRECTIVES +#******************************************************************************************************** + + .text + .align 4 + +#******************************************************************************************************** +# SAVE/RESTORE CPU STATUS REGISTER +# +# Description : Save/Restore the state of CPU interrupts, if possible. +# +# (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +# stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +# allocated in all functions that need to disable interrupts). The previous interrupt +# status state is restored by copying 'cpu_sr' into the CPU's status register. +# +# +# Prototypes : CPU_SR CPU_SR_Save (void); +# void CPU_SR_Restore(CPU_SR cpu_sr); +# +# Note(s) : (1) These functions are used in general like this : +# +# void Task (void *p_arg) +# { +# CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +# : +# : +# CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +# : +# : +# CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +# : +# } +#******************************************************************************************************** + +_CPU_SR_Save: + stsr PSW, r10 -- Store PSW + di + jmp [lp] + +_CPU_SR_Restore: + ldsr r6 , PSW + jmp [lp] + +#******************************************************************************************************** +# DISABLE and ENABLE INTERRUPTS +# +# Description: Disable/Enable interrupts. +# +# Prototypes : void CPU_IntDis(void); +# void CPU_IntEn (void); +#******************************************************************************************************** + +_CPU_IntDis: + di + jmp [lp] + +_CPU_IntEn: + ei + jmp [lp] + +#******************************************************************************************************** +# READS CPU EXCEPTION CAUSE REGISTER +# +# Description : Reads CPU exception code register(ECR), which identifies each interrupt source according to +# its exception code. +# +# Prototypes : CPU_DATA CPU_ECR_Rd (void); +# +# Note(s) : None. +# +#******************************************************************************************************** + +_CPU_ECR_Rd: + stsr ECR, r10 + jmp [lp] + +#******************************************************************************************************** +# CPU ASSEMBLY PORT FILE END +#******************************************************************************************************** diff --git a/V850ES/IAR/cpu.h b/V850ES/IAR/cpu.h new file mode 100644 index 0000000..35db9f1 --- /dev/null +++ b/V850ES/IAR/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850ES +* IAR compiler for V850 +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_ECR_Rd (void); /* Reads CPU Exception Code Register(ECR). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/V850ES/IAR/cpu_a.s85 b/V850ES/IAR/cpu_a.s85 new file mode 100644 index 0000000..95e3d59 --- /dev/null +++ b/V850ES/IAR/cpu_a.s85 @@ -0,0 +1,133 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +; +; SPDX-License-Identifier: APACHE-2.0 +; +; This software is subject to an open source license and is distributed by +; Silicon Laboratories Inc. pursuant to the terms of the Apache License, +; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +; +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; V850ES +; IAR compiler for V850 +; +; Filename : cpu_a.s85 +; Version : v1.32.00 +;******************************************************************************************************** + + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + PUBLIC CPU_IntDis + PUBLIC CPU_IntEn + PUBLIC CPU_ECR_Rd + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +ECR EQU 4 +PSW EQU 5 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + + +;******************************************************************************************************** +; SAVE/RESTORE CPU STATUS REGISTER +; +; Description : Save/Restore the state of CPU interrupts, if possible. +; +; (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +; stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +; allocated in all functions that need to disable interrupts). The previous interrupt +; status state is restored by copying 'cpu_sr' into the CPU's status register. +; +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; } +;******************************************************************************************************** + +CPU_SR_Save: + stsr PSW, r1 ; Store PSW + di + jmp [lp] + +CPU_SR_Restore: + ldsr r1 , PSW + jmp [lp] + + +;******************************************************************************************************** +; DISABLE and ENABLE INTERRUPTS +; +; Description: Disable/Enable interrupts. +; +; Prototypes : void CPU_IntDis(void); +; void CPU_IntEn (void); +;******************************************************************************************************** + +CPU_IntDis: + di + jmp [lp] + +CPU_IntEn: + ei + jmp [lp] + + +;******************************************************************************************************** +; READS CPU EXCEPTION CAUSE REGISTER +; +; Description : Reads CPU EI level exception code register(EIIC), which retains the cause of any EI level +; exception that occurs. +; +; Prototypes : CPU_DATA CPU_EIIC_Read (void); +; +; Note(s) : None. +; +;******************************************************************************************************** + +CPU_ECR_Rd: + stsr ECR, r1 + jmp [lp] + + +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END diff --git a/V850ES/PM+/cpu.h b/V850ES/PM+/cpu.h new file mode 100644 index 0000000..b089c88 --- /dev/null +++ b/V850ES/PM+/cpu.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* V850ES +* Renesas CA850 compiler +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN) +#define CPU_INT_DIS() do { CPU_IntDis(); } while (0) /* Disable interrupts. */ +#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_STK) +#define CPU_INT_DIS() do { CPU_SR_Push(); } while (0) /* Push CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Pop(); } while (0) /* Pop CPU status word. */ +#endif + +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntDis (void); /* Disable interrupts. */ +void CPU_IntEn (void); /* Enable interrupts. */ + +void CPU_SR_Push (void); /* Push CPU status word & disable interrupts. */ +void CPU_SR_Pop (void); /* Pop CPU status word. */ + +CPU_SR CPU_SR_Save (void); /* Save CPU status word & disable interrupts. */ +void CPU_SR_Restore(CPU_SR cpu_sr); /* Restore CPU status word. */ + + +CPU_DATA CPU_ECR_Rd (void); /* Reads CPU Exception Code Register(ECR). */ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/V850ES/PM+/cpu_a.s b/V850ES/PM+/cpu_a.s new file mode 100644 index 0000000..d8d12c1 --- /dev/null +++ b/V850ES/PM+/cpu_a.s @@ -0,0 +1,128 @@ +#******************************************************************************************************** +#* uC/CPU +#* CPU CONFIGURATION & PORT LAYER +#* +#* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +#* +#* SPDX-License-Identifier: APACHE-2.0 +#* +#* This software is subject to an open source license and is distributed by +#* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +#* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +#* +#******************************************************************************************************** + +#******************************************************************************************************** +# +# CPU PORT FILE +# +# V850ES +# Renesas CA850 +# +# Filename : cpu_a.s +# Version : v1.32.00 +#******************************************************************************************************** + + + +#******************************************************************************************************** +# PUBLIC FUNCTIONS +#******************************************************************************************************** + + + .extern _CPU_SR_Save + .extern _CPU_SR_Restore + .extern _CPU_IntDis + .extern _CPU_IntEn + .extern _CPU_ECR_Rd + + +#******************************************************************************************************** +# EQUATES +#******************************************************************************************************** + + .set ECR, 4 + .set PSW, 5 + +#******************************************************************************************************** +# CODE GENERATION DIRECTIVES +#******************************************************************************************************** + + .text + .align 4 + +#******************************************************************************************************** +# SAVE/RESTORE CPU STATUS REGISTER +# +# Description : Save/Restore the state of CPU interrupts, if possible. +# +# (1) (c) For CPU_CRITICAL_METHOD_STATUS_LOCAL, the state of the interrupt status flag is +# stored in the local variable 'cpu_sr' & interrupts are then disabled ('cpu_sr' is +# allocated in all functions that need to disable interrupts). The previous interrupt +# status state is restored by copying 'cpu_sr' into the CPU's status register. +# +# +# Prototypes : CPU_SR CPU_SR_Save (void); +# void CPU_SR_Restore(CPU_SR cpu_sr); +# +# Note(s) : (1) These functions are used in general like this : +# +# void Task (void *p_arg) +# { +# CPU_SR_ALLOC(); /* Allocate storage for CPU status register */ +# : +# : +# CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +# : +# : +# CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +# : +# } +#******************************************************************************************************** + +_CPU_SR_Save: + stsr PSW, r10 -- Store PSW + di + jmp [lp] + +_CPU_SR_Restore: + ldsr r6 , PSW + jmp [lp] + +#******************************************************************************************************** +# DISABLE and ENABLE INTERRUPTS +# +# Description: Disable/Enable interrupts. +# +# Prototypes : void CPU_IntDis(void); +# void CPU_IntEn (void); +#******************************************************************************************************** + +_CPU_IntDis: + di + jmp [lp] + +_CPU_IntEn: + ei + jmp [lp] + +#******************************************************************************************************** +# READS CPU EXCEPTION CAUSE REGISTER +# +# Description : Reads CPU exception code register(ECR), which identifies each interrupt source according to +# its exception code. +# +# Prototypes : CPU_DATA CPU_ECR_Rd (void); +# +# Note(s) : None. +# +#******************************************************************************************************** + +_CPU_ECR_Rd: + stsr ECR, r10 + jmp [lp] + +#******************************************************************************************************** +# CPU ASSEMBLY PORT FILE END +#******************************************************************************************************** + diff --git a/Win32/Visual_Studio/cpu.h b/Win32/Visual_Studio/cpu.h new file mode 100644 index 0000000..f8152e5 --- /dev/null +++ b/Win32/Visual_Studio/cpu.h @@ -0,0 +1,509 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Win32 +* Microsoft Visual Studio +* +* Filename : cpu.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (16u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_INT_DIS_EN + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() CPU_IntDis() /* Disable interrupts. */ +#define CPU_INT_EN() CPU_IntEn() /* Enable interrupts. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() CPU_INT_DIS() /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() CPU_INT_EN() /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() +#define CPU_RMB() +#define CPU_WMB() + + +/* +********************************************************************************************************* +* WIN32 CRITICAL SECTION CONFIGURATION +********************************************************************************************************* +*/ + +#define WIN32_CRITICAL_SECTION 1u +#define WIN32_MUTEX 2u /* Allow recursion of critical sections. */ + + +#ifndef CPU_CFG_CRITICAL_METHOD_WIN32 +#define CPU_CFG_CRITICAL_METHOD_WIN32 WIN32_CRITICAL_SECTION +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void CPU_IntInit(void); +void CPU_IntEnd (void); + +void CPU_IntDis (void); +void CPU_IntEn (void); + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \ + (CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64)) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#error " [ || CPU_WORD_SIZE_64 64-bit alignment]" +#endif + + + +#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE) +#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' " +#error " [MUST be >= CPU_CFG_DATA_SIZE]" +#endif + + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_STK_GROWTH +#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" + +#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \ + (CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO)) +#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]" +#error " [ || CPU_STK_GROWTH_HI_TO_LO]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* End of CPU module include. */ + diff --git a/Win32/Visual_Studio/cpu_c.c b/Win32/Visual_Studio/cpu_c.c new file mode 100644 index 0000000..9f4f471 --- /dev/null +++ b/Win32/Visual_Studio/cpu_c.c @@ -0,0 +1,516 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* Win32 +* Microsoft Visual Studio +* +* Filename : cpu_c.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#include +#include + + +#define _WIN32_WINNT 0x0600 +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#ifdef _MSC_VER +#include + +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +#if (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_CRITICAL_SECTION) +static CRITICAL_SECTION CriticalSection; +#elif (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_MUTEX) +static HANDLE CriticalSection; +#endif + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_MSG_TRACE_EN +static int CPU_Printf(char *p_str, ...); +#endif + + +/* +********************************************************************************************************* +* CPU_IntInit() +* +* Description : This function initializes the critical section. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : 1) CPU_IntInit() MUST be called prior to use any of the CPU_IntEn(), and CPU_IntDis() +* functions. +********************************************************************************************************* +*/ + +void CPU_IntInit (void) +{ +#if (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_MUTEX) +#ifdef CPU_CFG_MSG_TRACE_EN + DWORD last_err; + LPTSTR p_msg; +#endif + + + CriticalSection = CreateMutex(NULL, FALSE, NULL); + if (CriticalSection == NULL) { +#ifdef CPU_CFG_MSG_TRACE_EN + last_err = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + last_err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&p_msg, + 0, + NULL); + + CPU_Printf("Error: Initialize Critical Section failed: %s.\n", p_msg); + + LocalFree(p_msg); +#endif + return; + } +#elif (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_CRITICAL_SECTION) + InitializeCriticalSection(&CriticalSection); +#endif +} + + +/* +********************************************************************************************************* +* CPU_IntEnd() +* +* Description : This function terminates the critical section. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : 1) . +********************************************************************************************************* +*/ + +void CPU_IntEnd (void) +{ +#if (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_MUTEX) + CloseHandle(CriticalSection); +#elif (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_CRITICAL_SECTION) + DeleteCriticalSection(&CriticalSection); +#endif +} + + +/* +********************************************************************************************************* +* CPU_IntDis() +* +* Description : This function disables interrupts for critical sections of code. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntDis (void) +{ +#if (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_MUTEX) + DWORD ret; +#ifdef CPU_CFG_MSG_TRACE_EN + DWORD last_err; + LPTSTR p_msg; +#endif + + + ret = WaitForSingleObject(CriticalSection, INFINITE); + + switch (ret) { + case WAIT_OBJECT_0: + default: + break; + + +#ifdef CPU_CFG_MSG_TRACE_EN + case WAIT_ABANDONED: + CPU_Printf("cpu_c.c: Enter Critical Section failed: Mutex abandoned by owning thread.\n"); + break; + + + case WAIT_TIMEOUT: + CPU_Printf("cpu_c.c: Enter Critical Section failed: Time-out interval elapsed.\n"); + break; + + + case WAIT_FAILED: + last_err = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + last_err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&p_msg, + 0, + NULL); + + CPU_Printf("cpu_c.c: Enter Critical Section failed: %s.\n", p_msg); + + LocalFree(p_msg); + break; +#endif + } +#elif (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_CRITICAL_SECTION) + EnterCriticalSection(&CriticalSection); +#endif +} + + +/* +********************************************************************************************************* +* CPU_IntEn() +* +* Description : This function enables interrupts after critical sections of code. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +void CPU_IntEn (void) +{ +#if (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_MUTEX) +#ifdef CPU_CFG_MSG_TRACE_EN + DWORD last_err; + LPTSTR p_msg; +#endif + + + if (ReleaseMutex(CriticalSection) == 0u) { +#ifdef CPU_CFG_MSG_TRACE_EN + last_err = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + last_err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&p_msg, + 0, + NULL); + + CPU_Printf("cpu_c.c: Exit Critical Section failed: %s.\n", p_msg); + + LocalFree(p_msg); +#endif + } +#elif (CPU_CFG_CRITICAL_METHOD_WIN32 == WIN32_CRITICAL_SECTION) + LeaveCriticalSection(&CriticalSection); +#endif +} + + +/* +********************************************************************************************************* +* CPU_Printf() +* +* Description: This function is analog of printf. +* +* Arguments : p_str Pointer to format string output. +* +* Returns : Number of characters written. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_MSG_TRACE_EN +static int CPU_Printf (char *p_str, ...) +{ + va_list param; + int ret; + + + va_start(param, p_str); + ret = vprintf_s(p_str, param); + va_end(param); + + return (ret); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s). +* +* 0, otherwise. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* 0 0 0 1 x x x x 3 +* 0 0 0 0 1 x x x 4 +* 0 0 0 0 0 1 x x 5 +* 0 0 0 0 0 0 1 x 6 +* 0 0 0 0 0 0 0 1 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 11 +* 0 0 0 0 1 x x x 12 +* 0 0 0 0 0 1 x x 13 +* 0 0 0 0 0 0 1 x 14 +* 0 0 0 0 0 0 0 1 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +* +* (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT +* is #define'd in 'cpu_cfg.h' or 'cpu.h'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#ifdef _MSC_VER +CPU_DATA CPU_CntLeadZeros (CPU_DATA val) +{ + DWORD clz; + + + if (val == 0u) { + return (32u); + } + + _BitScanReverse(&clz, (DWORD)val); + + return (31u - (CPU_DATA)clz); +} +#endif +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* (4) 64-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* x x x x 1 0 0 0 3 +* x x x 1 0 0 0 0 4 +* x x 1 0 0 0 0 0 5 +* x 1 0 0 0 0 0 0 6 +* 1 0 0 0 0 0 0 0 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 11 +* x x x 1 0 0 0 0 12 +* x x 1 0 0 0 0 0 13 +* x 1 0 0 0 0 0 0 14 +* 1 0 0 0 0 0 0 0 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 27 +* x x x 1 0 0 0 0 28 +* x x 1 0 0 0 0 0 29 +* x 1 0 0 0 0 0 0 30 +* 1 0 0 0 0 0 0 0 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (4) For 64-bit values : +* +* b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 59 +* x x x 1 0 0 0 0 60 +* x x 1 0 0 0 0 0 61 +* x 1 0 0 0 0 0 0 62 +* 1 0 0 0 0 0 0 0 63 +* 0 0 0 0 0 0 0 0 64 +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) CPU_CntTrailZeros()'s final conditional statement calculates 'val's number of +* trailing zeros based on its return data size, 'CPU_CFG_DATA_SIZE', & 'val's +* calculated number of lead zeros ONLY if the initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final statement. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT +#ifdef _MSC_VER +CPU_DATA CPU_CntTrailZeros (CPU_DATA val) +{ + DWORD ctz; + + + if (val == 0u) { + return (32u); + } + + _BitScanForward(&ctz, (DWORD)val); + + return ((CPU_DATA)ctz); +} +#endif +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/cpu_cache.h b/cpu_cache.h new file mode 100644 index 0000000..e863181 --- /dev/null +++ b/cpu_cache.h @@ -0,0 +1,135 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CACHE CPU MODULE +* +* Filename : cpu_cache.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This cache CPU header file is protected from multiple pre-processor inclusion through use of +* the cache CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_CACHE_MODULE_PRESENT /* See Note #1. */ +#define CPU_CACHE_MODULE_PRESENT + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef CPU_CACHE_MODULE +#define CPU_CACHE_EXT +#else +#define CPU_CACHE_EXT extern +#endif + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#include +#include +#include + + +/* +********************************************************************************************************* +* CACHE CONFIGURATION +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_CACHE_MGMT_EN +#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* CACHE OPERATIONS DEFINES +********************************************************************************************************* +*/ + +#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) +#ifndef CPU_DCACHE_RANGE_FLUSH +#define CPU_DCACHE_RANGE_FLUSH(addr_start, len) CPU_DCache_RangeFlush(addr_start, len) +#endif /* CPU_DCACHE_RANGE_FLUSH */ +#else +#define CPU_DCACHE_RANGE_FLUSH(addr_start, len) +#endif /* CPU_CFG_CACHE_MGMT_EN) */ + + +#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) +#ifndef CPU_DCACHE_RANGE_INV +#define CPU_DCACHE_RANGE_INV(addr_start, len) CPU_DCache_RangeInv(addr_start, len) +#endif /* CPU_DCACHE_RANGE_INV */ +#else +#define CPU_DCACHE_RANGE_INV(addr_start, len) +#endif /* CPU_CFG_CACHE_MGMT_EN) */ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + +#ifdef __cplusplus +extern "C" { +#endif + +void CPU_Cache_Init (void); + +void CPU_DCache_RangeFlush(void *addr_start, + CPU_ADDR len); + +void CPU_DCache_RangeInv (void *addr_start, + CPU_ADDR len); + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CFG_CACHE_MGMT_EN */ + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu_core.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU core module include. */ diff --git a/cpu_core.c b/cpu_core.c new file mode 100644 index 0000000..5c1f599 --- /dev/null +++ b/cpu_core.c @@ -0,0 +1,2254 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CPU MODULE +* +* Filename : cpu_core.c +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define MICRIUM_SOURCE +#define CPU_CORE_MODULE +#include "cpu_core.h" + +#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) +#include "cpu_cache.h" +#endif + + +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + /* Pop cnt algorithm csts. */ +#define CRC_UTIL_POPCNT_MASK01010101_32 0x55555555u +#define CRC_UTIL_POPCNT_MASK00110011_32 0x33333333u +#define CRC_UTIL_POPCNT_MASK00001111_32 0x0F0F0F0Fu +#define CRC_UTIL_POPCNT_POWERSOF256_32 0x01010101u + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU COUNT LEAD ZEROs LOOKUP TABLE +* +* Note(s) : (1) Index into bit pattern table determines the number of leading zeros in an 8-bit value : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* 0 0 0 1 x x x x 3 +* 0 0 0 0 1 x x x 4 +* 0 0 0 0 0 1 x x 5 +* 0 0 0 0 0 0 1 x 6 +* 0 0 0 0 0 0 0 1 7 +* 0 0 0 0 0 0 0 0 8 +********************************************************************************************************* +*/ + +#if (!(defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) || \ + (CPU_CFG_DATA_SIZE_MAX > CPU_CFG_DATA_SIZE)) +static const CPU_INT08U CPU_CntLeadZerosTbl[256] = { /* Data vals : */ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 8u, 7u, 6u, 6u, 5u, 5u, 5u, 5u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, /* 0x00 to 0x0F */ + 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, /* 0x10 to 0x1F */ + 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x20 to 0x2F */ + 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x30 to 0x3F */ + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x40 to 0x4F */ + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x50 to 0x5F */ + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x60 to 0x6F */ + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x70 to 0x7F */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x80 to 0x8F */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x90 to 0x9F */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xA0 to 0xAF */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xB0 to 0xBF */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xC0 to 0xCF */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xD0 to 0xDF */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xE0 to 0xEF */ + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u /* 0xF0 to 0xFF */ +}; +#endif + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U const CPU_EndiannessTest = 0x12345678LU; /* Variable to test CPU endianness. */ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) /* ---------------- CPU NAME FNCTS ---------------- */ +static void CPU_NameInit (void); +#endif + + + /* ----------------- CPU TS FNCTS ----------------- */ +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ + (CPU_CFG_TS_TMR_EN == DEF_ENABLED)) +static void CPU_TS_Init (void); +#endif + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN /* ---------- CPU INT DIS TIME MEAS FNCTS --------- */ +static void CPU_IntDisMeasInit (void); + +static CPU_TS_TMR CPU_IntDisMeasMaxCalc(CPU_TS_TMR time_tot_cnts); +#endif + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU_Init() +* +* Description : (1) Initialize CPU module : +* +* (a) Initialize CPU timestamps +* (b) Initialize CPU interrupts disabled time measurements +* (c) Initialize CPU host name +* +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (2) CPU_Init() MUST be called ... : +* +* (a) ONLY ONCE from a product's application; ... +* (b) BEFORE product's application calls any core CPU module function(s) +* +* (3) The following initialization functions MUST be sequenced as follows : +* +* (a) CPU_TS_Init() SHOULD precede ALL calls to other CPU timestamp functions +* +* (b) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT() +* & other CPU interrupts disabled time measurement functions +********************************************************************************************************* +*/ + +void CPU_Init (void) +{ + /* --------------------- INIT TS ---------------------- */ +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ + (CPU_CFG_TS_TMR_EN == DEF_ENABLED)) + CPU_TS_Init(); /* See Note #3a. */ +#endif + /* -------------- INIT INT DIS TIME MEAS -------------- */ +#ifdef CPU_CFG_INT_DIS_MEAS_EN + CPU_IntDisMeasInit(); /* See Note #3b. */ +#endif + + /* ------------------ INIT CPU NAME ------------------- */ +#if (CPU_CFG_NAME_EN == DEF_ENABLED) + CPU_NameInit(); +#endif + +#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED) + CPU_Cache_Init(); +#endif +} + + +/* +********************************************************************************************************* +* CPU_SW_Exception() +* +* Description : Trap unrecoverable software exception. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) CPU_SW_Exception() deadlocks the current code execution -- whether multi-tasked/ +* -processed/-threaded or single-threaded -- when the current code execution cannot +* gracefully recover or report a fault or exception condition. +* +* See also 'cpu_core.h CPU_SW_EXCEPTION() Note #1'. +********************************************************************************************************* +*/ + +void CPU_SW_Exception (void) +{ + for (;;) { + ; + } +} + + +/* +********************************************************************************************************* +* CPU_NameClr() +* +* Description : Clear CPU Name. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +void CPU_NameClr (void) +{ + CPU_SR_ALLOC(); + + + CPU_CRITICAL_ENTER(); + Mem_Clr((void *)&CPU_Name[0], + (CPU_SIZE_T) CPU_CFG_NAME_SIZE); + CPU_CRITICAL_EXIT(); +} +#endif + + +/* +********************************************************************************************************* +* CPU_NameGet() +* +* Description : Get CPU host name. +* +* Argument(s) : p_name Pointer to an ASCII character array that will receive the return CPU host +* name ASCII string from this function (see Note #1). +* +* p_err Pointer to variable that will receive the return error code from this function : +* +* CPU_ERR_NONE CPU host name successfully returned. +* CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer. +* +* Return(s) : none. +* +* Note(s) : (1) The size of the ASCII character array that will receive the return CPU host name +* ASCII string : +* +* (a) MUST be greater than or equal to the current CPU host name's ASCII string +* size including the terminating NULL character; +* (b) SHOULD be greater than or equal to CPU_CFG_NAME_SIZE +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +void CPU_NameGet (CPU_CHAR *p_name, + CPU_ERR *p_err) +{ + CPU_SR_ALLOC(); + + + if (p_err == (CPU_ERR *)0) { + CPU_SW_EXCEPTION(;); + } + + if (p_name == (CPU_CHAR *)0) { + *p_err = CPU_ERR_NULL_PTR; + return; + } + + CPU_CRITICAL_ENTER(); + (void)Str_Copy_N(p_name, + &CPU_Name[0], + CPU_CFG_NAME_SIZE); + CPU_CRITICAL_EXIT(); + + *p_err = CPU_ERR_NONE; +} +#endif + + +/* +********************************************************************************************************* +* CPU_NameSet() +* +* Description : Set CPU host name. +* +* Argument(s) : p_name Pointer to CPU host name to set. +* +* p_err Pointer to variable that will receive the return error code from this function : +* +* CPU_ERR_NONE CPU host name successfully set. +* CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer. +* CPU_ERR_NAME_SIZE Invalid CPU host name size (see Note #1). +* +* Return(s) : none. +* +* Note(s) : (1) 'p_name' ASCII string size, including the terminating NULL character, MUST be less +* than or equal to CPU_CFG_NAME_SIZE. +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +void CPU_NameSet (const CPU_CHAR *p_name, + CPU_ERR *p_err) +{ + CPU_SIZE_T len; + CPU_SR_ALLOC(); + + + if (p_err == (CPU_ERR *)0) { + CPU_SW_EXCEPTION(;); + } + + if (p_name == (const CPU_CHAR *)0) { + *p_err = CPU_ERR_NULL_PTR; + return; + } + + len = Str_Len_N(p_name, + CPU_CFG_NAME_SIZE); + if (len < CPU_CFG_NAME_SIZE) { /* If cfg name len < max name size, ... */ + CPU_CRITICAL_ENTER(); + (void)Str_Copy_N(&CPU_Name[0], /* ... copy cfg name to CPU host name. */ + p_name, + CPU_CFG_NAME_SIZE); + CPU_CRITICAL_EXIT(); + *p_err = CPU_ERR_NONE; + + } else { + *p_err = CPU_ERR_NAME_SIZE; + } +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_Get32() +* +* Description : Get current 32-bit CPU timestamp. +* +* Argument(s) : none. +* +* Return(s) : Current 32-bit CPU timestamp (in timestamp timer counts). +* +* Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by +* either of the following equations : +* +* (a) Time measured = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Time measured Amount of time measured, in same +* units of (fractional) seconds +* as the Timer period +* +* Number timer counts +* (b) Time measured = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Time measured Amount of time measured, in seconds +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'. +* +* (2) In case the CPU timestamp timer has lower precision than the 32-bit CPU timestamp; +* its precision is extended via periodic updates by accumulating the deltas of the +* timestamp timer count values into the higher-precision 32-bit CPU timestamp. +* +* (3) After initialization, 'CPU_TS_32_Accum' & 'CPU_TS_32_TmrPrev' MUST ALWAYS +* be accessed AND updated exclusively with interrupts disabled -- but NOT +* with critical sections. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_TS32 CPU_TS_Get32 (void) +{ + CPU_TS32 ts; +#if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32) + CPU_TS_TMR tmr_cur; + CPU_TS_TMR tmr_delta; + CPU_SR_ALLOC(); + +#endif + +#if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_32) + ts = (CPU_TS32)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 32-bit ts cnts). */ + +#else + CPU_INT_DIS(); + tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */ + tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_32_TmrPrev); /* Calc delta ts tmr cnts. */ + CPU_TS_32_Accum += (CPU_TS32 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */ + CPU_TS_32_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */ + ts = (CPU_TS32 ) CPU_TS_32_Accum; + CPU_INT_EN(); +#endif + + return (ts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_Get64() +* +* Description : Get current 64-bit CPU timestamp. +* +* Argument(s) : none. +* +* Return(s) : Current 64-bit CPU timestamp (in timestamp timer counts). +* +* Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by +* either of the following equations : +* +* (a) Time measured = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Time measured Amount of time measured, in same +* units of (fractional) seconds +* as the Timer period +* +* Number timer counts +* (b) Time measured = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Time measured Amount of time measured, in seconds +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'. +* +* (2) In case the CPU timestamp timer has lower precision than the 64-bit CPU timestamp; +* its precision is extended via periodic updates by accumulating the deltas of the +* timestamp timer count values into the higher-precision 64-bit CPU timestamp. +* +* (3) After initialization, 'CPU_TS_64_Accum' & 'CPU_TS_64_TmrPrev' MUST ALWAYS +* be accessed AND updated exclusively with interrupts disabled -- but NOT +* with critical sections. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_TS64 CPU_TS_Get64 (void) +{ + CPU_TS64 ts; +#if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64) + CPU_TS_TMR tmr_cur; + CPU_TS_TMR tmr_delta; + CPU_SR_ALLOC(); +#endif + + +#if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_64) + ts = (CPU_TS64)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 64-bit ts cnts). */ + +#else + CPU_INT_DIS(); + tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */ + tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_64_TmrPrev); /* Calc delta ts tmr cnts. */ + CPU_TS_64_Accum += (CPU_TS64 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */ + CPU_TS_64_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */ + ts = (CPU_TS64 ) CPU_TS_64_Accum; + CPU_INT_EN(); +#endif + + return (ts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_Update() +* +* Description : Update current CPU timestamp(s). +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) (a) CPU timestamp(s) MUST be updated periodically by some application (or BSP) time +* handler in order to (adequately) maintain CPU timestamp(s)' time. +* +* (b) CPU timestamp(s) MUST be updated more frequently than the CPU timestamp timer +* overflows; otherwise, CPU timestamp(s) will lose time. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c2'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_EN == DEF_ENABLED) +void CPU_TS_Update (void) +{ +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) + (void)CPU_TS_Get32(); +#endif + +#if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)) + (void)CPU_TS_Get64(); +#endif +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrFreqGet() +* +* Description : Get CPU timestamp's timer frequency. +* +* Argument(s) : p_err Pointer to variable that will receive the return error code from this function : +* +* CPU_ERR_NONE CPU timestamp's timer frequency successfully +* returned. +* CPU_ERR_TS_FREQ_INVALID CPU timestamp's timer frequency invalid &/or +* NOT yet configured. +* +* Return(s) : CPU timestamp's timer frequency (in Hertz), if NO error(s). +* +* 0, otherwise. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_TS_TMR_FREQ CPU_TS_TmrFreqGet (CPU_ERR *p_err) +{ + CPU_TS_TMR_FREQ freq_hz; + + + if (p_err == (CPU_ERR *)0) { + CPU_SW_EXCEPTION(0); + } + + freq_hz = CPU_TS_TmrFreq_Hz; + *p_err = (freq_hz != 0u) ? CPU_ERR_NONE : CPU_ERR_TS_FREQ_INVALID; + + return (freq_hz); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrFreqSet() +* +* Description : Set CPU timestamp's timer frequency. +* +* Argument(s) : freq_hz Frequency (in Hertz) to set for CPU timestamp's timer. +* +* Return(s) : none. +* +* Note(s) : (1) (a) (1) CPU timestamp timer frequency is NOT required for internal CPU timestamp +* operations but may OPTIONALLY be configured by CPU_TS_TmrInit() or other +* application/BSP initialization functions. +* +* (2) CPU timestamp timer frequency MAY be used with optional CPU_TSxx_to_uSec() +* to convert CPU timestamps from timer counts into microseconds. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2a'. +* +* (b) CPU timestamp timer period SHOULD be less than the typical measured time but MUST +* be less than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2b'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +void CPU_TS_TmrFreqSet (CPU_TS_TMR_FREQ freq_hz) +{ + CPU_TS_TmrFreq_Hz = freq_hz; +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasMaxCurReset() +* +* Description : Reset current maximum interrupts disabled time. +* +* Argument(s) : none. +* +* Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts) before resetting. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c' +* & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'. +* +* Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed +* exclusively with interrupts disabled -- but NOT with critical sections. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +CPU_TS_TMR CPU_IntDisMeasMaxCurReset (void) +{ + CPU_TS_TMR time_max_cnts; + CPU_SR_ALLOC(); + + + time_max_cnts = CPU_IntDisMeasMaxCurGet(); + CPU_INT_DIS(); + CPU_IntDisMeasMaxCur_cnts = 0u; + CPU_INT_EN(); + + return (time_max_cnts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasMaxCurGet() +* +* Description : Get current maximum interrupts disabled time. +* +* Argument(s) : none. +* +* Return(s) : Current maximum interrupts disabled time (in CPU timestamp timer counts). +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c' +* & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'. +* +* Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed +* exclusively with interrupts disabled -- but NOT with critical sections. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +CPU_TS_TMR CPU_IntDisMeasMaxCurGet (void) +{ + CPU_TS_TMR time_tot_cnts; + CPU_TS_TMR time_max_cnts; + CPU_SR_ALLOC(); + + + CPU_INT_DIS(); + time_tot_cnts = CPU_IntDisMeasMaxCur_cnts; + CPU_INT_EN(); + time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts); + + return (time_max_cnts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasMaxGet() +* +* Description : Get (non-resetable) maximum interrupts disabled time. +* +* Argument(s) : none. +* +* Return(s) : (Non-resetable) maximum interrupts disabled time (in CPU timestamp timer counts). +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c' +* & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'. +* +* Note(s) : (1) After initialization, 'CPU_IntDisMeasMax_cnts' MUST ALWAYS be accessed +* exclusively with interrupts disabled -- but NOT with critical sections. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +CPU_TS_TMR CPU_IntDisMeasMaxGet (void) +{ + CPU_TS_TMR time_tot_cnts; + CPU_TS_TMR time_max_cnts; + CPU_SR_ALLOC(); + + + CPU_INT_DIS(); + time_tot_cnts = CPU_IntDisMeasMax_cnts; + CPU_INT_EN(); + time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts); + + return (time_max_cnts); +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasStart() +* +* Description : Start interrupts disabled time measurement. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +void CPU_IntDisMeasStart (void) +{ + CPU_IntDisMeasCtr++; + if (CPU_IntDisNestCtr == 0u) { /* If ints NOT yet dis'd, ... */ + CPU_IntDisMeasStart_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd start time. */ + } + CPU_IntDisNestCtr++; +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasStop() +* +* Description : Stop interrupts disabled time measurement. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code +* during critical sections is calculated by the following equations : +* +* (1) When interrupts disabled time measurements are disabled : +* +* +* | CRITICAL | | CRITICAL | +* |<- SECTION ->| |<- SECTION ->| +* | ENTER | | EXIT | +* +* Disable Enable +* Interrupts Interrupts +* +* || || || || +* || || || || +* || | ||<------------------------->|| | || +* || |<->|| | ||<----->| || +* || | | || | || | | || +* | | | | | +* interrupts time interrupts +* disabled interrupts |enabled +* | disabled | +* | (via application) | +* time time +* interrupts interrupts +* disabled ovrhd enabled ovrhd +* +* +* (A) time = [ time - time ] - time +* interrupts [ interrupts interrupts ] total +* disabled [ enabled disabled ] ovrhd +* (via application) +* +* +* (B) time = time + time +* total interrupts interrupts +* ovrhd enabled ovrhd disabled ovrhd +* +* +* where +* +* time time interrupts are disabled between +* interrupts first critical section enter & +* disabled last critical section exit (i.e. +* (via application) minus total overhead time) +* +* time time when interrupts are disabled +* interrupts +* disabled +* +* time time when interrupts are enabled +* interrupts +* enabled +* +* +* time total overhead time to disable/enable +* total interrupts during critical section +* ovrhd enter & exit +* +* time total overhead time to disable interrupts +* interrupts during critical section enter +* disabled ovrhd +* +* time total overhead time to enable interrupts +* interrupts during critical section exit +* enabled ovrhd +* +* +* (2) When interrupts disabled time measurements are enabled : +* +* +* | | | | +* |<----- CRITICAL SECTION ENTER ----->| |<------- CRITICAL SECTION EXIT ------->| +* | | | | +* +* Time Time +* Disable Measurement Measurement Enable +* Interrupts Start Stop Interrupts +* +* || | || || | || +* || | || || | || +* || | | ||<------------------------->|| | | || +* || | | |<----------->|| | ||<------------->| | | || +* || | | | | || | || | | | | || +* | | | | | | | +* interrupts get | time | get interrupts +* disabled start time | interrupts | stop time enabled +* meas | disabled | meas +* time (via application) time +* start meas stop meas +* ovrhd ovrhd +* +* +* (A) time = [ time - time ] - time +* interrupts [ stop start ] total meas +* disabled [ meas meas ] ovrhd +* (via application) +* +* +* (B) time = time + time +* total meas start meas stop meas +* ovrhd ovrhd ovrhd +* +* +* where +* +* time time interrupts are disabled between first +* interrupts critical section enter & last critical +* disabled section exit (i.e. minus measurement +* (via application) overhead time; however, this does NOT +* include any overhead time to disable +* or enable interrupts during critical +* section enter & exit) +* +* time time of disable interrupts start time +* start measurement (in timer counts) +* meas +* +* time time of disable interrupts stop time +* stop measurement (in timer counts) +* meas +* +* +* time total overhead time to start/stop disabled +* total meas interrupts time measurements (in timer +* ovrhd counts) +* +* time total overhead time after getting start +* start meas time until end of start measurement +* ovrhd function (in timer counts) +* +* time total overhead time from beginning of stop +* stop meas measurement function until after getting +* ovrhd stop time (in timer counts) +* +* +* (b) (1) (A) In order to correctly handle unsigned subtraction overflows of start times +* from stop times, CPU timestamp timer count values MUST be returned via +* word-size-configurable 'CPU_TS_TMR' data type. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'. +* +* (B) Since unsigned subtraction of start times from stop times assumes increasing +* values, timestamp timer count values MUST increase with each time count. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2b'. +* +* (2) (A) To expedite & reduce interrupts disabled time measurement overhead; only the +* subtraction of start times from stop times is performed. +* +* (B) The final calculations to subtract the interrupts disabled time measurement +* overhead is performed asynchronously in appropriate API functions. +* +* See also 'CPU_IntDisMeasMaxCalc() Note #1b'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +void CPU_IntDisMeasStop (void) +{ + CPU_TS_TMR time_ints_disd_cnts; + + + CPU_IntDisNestCtr--; + if (CPU_IntDisNestCtr == 0u) { /* If ints NO longer dis'd, ... */ + CPU_IntDisMeasStop_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd stop time & ... */ + /* ... calc ints dis'd tot time (see Note #1b2A). */ + time_ints_disd_cnts = CPU_IntDisMeasStop_cnts - + CPU_IntDisMeasStart_cnts; + /* Calc max ints dis'd times. */ + if (CPU_IntDisMeasMaxCur_cnts < time_ints_disd_cnts) { + CPU_IntDisMeasMaxCur_cnts = time_ints_disd_cnts; + } + if (CPU_IntDisMeasMax_cnts < time_ints_disd_cnts) { + CPU_IntDisMeasMax_cnts = time_ints_disd_cnts; + } + } +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s). +* +* DEF_INT_CPU_U_MAX_VAL, otherwise. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* (4) 64-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* 0 0 0 1 x x x x 3 +* 0 0 0 0 1 x x x 4 +* 0 0 0 0 0 1 x x 5 +* 0 0 0 0 0 0 1 x 6 +* 0 0 0 0 0 0 0 1 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 11 +* 0 0 0 0 1 x x x 12 +* 0 0 0 0 0 1 x x 13 +* 0 0 0 0 0 0 1 x 14 +* 0 0 0 0 0 0 0 1 15 +* 0 0 0 0 0 0 0 0 16 +* +* (3) For 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (4) For 64-bit values : +* +* b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 59 +* 0 0 0 0 1 x x x 60 +* 0 0 0 0 0 1 x x 61 +* 0 0 0 0 0 0 1 x 62 +* 0 0 0 0 0 0 0 1 63 +* 0 0 0 0 0 0 0 0 64 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntLeadZeros (CPU_DATA val) +{ + CPU_DATA nbr_lead_zeros; + + +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_08) + nbr_lead_zeros = CPU_CntLeadZeros08((CPU_INT08U)val); + +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) + nbr_lead_zeros = CPU_CntLeadZeros16((CPU_INT16U)val); + +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) + nbr_lead_zeros = CPU_CntLeadZeros32((CPU_INT32U)val); + +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) + nbr_lead_zeros = CPU_CntLeadZeros64((CPU_INT64U)val); + +#else /* See Note #1a. */ + nbr_lead_zeros = DEF_INT_CPU_U_MAX_VAL; +#endif + + + return (nbr_lead_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros08() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in an 8-bit data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) Supports 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* 0 0 0 1 x x x x 3 +* 0 0 0 0 1 x x x 4 +* 0 0 0 0 0 1 x x 5 +* 0 0 0 0 0 0 1 x 6 +* 0 0 0 0 0 0 0 1 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08) +CPU_DATA CPU_CntLeadZeros08 (CPU_INT08U val) +{ +#if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08))) + CPU_DATA ix; +#endif + CPU_DATA nbr_lead_zeros; + + /* ---------- ASM-OPTIMIZED ----------- */ +#if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08)) + nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val); + nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_08) * DEF_OCTET_NBR_BITS; + + +#else /* ----------- C-OPTIMIZED ------------ */ + /* Chk bits [07:00] : */ + /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */ + nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/ +#endif + + + return (nbr_lead_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros16() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a 16-bit data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) Supports 16-bit values : +* +* b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 11 +* 0 0 0 0 1 x x x 12 +* 0 0 0 0 0 1 x x 13 +* 0 0 0 0 0 0 1 x 14 +* 0 0 0 0 0 0 0 1 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16) +CPU_DATA CPU_CntLeadZeros16 (CPU_INT16U val) +{ +#if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16))) + CPU_DATA ix; +#endif + CPU_DATA nbr_lead_zeros; + + /* ---------- ASM-OPTIMIZED ----------- */ +#if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16)) + nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val); + nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_16) * DEF_OCTET_NBR_BITS; + + +#else /* ----------- C-OPTIMIZED ------------ */ + if (val > 0x00FFu) { /* Chk bits [15:08] : */ + val >>= 8u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 8 bits */ + nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/ + + } else { /* Chk bits [07:00] : */ + /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 8u); /* .. plus nbr msb lead zeros = 8 bits.*/ + } +#endif + + + return (nbr_lead_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros32() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a 32-bit data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) Supports 32-bit values : +* +* b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 27 +* 0 0 0 0 1 x x x 28 +* 0 0 0 0 0 1 x x 29 +* 0 0 0 0 0 0 1 x 30 +* 0 0 0 0 0 0 0 1 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32) +CPU_DATA CPU_CntLeadZeros32 (CPU_INT32U val) +{ +#if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32))) + CPU_DATA ix; +#endif + CPU_DATA nbr_lead_zeros; + + /* ---------- ASM-OPTIMIZED ----------- */ +#if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32)) + nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val); + nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_32) * DEF_OCTET_NBR_BITS; + + +#else /* ----------- C-OPTIMIZED ------------ */ + if (val > 0x0000FFFFu) { + if (val > 0x00FFFFFFu) { /* Chk bits [31:24] : */ + val >>= 24u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 24 bits */ + nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/ + + } else { /* Chk bits [23:16] : */ + val >>= 16u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 16 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 8u);/* .. plus nbr msb lead zeros = 8 bits.*/ + } + + } else { + if (val > 0x000000FFu) { /* Chk bits [15:08] : */ + val >>= 8u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 8 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 16u);/* .. plus nbr msb lead zeros = 16 bits.*/ + + } else { /* Chk bits [07:00] : */ + /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 24u);/* .. plus nbr msb lead zeros = 24 bits.*/ + } + } +#endif + + + return (nbr_lead_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntLeadZeros64() +* +* Description : Count the number of contiguous, most-significant, leading zero bits in a 64-bit data value. +* +* Argument(s) : val Data value to count leading zero bits. +* +* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'. +* +* Note(s) : (1) Supports 64-bit values : +* +* b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros +* --- --- --- --- --- --- --- --- --------------- +* 1 x x x x x x x 0 +* 0 1 x x x x x x 1 +* 0 0 1 x x x x x 2 +* : : : : : : : : : +* : : : : : : : : : +* 0 0 0 1 x x x x 59 +* 0 0 0 0 1 x x x 60 +* 0 0 0 0 0 1 x x 61 +* 0 0 0 0 0 0 1 x 62 +* 0 0 0 0 0 0 0 1 63 +* 0 0 0 0 0 0 0 0 64 +* +* +* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64) +CPU_DATA CPU_CntLeadZeros64 (CPU_INT64U val) +{ +#if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64))) + CPU_DATA ix; +#endif + CPU_DATA nbr_lead_zeros; + + /* ---------- ASM-OPTIMIZED ----------- */ +#if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64)) + nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val); + nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_64) * DEF_OCTET_NBR_BITS; + + +#else /* ----------- C-OPTIMIZED ------------ */ + if (val > 0x00000000FFFFFFFFuLL) { + if (val > 0x0000FFFFFFFFFFFFuLL) { + if (val > 0x00FFFFFFFFFFFFFFuLL) { /* Chk bits [63:56] : */ + val >>= 56u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 56 bits */ + nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/ + + } else { /* Chk bits [55:48] : */ + val >>= 48u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 48 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 8u);/* .. plus nbr msb lead zeros = 8 bits.*/ + } + + } else { + if (val > 0x000000FFFFFFFFFFuLL) { /* Chk bits [47:40] : */ + val >>= 40u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 40 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 16u);/* .. plus nbr msb lead zeros = 16 bits.*/ + + } else { /* Chk bits [39:32] : */ + val >>= 32u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 32 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 24u);/* .. plus nbr msb lead zeros = 24 bits.*/ + } + } + + } else { + if (val > 0x000000000000FFFFuLL) { + if (val > 0x0000000000FFFFFFuLL) { /* Chk bits [31:24] : */ + val >>= 24u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 24 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 32u);/* .. plus nbr msb lead zeros = 32 bits.*/ + + } else { /* Chk bits [23:16] : */ + val >>= 16u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 16 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 40u);/* .. plus nbr msb lead zeros = 40 bits.*/ + } + + } else { + if (val > 0x00000000000000FFuLL) { /* Chk bits [15:08] : */ + val >>= 8u; /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 8 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 48u);/* .. plus nbr msb lead zeros = 48 bits.*/ + + } else { /* Chk bits [07:00] : */ + /* .. Nbr lead zeros = .. */ + ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */ + nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 56u);/* .. plus nbr msb lead zeros = 56 bits.*/ + } + } + } +#endif + + + return (nbr_lead_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) (a) Supports the following data value sizes : +* +* (1) 8-bits +* (2) 16-bits +* (3) 32-bits +* (4) 64-bits +* +* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'. +* +* (b) (1) For 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* x x x x 1 0 0 0 3 +* x x x 1 0 0 0 0 4 +* x x 1 0 0 0 0 0 5 +* x 1 0 0 0 0 0 0 6 +* 1 0 0 0 0 0 0 0 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For 16-bit values : +* +* b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 11 +* x x x 1 0 0 0 0 12 +* x x 1 0 0 0 0 0 13 +* x 1 0 0 0 0 0 0 14 +* 1 0 0 0 0 0 0 0 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (3) For 32-bit values : +* +* b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 27 +* x x x 1 0 0 0 0 28 +* x x 1 0 0 0 0 0 29 +* x 1 0 0 0 0 0 0 30 +* 1 0 0 0 0 0 0 0 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (4) For 64-bit values : +* +* b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 59 +* x x x 1 0 0 0 0 60 +* x x 1 0 0 0 0 0 61 +* x 1 0 0 0 0 0 0 62 +* 1 0 0 0 0 0 0 0 63 +* 0 0 0 0 0 0 0 0 64 +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) CPU_CntTrailZeros()'s final conditional statement calculates 'val's number of +* trailing zeros based on its return data size, 'CPU_CFG_DATA_SIZE', & 'val's +* calculated number of lead zeros ONLY if the initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final 'if' statement. +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT +CPU_DATA CPU_CntTrailZeros (CPU_DATA val) +{ + CPU_DATA val_bit_mask; + CPU_DATA nbr_lead_zeros; + CPU_DATA nbr_trail_zeros; + + + if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */ + return ((CPU_DATA)(CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS)); + } + + + val_bit_mask = val & ((CPU_DATA)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */ + nbr_lead_zeros = CPU_CntLeadZeros(val_bit_mask); /* Cnt nbr lead 0s. */ + /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/ + nbr_trail_zeros = ((CPU_DATA)((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros); + + + return (nbr_trail_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros08() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in an 8-bit data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) Supports 8-bit values : +* +* b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* x x x x 1 0 0 0 3 +* x x x 1 0 0 0 0 4 +* x x 1 0 0 0 0 0 5 +* x 1 0 0 0 0 0 0 6 +* 1 0 0 0 0 0 0 0 7 +* 0 0 0 0 0 0 0 0 8 +* +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's +* number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'. +* If the returned number of zeros exceeds CPU_CntTrailZeros08()'s 8-bit return +* data size, then the returned number of zeros must be offset by the difference +* between CPU_CntTrailZeros()'s & CPU_CntTrailZeros08()'s return data size : +* +* nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); +* if (nbr_trail_zeros > (CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS)) { +* nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_08) * DEF_OCTET_NBR_BITS; +* } +* +* However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 8-bit +* values would return a number of trailing zeros less than or equal to 8 bits. +* +* Therefore, initially validating all non-'0' values prior to calling assembly- +* optimized CPU_CntTrailZeros() avoids having to offset the number of returned +* trailing zeros by the difference in CPU data size and 8-bit data value bits. +* +* (b) For CPU_CntTrailZeros08()'s C implementation, the final conditional statement +* calculates 'val's number of trailing zeros based on CPU_CntTrailZeros08()'s +* 8-bit return data size & 'val's calculated number of lead zeros ONLY if the +* initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final 'if' statement. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08) +CPU_DATA CPU_CntTrailZeros08 (CPU_INT08U val) +{ +#if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08))) + CPU_INT08U val_bit_mask; + CPU_DATA nbr_lead_zeros; +#endif + CPU_DATA nbr_trail_zeros; + + + if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */ + return ((CPU_DATA)(CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS)); + } + + /* ------------------ ASM-OPTIMIZED ------------------- */ +#if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08)) + nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); + +#else /* ------------------- C-OPTIMIZED -------------------- */ + val_bit_mask = val & ((CPU_INT08U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */ + nbr_lead_zeros = CPU_CntLeadZeros08(val_bit_mask); /* Cnt nbr lead 0s. */ + /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/ + nbr_trail_zeros = ((CPU_DATA)((CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros); +#endif + + + return (nbr_trail_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros16() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a 16-bit data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) Supports 16-bit values : +* +* b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 11 +* x x x 1 0 0 0 0 12 +* x x 1 0 0 0 0 0 13 +* x 1 0 0 0 0 0 0 14 +* 1 0 0 0 0 0 0 0 15 +* 0 0 0 0 0 0 0 0 16 +* +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's +* number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'. +* If the returned number of zeros exceeds CPU_CntTrailZeros16()'s 16-bit return +* data size, then the returned number of zeros must be offset by the difference +* between CPU_CntTrailZeros()'s & CPU_CntTrailZeros16()'s return data size : +* +* nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); +* if (nbr_trail_zeros > (CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS)) { +* nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_16) * DEF_OCTET_NBR_BITS; +* } +* +* However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 16-bit +* values would return a number of trailing zeros less than or equal to 16 bits. +* +* Therefore, initially validating all non-'0' values prior to calling assembly- +* optimized CPU_CntTrailZeros() avoids having to offset the number of returned +* trailing zeros by the difference in CPU data size and 16-bit data value bits. +* +* (b) For CPU_CntTrailZeros16()'s C implementation, the final conditional statement +* calculates 'val's number of trailing zeros based on CPU_CntTrailZeros16()'s +* 16-bit return data size & 'val's calculated number of lead zeros ONLY if the +* initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final 'if' statement. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16) +CPU_DATA CPU_CntTrailZeros16 (CPU_INT16U val) +{ +#if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16))) + CPU_INT16U val_bit_mask; + CPU_DATA nbr_lead_zeros; +#endif + CPU_DATA nbr_trail_zeros; + + + if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */ + return ((CPU_DATA)(CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS)); + } + + /* ------------------ ASM-OPTIMIZED ------------------- */ +#if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16)) + nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); + +#else /* ------------------- C-OPTIMIZED -------------------- */ + val_bit_mask = val & ((CPU_INT16U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */ + nbr_lead_zeros = CPU_CntLeadZeros16(val_bit_mask); /* Cnt nbr lead 0s. */ + /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/ + nbr_trail_zeros = ((CPU_DATA)((CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros); +#endif + + + return (nbr_trail_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros32() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a 32-bit data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) Supports 32-bit values : +* +* b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 27 +* x x x 1 0 0 0 0 28 +* x x 1 0 0 0 0 0 29 +* x 1 0 0 0 0 0 0 30 +* 1 0 0 0 0 0 0 0 31 +* 0 0 0 0 0 0 0 0 32 +* +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's +* number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'. +* If the returned number of zeros exceeds CPU_CntTrailZeros32()'s 32-bit return +* data size, then the returned number of zeros must be offset by the difference +* between CPU_CntTrailZeros()'s & CPU_CntTrailZeros32()'s return data size : +* +* nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); +* if (nbr_trail_zeros > (CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS)) { +* nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_32) * DEF_OCTET_NBR_BITS; +* } +* +* However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 32-bit +* values would return a number of trailing zeros less than or equal to 32 bits. +* +* Therefore, initially validating all non-'0' values prior to calling assembly- +* optimized CPU_CntTrailZeros() avoids having to offset the number of returned +* trailing zeros by the difference in CPU data size and 32-bit data value bits. +* +* (b) For CPU_CntTrailZeros32()'s C implementation, the final conditional statement +* calculates 'val's number of trailing zeros based on CPU_CntTrailZeros32()'s +* 32-bit return data size & 'val's calculated number of lead zeros ONLY if the +* initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final 'if' statement. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32) +CPU_DATA CPU_CntTrailZeros32 (CPU_INT32U val) +{ +#if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32))) + CPU_INT32U val_bit_mask; + CPU_DATA nbr_lead_zeros; +#endif + CPU_DATA nbr_trail_zeros; + + + if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */ + return ((CPU_DATA)(CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS)); + } + + /* ------------------ ASM-OPTIMIZED ------------------- */ +#if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32)) + nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); + +#else /* ------------------- C-OPTIMIZED -------------------- */ + val_bit_mask = val & ((CPU_INT32U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */ + nbr_lead_zeros = CPU_CntLeadZeros32(val_bit_mask); /* Cnt nbr lead 0s. */ + /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/ + nbr_trail_zeros = ((CPU_DATA)((CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros); +#endif + + + return (nbr_trail_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CPU_CntTrailZeros64() +* +* Description : Count the number of contiguous, least-significant, trailing zero bits in a 64-bit data value. +* +* Argument(s) : val Data value to count trailing zero bits. +* +* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'. +* +* Note(s) : (1) Supports 64-bit values : +* +* b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros +* --- --- --- --- --- --- --- --- ---------------- +* x x x x x x x 1 0 +* x x x x x x 1 0 1 +* x x x x x 1 0 0 2 +* : : : : : : : : : +* : : : : : : : : : +* x x x x 1 0 0 0 59 +* x x x 1 0 0 0 0 60 +* x x 1 0 0 0 0 0 61 +* x 1 0 0 0 0 0 0 62 +* 1 0 0 0 0 0 0 0 63 +* 0 0 0 0 0 0 0 0 64 +* +* +* (2) For non-zero values, the returned number of contiguous, least-significant, trailing +* zero bits is also equivalent to the bit position of the least-significant set bit. +* +* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations : +* +* (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's +* number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'. +* If the returned number of zeros exceeds CPU_CntTrailZeros64()'s 64-bit return +* data size, then the returned number of zeros must be offset by the difference +* between CPU_CntTrailZeros()'s & CPU_CntTrailZeros64()'s return data size : +* +* nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); +* if (nbr_trail_zeros > (CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS)) { +* nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_64) * DEF_OCTET_NBR_BITS; +* } +* +* However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 64-bit +* values would return a number of trailing zeros less than or equal to 64 bits. +* +* Therefore, initially validating all non-'0' values prior to calling assembly- +* optimized CPU_CntTrailZeros() avoids having to offset the number of returned +* trailing zeros by the difference in CPU data size and 64-bit data value bits. +* +* (b) For CPU_CntTrailZeros64()'s C implementation, the final conditional statement +* calculates 'val's number of trailing zeros based on CPU_CntTrailZeros64()'s +* 64-bit return data size & 'val's calculated number of lead zeros ONLY if the +* initial 'val' is non-'0' : +* +* if (val != 0u) { +* nbr_trail_zeros = ((CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros; +* } else { +* nbr_trail_zeros = nbr_lead_zeros; +* } +* +* Therefore, initially validating all non-'0' values avoids having to conditionally +* execute the final 'if' statement. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64) +CPU_DATA CPU_CntTrailZeros64 (CPU_INT64U val) +{ +#if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64))) + CPU_INT64U val_bit_mask; + CPU_DATA nbr_lead_zeros; +#endif + CPU_DATA nbr_trail_zeros; + + + if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */ + return ((CPU_DATA)(CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS)); + } + + /* ------------------ ASM-OPTIMIZED ------------------- */ +#if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \ + (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64)) + nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val); + +#else /* ------------------- C-OPTIMIZED -------------------- */ + val_bit_mask = val & ((CPU_INT64U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */ + nbr_lead_zeros = CPU_CntLeadZeros64(val_bit_mask); /* Cnt nbr lead 0s. */ + /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/ + nbr_trail_zeros = ((CPU_DATA)((CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros); +#endif + + + return (nbr_trail_zeros); +} +#endif + + +/* +********************************************************************************************************* +* CRCUtil_PopCnt_32() +* +* Description : Compute population count (hamming weight) for value (number of bits set). +* +* Argument(s) : value Value to compute population count on. +* +* +* Return(s) : value's population count. +* +* Note(s) : (1) Algorithm taken from en.wikipedia.org/wiki/Hamming_weight +********************************************************************************************************* +*/ + +CPU_INT08U CPU_PopCnt32 (CPU_INT32U value) +{ + CPU_INT32U even_cnt; + CPU_INT32U odd_cnt; + CPU_INT32U result; + + + odd_cnt = (value >> 1u) & CRC_UTIL_POPCNT_MASK01010101_32; /* 2-bits pieces. */ + result = value - odd_cnt; /* Same result as result=odd_cnt+(value & 0x55555555). */ + + even_cnt = result & CRC_UTIL_POPCNT_MASK00110011_32; /* 4-bits pieces. */ + odd_cnt = (result >> 2u) & CRC_UTIL_POPCNT_MASK00110011_32; + result = even_cnt + odd_cnt; + + even_cnt = result & CRC_UTIL_POPCNT_MASK00001111_32; /* 8-bits pieces. */ + odd_cnt = (result >> 4u) & CRC_UTIL_POPCNT_MASK00001111_32; + result = even_cnt + odd_cnt; + + result = (result * CRC_UTIL_POPCNT_POWERSOF256_32) >> 24u; + + return ((CPU_INT08U)result); +} + + +/* +********************************************************************************************************* +* CPU_StatReset() +* +* Description : Reset all performance monitors. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : Critical section provided by caller. +********************************************************************************************************* +*/ + +#if (CPU_CFG_PERF_MON_EN == DEF_ENABLED) +void CPU_StatReset (void) +{ +#ifdef CPU_CFG_INT_DIS_MEAS_EN + CPU_IntDisMeasMax_cnts = 0u; +#endif +} +#endif + + +/* +********************************************************************************************************* +********************************************************************************************************* +* LOCAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_NameInit() +* +* Description : Initialize CPU Name. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +static void CPU_NameInit (void) +{ + CPU_NameClr(); +} +#endif + + +/* +********************************************************************************************************* +* CPU_TS_Init() +* +* Description : (1) Initialize CPU timestamp : +* +* (a) Initialize/start CPU timestamp timer See Note #1 +* (b) Initialize CPU timestamp controls +* +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) The following initialization MUST be sequenced as follows : +* +* (a) CPU_TS_TmrFreq_Hz MUST be initialized prior to CPU_TS_TmrInit() +* (b) CPU_TS_TmrInit() SHOULD precede calls to all other CPU timestamp functions; +* otherwise, invalid time measurements may be calculated/ +* returned. +* +* See also 'CPU_Init() Note #3a'. +********************************************************************************************************* +*/ + +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ + (CPU_CFG_TS_TMR_EN == DEF_ENABLED)) +static void CPU_TS_Init (void) +{ +#if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \ + ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))) + CPU_TS_TMR ts_tmr_cnts; +#endif + + + /* ----------------- INIT CPU TS TMR ------------------ */ +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) + CPU_TS_TmrFreq_Hz = 0u; /* Init/clr ts tmr freq (see Note #1a). */ + CPU_TS_TmrInit(); /* Init & start ts tmr (see Note #1b). */ +#endif + + + /* ------------------- INIT CPU TS -------------------- */ +#if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \ + ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))) + ts_tmr_cnts = CPU_TS_TmrRd(); /* Get init ts tmr val (in ts tmr cnts). */ +#endif + +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) + CPU_TS_32_Accum = 0u; /* Init 32-bit accum'd ts. */ + CPU_TS_32_TmrPrev = ts_tmr_cnts; /* Init 32-bit ts prev tmr val. */ +#endif + +#if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)) + CPU_TS_64_Accum = 0u; /* Init 64-bit accum'd ts. */ + CPU_TS_64_TmrPrev = ts_tmr_cnts; /* Init 64-bit ts prev tmr val. */ +#endif +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasInit() +* +* Description : (1) Initialize interrupts disabled time measurements feature : +* +* (a) Initialize interrupts disabled time measurement controls +* (b) Calculate interrupts disabled time measurement overhead +* +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (2) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT() +* & other CPU interrupts disabled time measurement functions; otherwise, invalid interrupts +* disabled time measurements may be calculated/returned. +* +* See also 'CPU_Init() Note #3b'. +* +* (3) (a) (1) Interrupts disabled time measurement overhead performed multiple times to calculate +* a rounded average with better accuracy, hopefully of +/- one timer count. +* +* (2) However, a single overhead time measurement is recommended, even for instruction- +* cache-enabled CPUs, since critical sections are NOT typically called within +* instruction-cached loops. Thus a single non-cached/non-averaged time measurement +* is a more realistic overhead for the majority of non-cached interrupts disabled +* time measurements. +* +* (b) Interrupts MUST be disabled while measuring the interrupts disabled time measurement +* overhead; otherwise, overhead measurements could be interrupted which would incorrectly +* calculate an inflated overhead time which would then incorrectly calculate deflated +* interrupts disabled times. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +static void CPU_IntDisMeasInit (void) +{ + CPU_TS_TMR time_meas_tot_cnts; + CPU_INT16U i; + CPU_SR_ALLOC(); + + /* ----------- INIT INT DIS TIME MEAS CTRLS ----------- */ + CPU_IntDisMeasCtr = 0u; + CPU_IntDisNestCtr = 0u; + CPU_IntDisMeasStart_cnts = 0u; + CPU_IntDisMeasStop_cnts = 0u; + CPU_IntDisMeasMaxCur_cnts = 0u; + CPU_IntDisMeasMax_cnts = 0u; + CPU_IntDisMeasOvrhd_cnts = 0u; + + /* ----------- CALC INT DIS TIME MEAS OVRHD ----------- */ + time_meas_tot_cnts = 0u; + CPU_INT_DIS(); /* Ints MUST be dis'd for ovrhd calc (see Note #3b). */ + for (i = 0u; i < CPU_CFG_INT_DIS_MEAS_OVRHD_NBR; i++) { + CPU_IntDisMeasMaxCur_cnts = 0u; + CPU_IntDisMeasStart(); /* Perform multiple consecutive start/stop time meas's */ + CPU_IntDisMeasStop(); + time_meas_tot_cnts += CPU_IntDisMeasMaxCur_cnts; /* ... & sum time meas max's ... */ + } + /* ... to calc avg time meas ovrhd (see Note #3a). */ + CPU_IntDisMeasOvrhd_cnts = (time_meas_tot_cnts + (CPU_CFG_INT_DIS_MEAS_OVRHD_NBR / 2u)) + / CPU_CFG_INT_DIS_MEAS_OVRHD_NBR; + CPU_IntDisMeasMaxCur_cnts = 0u; /* Reset max ints dis'd times. */ + CPU_IntDisMeasMax_cnts = 0u; + CPU_INT_EN(); +} +#endif + + +/* +********************************************************************************************************* +* CPU_IntDisMeasMaxCalc() +* +* Description : Calculate maximum interrupts disabled time. +* +* Argument(s) : time_tot_cnts Total interrupt disabled time, in timer counts. +* +* Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts). +* +* Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code +* during critical sections is calculated by the following equations : +* +* (1) time = [ time - time ] - time +* interrupts [ stop start ] total meas +* disabled [ meas meas ] ovrhd +* (via application) +* +* +* (2) time = time + time +* total meas start meas stop meas +* ovrhd ovrhd ovrhd +* +* +* where +* +* time time interrupts are disabled between +* interrupts first critical section enter & +* disabled last critical section exit minus +* (via application) time measurement overhead +* +* time time of disable interrupts start time +* start measurement (in timer counts) +* meas +* +* time time of disable interrupts stop time +* stop measurement (in timer counts) +* meas +* +* time total overhead time to start/stop disabled +* total meas interrupts time measurements (in timer +* ovrhd counts) +* +* time total overhead time after getting start +* start meas time until end of start measurement +* ovrhd function (in timer counts) +* +* time total overhead time from beginning of stop +* stop meas measurement function until after getting +* ovrhd stop time (in timer counts) +* +* +* (b) To expedite & reduce interrupts disabled time measurement overhead, the final +* calculations to subtract the interrupts disabled time measurement overhead is +* performed asynchronously in API functions. +* +* See also 'CPU_IntDisMeasStop() Note #1b2'. +* +* (c) The amount of time interrupts are disabled is calculated by either of the +* following equations : +* +* (1) Interrupts disabled time = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Interrupts disabled time Amount of time interrupts are +* disabled, in same units of +* (fractional) seconds as the +* Timer period +* +* Number timer counts +* (2) Interrupts disabled time = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Interrupts disabled time Amount of time interrupts are +* disabled, in seconds +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c' +* & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'. +* +* (2) Although it is not typical, it is possible for an interrupts disabled time +* measurement to be less than the interrupts disabled time measurement overhead; +* especially if the overhead was calculated with a single, non-cached measurement +* & critical sections are called within instruction-cached loops. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +static CPU_TS_TMR CPU_IntDisMeasMaxCalc (CPU_TS_TMR time_tot_cnts) +{ + CPU_TS_TMR time_max_cnts; + + + time_max_cnts = time_tot_cnts; + if (time_max_cnts > CPU_IntDisMeasOvrhd_cnts) { /* If max ints dis'd time > ovrhd time, ... */ + time_max_cnts -= CPU_IntDisMeasOvrhd_cnts; /* ... adj max ints dis'd time by ovrhd time; ... */ + } else { /* ... else max ints dis'd time < ovrhd time, ... */ + time_max_cnts = 0u; /* ... clr max ints dis'd time (see Note #2). */ + } + + return (time_max_cnts); +} +#endif + diff --git a/cpu_core.h b/cpu_core.h new file mode 100644 index 0000000..4ad1bb7 --- /dev/null +++ b/cpu_core.h @@ -0,0 +1,1031 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CPU MODULE +* +* Filename : cpu_core.h +* Version : V1.32.00 +********************************************************************************************************* +* Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in +* the project build : +* +* (a) uC/LIB V1.38.02 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This core CPU header file is protected from multiple pre-processor inclusion through use of +* the core CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_CORE_MODULE_PRESENT /* See Note #1. */ +#define CPU_CORE_MODULE_PRESENT + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef CPU_CORE_MODULE +#define CPU_CORE_EXT +#else +#define CPU_CORE_EXT extern +#endif + + +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) CPU-configuration software files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_*.* +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) NO compiler-supplied standard library functions SHOULD be used. +* +* (a) Standard library functions are implemented in the custom library module(s) : +* +* \\lib_*.* +* +* where +* directory path for custom library software +* +* (3) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (c) '\\' directory See Note #2a +********************************************************************************************************* +*/ + +#include +#include +#include + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +#include +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* CPU CONFIGURATION +* +* Note(s) : (1) The following pre-processor directives correctly configure CPU parameters. DO NOT MODIFY. +* +* (2) CPU timestamp timer feature is required for : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurement +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_TS_EN +#undef CPU_CFG_TS_EN +#endif + + +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) || \ + (CPU_CFG_TS_64_EN == DEF_ENABLED)) +#define CPU_CFG_TS_EN DEF_ENABLED +#else +#define CPU_CFG_TS_EN DEF_DISABLED +#endif + +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ +(defined(CPU_CFG_INT_DIS_MEAS_EN))) +#define CPU_CFG_TS_TMR_EN DEF_ENABLED +#else +#define CPU_CFG_TS_TMR_EN DEF_DISABLED +#endif + +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ +(defined(CPU_CFG_INT_DIS_MEAS_EN))) +#define CPU_CFG_PERF_MON_EN DEF_ENABLED +#else +#define CPU_CFG_PERF_MON_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* CACHE CONFIGURATION +* +* Note(s) : (1) The following pre-processor directives correctly configure CACHE parameters. DO NOT MODIFY. +* +********************************************************************************************************** +*/ + +#ifndef CPU_CFG_CACHE_MGMT_EN +#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define CPU_TIME_MEAS_NBR_MIN 1u +#define CPU_TIME_MEAS_NBR_MAX 128u + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU ERROR CODES +********************************************************************************************************* +*/ + +typedef enum cpu_err { + + CPU_ERR_NONE = 0u, + CPU_ERR_NULL_PTR = 10u, + + CPU_ERR_NAME_SIZE = 1000u, + + CPU_ERR_TS_FREQ_INVALID = 2000u + +} CPU_ERR; + + +/* +********************************************************************************************************* +* CPU TIMESTAMP DATA TYPES +* +* Note(s) : (1) CPU timestamp timer data type defined to the binary-multiple of 8-bit octets as configured +* by 'CPU_CFG_TS_TMR_SIZE' (see 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'). +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_TS32; +typedef CPU_INT64U CPU_TS64; + +typedef CPU_TS32 CPU_TS; /* Req'd for backwards-compatibility. */ + + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) /* CPU ts tmr defined to cfg'd word size (see Note #1). */ +#if (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_08) +typedef CPU_INT08U CPU_TS_TMR; +#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_TS_TMR; +#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_TS_TMR; +#else /* CPU ts tmr dflt size = 32-bits. */ +typedef CPU_INT32U CPU_TS_TMR; +#endif +#endif + + +/* +********************************************************************************************************* +* CPU TIMESTAMP TIMER FREQUENCY DATA TYPE +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_TS_TMR_FREQ; + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +CPU_CORE_EXT CPU_CHAR CPU_Name[CPU_CFG_NAME_SIZE]; /* CPU host name. */ +#endif + + +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) +CPU_CORE_EXT CPU_TS32 CPU_TS_32_Accum; /* 32-bit accum'd ts (in ts tmr cnts). */ +CPU_CORE_EXT CPU_TS_TMR CPU_TS_32_TmrPrev; /* 32-bit ts prev tmr (in ts tmr cnts). */ +#endif + +#if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)) +CPU_CORE_EXT CPU_TS64 CPU_TS_64_Accum; /* 64-bit accum'd ts (in ts tmr cnts). */ +CPU_CORE_EXT CPU_TS_TMR CPU_TS_64_TmrPrev; /* 64-bit ts prev tmr (in ts tmr cnts). */ +#endif + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_CORE_EXT CPU_TS_TMR_FREQ CPU_TS_TmrFreq_Hz; /* CPU ts tmr freq (in Hz). */ +#endif + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +CPU_CORE_EXT CPU_INT16U CPU_IntDisMeasCtr; /* Nbr tot ints dis'd ctr. */ +CPU_CORE_EXT CPU_INT16U CPU_IntDisNestCtr; /* Nbr nested ints dis'd ctr. */ + /* Ints dis'd time (in ts tmr cnts) : ... */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStart_cnts; /* ... start time. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStop_cnts; /* ... stop time. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasOvrhd_cnts; /* ... time meas ovrhd. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMaxCur_cnts; /* ... resetable max time dis'd. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMax_cnts; /* ... non-resetable max time dis'd. */ +#endif + + +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_SW_EXCEPTION() +* +* Description : Trap unrecoverable software exception. +* +* Argument(s) : err_rtn_val Error type &/or value of the calling function to return (see Note #2b). +* +* Return(s) : none. +* +* Note(s) : (1) CPU_SW_EXCEPTION() deadlocks the current code execution -- whether multi-tasked/ +* -processed/-threaded or single-threaded -- when the current code execution cannot +* gracefully recover or report a fault or exception condition. +* +* Example CPU_SW_EXCEPTION() call : +* +* void Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { If 'p_err' NULL, cannot return error ... +* CPU_SW_EXCEPTION(;); ... so trap invalid argument exception. +* } +* +* : +* } +* +* See also 'cpu_core.c CPU_SW_Exception() Note #1'. +* +* (2) (a) CPU_SW_EXCEPTION() MAY be developer-implemented to output &/or handle any error or +* exception conditions; but since CPU_SW_EXCEPTION() is intended to trap unrecoverable +* software conditions, it is recommended that developer-implemented versions prevent +* execution of any code following calls to CPU_SW_EXCEPTION() by deadlocking the code +* (see Note #1). +* +* Example CPU_SW_EXCEPTION() : +* +* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ +* Log(__FILE__, __LINE__); \ +* CPU_SW_Exception(); \ +* } while (0) +* +* (b) (1) However, if execution of code following calls to CPU_SW_EXCEPTION() is required +* (e.g. for automated testing); it is recommended that the last statement in +* developer-implemented versions be to return from the current function to prevent +* possible software exception(s) in the current function from triggering CPU &/or +* hardware exception(s). +* +* Example CPU_SW_EXCEPTION() : +* +* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ +* Log(__FILE__, __LINE__); \ +* return err_rtn_val; \ +* } while (0) +* +* (A) Note that 'err_rtn_val' in the return statement MUST NOT be enclosed in +* parentheses. This allows CPU_SW_EXCEPTION() to return from functions that +* return 'void', i.e. NO return type or value (see also Note #2b2A). +* +* (2) In order for CPU_SW_EXCEPTION() to return from functions with various return +* types/values, each caller function MUST pass an appropriate error return type +* & value to CPU_SW_EXCEPTION(). +* +* (A) Note that CPU_SW_EXCEPTION() MUST NOT be passed any return type or value +* for functions that return 'void', i.e. NO return type or value; but SHOULD +* instead be passed a single semicolon. This prevents possible compiler +* warnings that CPU_SW_EXCEPTION() is passed too few arguments. However, +* the compiler may warn that CPU_SW_EXCEPTION() does NOT prevent creating +* null statements on lines with NO other code statements. +* +* Example CPU_SW_EXCEPTION() calls : +* +* void Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION(;); Exception macro returns NO value +* } (see Note #2b2A) +* +* : +* } +* +* CPU_BOOLEAN Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION(DEF_FAIL); Exception macro returns 'DEF_FAIL' +* } +* +* : +* } +* +* OBJ *Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION((OBJ *)0); Exception macro returns NULL 'OBJ *' +* } +* +* : +* } +* +********************************************************************************************************* +*/ + +#ifndef CPU_SW_EXCEPTION /* See Note #2. */ +#define CPU_SW_EXCEPTION(err_rtn_val) do { \ + CPU_SW_Exception(); \ + } while (0) +#endif + + +/* +********************************************************************************************************* +* CPU_VAL_UNUSED() +* +* Description : Suppresses unused variable warnings. +* +* Argument(s) : none. +* +* Return(s) : none. +* + Note(s) : none. +********************************************************************************************************* +*/ + + +#define CPU_VAL_UNUSED(val) ((void)(val)); + + +#define CPU_VAL_IGNORED(val) CPU_VAL_UNUSED(val) + + +/* +********************************************************************************************************* +* CPU_TYPE_CREATE() +* +* Description : Creates a generic type value. +* +* Argument(s) : char_1 1st ASCII character to create generic type value. +* +* char_2 2nd ASCII character to create generic type value. +* +* char_3 3rd ASCII character to create generic type value. +* +* char_4 4th ASCII character to create generic type value. +* +* Return(s) : 32-bit generic type value. +* +* Note(s) : (1) (a) Generic type values should be #define'd with large, non-trivial values to trap +* & discard invalid/corrupted objects based on type value. +* +* In other words, by assigning large, non-trivial values to valid objects' type +* fields; the likelihood that an object with an unassigned &/or corrupted type +* field will contain a value is highly improbable & therefore the object itself +* will be trapped as invalid. +* +* (b) (1) CPU_TYPE_CREATE() creates a 32-bit type value from four values. +* +* (2) Ideally, generic type values SHOULD be created from 'CPU_CHAR' characters to +* represent ASCII string abbreviations of the specific object types. Memory +* displays of object type values will display the specific object types with +* their chosen ASCII names. +* +* Examples : +* +* #define FILE_TYPE CPU_TYPE_CREATE('F', 'I', 'L', 'E') +* #define BUF_TYPE CPU_TYPE_CREATE('B', 'U', 'F', ' ') +********************************************************************************************************* +*/ + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)))) + +#else + +#if ((CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) || \ + (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1))) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)) << (3u * DEF_OCTET_NBR_BITS))) + + +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3))) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)) << (1u * DEF_OCTET_NBR_BITS))) + +#else /* Dflt CPU_WORD_SIZE_08. */ +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)))) +#endif +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* Note(s) : (1) CPU interrupts disabled time measurement functions prototyped/defined only if +* CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h'. +* +* (2) (a) CPU_CntLeadZeros() defined in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) +* +* (b) CPU_CntTrailZeros() defined in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) +********************************************************************************************************* +*/ + +void CPU_Init (void); + +void CPU_SW_Exception (void); + + + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) /* -------------- CPU NAME FNCTS -------------- */ +void CPU_NameClr (void); + +void CPU_NameGet ( CPU_CHAR *p_name, + CPU_ERR *p_err); + +void CPU_NameSet (const CPU_CHAR *p_name, + CPU_ERR *p_err); +#endif + + + + /* --------------- CPU TS FNCTS --------------- */ +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_TS32 CPU_TS_Get32 (void); +#endif + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_TS64 CPU_TS_Get64 (void); +#endif + +#if (CPU_CFG_TS_EN == DEF_ENABLED) +void CPU_TS_Update (void); +#endif + + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) /* ------------- CPU TS TMR FNCTS ------------- */ +CPU_TS_TMR_FREQ CPU_TS_TmrFreqGet (CPU_ERR *p_err); + +void CPU_TS_TmrFreqSet (CPU_TS_TMR_FREQ freq_hz); +#endif + + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN /* -------- CPU INT DIS TIME MEAS FNCTS ------- */ + /* See Note #1. */ +CPU_TS_TMR CPU_IntDisMeasMaxCurReset(void); + +CPU_TS_TMR CPU_IntDisMeasMaxCurGet (void); + +CPU_TS_TMR CPU_IntDisMeasMaxGet (void); + + +void CPU_IntDisMeasStart (void); + +void CPU_IntDisMeasStop (void); +#endif + + + + /* ----------- CPU CNT ZEROS FNCTS ------------ */ +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#ifdef __cplusplus +extern "C" { +#endif +#endif + +CPU_DATA CPU_CntLeadZeros (CPU_DATA val); + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#ifdef __cplusplus +} +#endif +#endif + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08) +CPU_DATA CPU_CntLeadZeros08 (CPU_INT08U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16) +CPU_DATA CPU_CntLeadZeros16 (CPU_INT16U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32) +CPU_DATA CPU_CntLeadZeros32 (CPU_INT32U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64) +CPU_DATA CPU_CntLeadZeros64 (CPU_INT64U val); +#endif + + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#ifdef __cplusplus +extern "C" { +#endif +#endif + +CPU_DATA CPU_CntTrailZeros (CPU_DATA val); + +#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#ifdef __cplusplus +} +#endif +#endif + +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08) +CPU_DATA CPU_CntTrailZeros08 (CPU_INT08U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16) +CPU_DATA CPU_CntTrailZeros16 (CPU_INT16U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32) +CPU_DATA CPU_CntTrailZeros32 (CPU_INT32U val); +#endif +#if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64) +CPU_DATA CPU_CntTrailZeros64 (CPU_INT64U val); +#endif + +CPU_INT08U CPU_PopCnt32 (CPU_INT32U value); + + /* ------------ CPU PERF MON RESET ------------ */ +#if (CPU_CFG_PERF_MON_EN == DEF_ENABLED) +void CPU_StatReset (void); +#endif + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* DEFINED IN PRODUCT'S BSP +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_TS_TmrInit() +* +* Description : Initialize & start CPU timestamp timer. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (c) When applicable, timer period SHOULD be less than the typical measured time +* but MUST be less than the maximum measured time; otherwise, timer resolution +* inadequate to measure desired times. +* +* See also 'CPU_TS_TmrRd() Note #2'. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +void CPU_TS_TmrInit(void); +#endif + + +/* +********************************************************************************************************* +* CPU_TS_TmrRd() +* +* Description : Get current CPU timestamp timer count value. +* +* Argument(s) : none. +* +* Return(s) : Timestamp timer count (see Notes #2a & #2b). +* +* Note(s) : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer +* if either of the following CPU features is enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR' +* data type. +* +* (1) If timer has more bits, truncate timer values' higher-order bits greater +* than the configured 'CPU_TS_TMR' timestamp timer data type word size. +* +* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR' +* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be +* configured so that ALL bits in 'CPU_TS_TMR' data type are significant. +* +* In other words, if timer size is not a binary-multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple +* octet word size SHOULD be configured (e.g. to 16-bits). However, the +* minimum supported word size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2' +* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'. +* +* (b) Timer SHOULD be an 'up' counter whose values increase with each time count. +* +* (1) If timer is a 'down' counter whose values decrease with each time count, +* then the returned timer value MUST be ones-complemented. +* +* (c) (1) When applicable, the amount of time measured by CPU timestamps is +* calculated by either of the following equations : +* +* (A) Time measured = Number timer counts * Timer period +* +* where +* +* Number timer counts Number of timer counts measured +* Timer period Timer's period in some units of +* (fractional) seconds +* Time measured Amount of time measured, in same +* units of (fractional) seconds +* as the Timer period +* +* Number timer counts +* (B) Time measured = --------------------- +* Timer frequency +* +* where +* +* Number timer counts Number of timer counts measured +* Timer frequency Timer's frequency in some units +* of counts per second +* Time measured Amount of time measured, in seconds +* +* (2) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_TS_TMR CPU_TS_TmrRd(void); +#endif + + +/* +********************************************************************************************************* +* CPU_TSxx_to_uSec() +* +* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds. +* +* Argument(s) : ts_cnts CPU timestamp (in timestamp timer counts [see Note #2aA]). +* +* Return(s) : Converted CPU timestamp (in microseconds [see Note #2aD]). +* +* Note(s) : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be +* optionally defined by the developer when either of the following CPU features is +* enabled : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurements +* +* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'. +* +* (2) (a) The amount of time measured by CPU timestamps is calculated by either of +* the following equations : +* +* 10^6 microseconds +* (1) Time measured = Number timer counts * ------------------- * Timer period +* 1 second +* +* Number timer counts 10^6 microseconds +* (2) Time measured = --------------------- * ------------------- +* Timer frequency 1 second +* +* where +* +* (A) Number timer counts Number of timer counts measured +* (B) Timer frequency Timer's frequency in some units +* of counts per second +* (C) Timer period Timer's period in some units of +* (fractional) seconds +* (D) Time measured Amount of time measured, +* in microseconds +* +* (b) Timer period SHOULD be less than the typical measured time but MUST be less +* than the maximum measured time; otherwise, timer resolution inadequate to +* measure desired times. +* +* (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits +* -- up to 32 or 64, respectively -- into microseconds. +********************************************************************************************************* +*/ + +#if (CPU_CFG_TS_32_EN == DEF_ENABLED) +CPU_INT64U CPU_TS32_to_uSec(CPU_TS32 ts_cnts); +#endif + +#if (CPU_CFG_TS_64_EN == DEF_ENABLED) +CPU_INT64U CPU_TS64_to_uSec(CPU_TS64 ts_cnts); +#endif + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_NAME_EN +#error "CPU_CFG_NAME_EN not #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_ENABLED ] " +#error " [ || DEF_DISABLED] " + +#elif ((CPU_CFG_NAME_EN != DEF_ENABLED ) && \ + (CPU_CFG_NAME_EN != DEF_DISABLED)) +#error "CPU_CFG_NAME_EN illegally #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_ENABLED ] " +#error " [ || DEF_DISABLED] " + + +#elif (CPU_CFG_NAME_EN == DEF_ENABLED) + +#ifndef CPU_CFG_NAME_SIZE +#error "CPU_CFG_NAME_SIZE not #define'd in 'cpu_cfg.h'" +#error " [MUST be >= 1] " +#error " [ && <= 255] " + +#elif (DEF_CHK_VAL(CPU_CFG_NAME_SIZE, \ + 1, \ + DEF_INT_08U_MAX_VAL) != DEF_OK) +#error "CPU_CFG_NAME_SIZE illegally #define'd in 'cpu_cfg.h'" +#error " [MUST be >= 1] " +#error " [ && <= 255] " +#endif + +#endif + + + + +#ifndef CPU_CFG_TS_32_EN +#error "CPU_CFG_TS_32_EN not #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((CPU_CFG_TS_32_EN != DEF_DISABLED) && \ + (CPU_CFG_TS_32_EN != DEF_ENABLED )) +#error "CPU_CFG_TS_32_EN illegally #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#endif + + +#ifndef CPU_CFG_TS_64_EN +#error "CPU_CFG_TS_64_EN not #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((CPU_CFG_TS_64_EN != DEF_DISABLED) && \ + (CPU_CFG_TS_64_EN != DEF_ENABLED )) +#error "CPU_CFG_TS_64_EN illegally #define'd in 'cpu_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#endif + + /* Correctly configured in 'cpu_core.h'; DO NOT MODIFY. */ +#ifndef CPU_CFG_TS_EN +#error "CPU_CFG_TS_EN not #define'd in 'cpu_core.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((CPU_CFG_TS_EN != DEF_DISABLED) && \ + (CPU_CFG_TS_EN != DEF_ENABLED )) +#error "CPU_CFG_TS_EN illegally #define'd in 'cpu_core.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#endif + + + /* Correctly configured in 'cpu_core.h'; DO NOT MODIFY. */ +#ifndef CPU_CFG_TS_TMR_EN +#error "CPU_CFG_TS_TMR_EN not #define'd in 'cpu_core.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((CPU_CFG_TS_TMR_EN != DEF_DISABLED) && \ + (CPU_CFG_TS_TMR_EN != DEF_ENABLED )) +#error "CPU_CFG_TS_TMR_EN illegally #define'd in 'cpu_core.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + + +#elif (CPU_CFG_TS_TMR_EN == DEF_ENABLED) + +#ifndef CPU_CFG_TS_TMR_SIZE +#error "CPU_CFG_TS_TMR_SIZE not #define'd in 'cpu_cfg.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit timer]" +#error " [ || CPU_WORD_SIZE_16 16-bit timer]" +#error " [ || CPU_WORD_SIZE_32 32-bit timer]" +#error " [ || CPU_WORD_SIZE_64 64-bit timer]" + +#elif ((CPU_CFG_TS_TMR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_TS_TMR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_TS_TMR_SIZE != CPU_WORD_SIZE_32) && \ + (CPU_CFG_TS_TMR_SIZE != CPU_WORD_SIZE_64)) +#error "CPU_CFG_TS_TMR_SIZE illegally #define'd in 'cpu_cfg.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit timer]" +#error " [ || CPU_WORD_SIZE_16 16-bit timer]" +#error " [ || CPU_WORD_SIZE_32 32-bit timer]" +#error " [ || CPU_WORD_SIZE_64 64-bit timer]" +#endif + +#endif + + + +#ifndef CPU_CFG_INT_DIS_MEAS_EN +#if 0 /* Optionally configured in 'cpu_cfg.h'; DO NOT MODIFY. */ +#error "CPU_CFG_INT_DIS_MEAS_EN not #define'd in 'cpu_cfg.h'" +#endif + +#else + +#ifndef CPU_CFG_INT_DIS_MEAS_OVRHD_NBR +#error "CPU_CFG_INT_DIS_MEAS_OVRHD_NBR not #define'd in 'cpu_cfg.h' " +#error " [MUST be >= CPU_TIME_MEAS_NBR_MIN]" +#error " [ || <= CPU_TIME_MEAS_NBR_MAX]" + +#elif (DEF_CHK_VAL(CPU_CFG_INT_DIS_MEAS_OVRHD_NBR, \ + CPU_TIME_MEAS_NBR_MIN, \ + CPU_TIME_MEAS_NBR_MAX) != DEF_OK) +#error "CPU_CFG_INT_DIS_MEAS_OVRHD_NBR illegally #define'd in 'cpu_cfg.h' " +#error " [MUST be >= CPU_TIME_MEAS_NBR_MIN]" +#error " [ || <= CPU_TIME_MEAS_NBR_MAX]" + +#endif + +#endif + + + + +#ifndef CPU_CFG_LEAD_ZEROS_ASM_PRESENT +#if 0 /* Optionally configured in 'cpu_cfg.h'; DO NOT MODIFY. */ +#error "CPU_CFG_LEAD_ZEROS_ASM_PRESENT not #define'd in 'cpu.h'/'cpu_cfg.h'" +#endif +#endif + + +#ifndef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT +#if 0 /* Optionally configured in 'cpu_cfg.h'; DO NOT MODIFY. */ +#error "CPU_CFG_TRAIL_ZEROS_ASM_PRESENT not #define'd in 'cpu.h'/'cpu_cfg.h'" +#endif +#endif + + +/* +********************************************************************************************************* +* CPU PORT CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h'" +#endif + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h'" +#endif + +#ifndef CPU_CFG_DATA_SIZE_MAX +#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h'" +#endif + + +/* +********************************************************************************************************* +* LIBRARY CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + /* See 'cpu_core.h Note #1a'. */ +#if (LIB_VERSION < 13802u) +#error "LIB_VERSION [SHOULD be >= V1.38.02]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu_core.h MODULE'. +********************************************************************************************************* +*/ + +#ifdef __cplusplus +} +#endif +#endif /* End of CPU core module include. */ + diff --git a/cpu_def.h b/cpu_def.h new file mode 100644 index 0000000..58891d5 --- /dev/null +++ b/cpu_def.h @@ -0,0 +1,212 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com +* +* SPDX-License-Identifier: APACHE-2.0 +* +* This software is subject to an open source license and is distributed by +* Silicon Laboratories Inc. pursuant to the terms of the Apache License, +* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION DEFINES +* +* Filename : cpu_def.h +* Version : v1.32.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU definition header file is protected from multiple pre-processor inclusion +* through use of the CPU definition module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_DEF_MODULE_PRESENT +#define CPU_DEF_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CORE CPU MODULE VERSION NUMBER +* +* Note(s) : (1) (a) The core CPU module software version is denoted as follows : +* +* Vx.yy.zz +* +* where +* V denotes 'Version' label +* x denotes major software version revision number +* yy denotes minor software version revision number +* zz denotes sub-minor software version revision number +* +* (b) The software version label #define is formatted as follows : +* +* ver = x.yyzz * 100 * 100 +* +* where +* ver denotes software version number scaled as an integer value +* x.yyzz denotes software version number, where the unscaled integer +* portion denotes the major version number & the unscaled +* fractional portion denotes the (concatenated) minor +* version numbers +********************************************************************************************************* +*/ + +#define CPU_CORE_VERSION 13200u /* See Note #1. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* ---------------------- CPU WORD SIZE ----------------------- */ +#define CPU_WORD_SIZE_08 1u /* 8-bit word size (in octets). */ +#define CPU_WORD_SIZE_16 2u /* 16-bit word size (in octets). */ +#define CPU_WORD_SIZE_32 4u /* 32-bit word size (in octets). */ +#define CPU_WORD_SIZE_64 8u /* 64-bit word size (in octets). */ + + + /* ------------------ CPU WORD-ENDIAN ORDER ------------------- */ +#define CPU_ENDIAN_TYPE_NONE 0u +#define CPU_ENDIAN_TYPE_BIG 1u /* Big- endian word order (see Note #1a). */ +#define CPU_ENDIAN_TYPE_LITTLE 2u /* Little-endian word order (see Note #1b). */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +********************************************************************************************************* +*/ + + /* ------------------ CPU STACK GROWTH ORDER ------------------ */ +#define CPU_STK_GROWTH_NONE 0u +#define CPU_STK_GROWTH_LO_TO_HI 1u /* CPU stk incs towards higher mem addrs (see Note #1a). */ +#define CPU_STK_GROWTH_HI_TO_LO 2u /* CPU stk decs towards lower mem addrs (see Note #1b). */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, +* if used, MUST be declared following ALL other local variables (see any 'cpu.h +* CRITICAL SECTION CONFIGURATION Note #3a1'). +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* --------------- CPU CRITICAL SECTION METHODS --------------- */ +#define CPU_CRITICAL_METHOD_NONE 0u /* */ +#define CPU_CRITICAL_METHOD_INT_DIS_EN 1u /* DIS/EN ints (see Note #1a). */ +#define CPU_CRITICAL_METHOD_STATUS_STK 2u /* Push/Pop int status onto stk (see Note #1b). */ +#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3u /* Save/Restore int status to local var (see Note #1c). */ + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu_def.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU def module include. */ + diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..4242d40 --- /dev/null +++ b/license.txt @@ -0,0 +1,29 @@ +ATTENTION ALL USERS OF THIS REPOSITORY: + +The original work found in this repository is provided by Silicon Labs under the +Apache License, Version 2.0. + +Any third party may contribute derivative works to the original work in which +modifications are clearly identified as being licensed under: + + (1) the Apache License, Version 2.0 or a compatible open source license; or + (2) under a proprietary license with a copy of such license deposited. + +All posted derivative works must clearly identify which license choice has been +elected. + +No such posted derivative works will be considered to be a “Contribution” under +the Apache License, Version 2.0. + +SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT +AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP, +NON-INFRINGEMENT, AND NON-MISAPPROPRIATION. + +In the event a derivative work is desired to be submitted to Silicon Labs as a +“Contribution” under the Apache License, Version 2.0, a “Contributor” must give +written email notice to micrium@weston-embedded.com. Unless an email response in +the affirmative to accept the derivative work as a “Contribution”, such email +submission should be considered to have not been incorporated into the original +work. + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..8301a49 --- /dev/null +++ b/readme.md @@ -0,0 +1,5 @@ +# uC/CPU + +Designed with Micriμm’s renowned quality, scalability and reliability, the purpose of μC/ CPU is to provide a clean, organized ANSI C implementation of each processor’s/ compiler’s hardware-dependent. + +## For the complete documentation, visit https://doc.micrium.com/display/ucos/ \ No newline at end of file