diff --git a/testjig/production/arm_debug.cpp b/testjig/production/arm_debug.cpp index 293b4fb09a29a5d5aacf3cd754408321efb81854..e10e79a7c0b25c103088e21c3d4e3f53368fe553 100644 --- a/testjig/production/arm_debug.cpp +++ b/testjig/production/arm_debug.cpp @@ -25,33 +25,6 @@ #include <stdarg.h> #include "arm_debug.h" -// Debug port registers -enum DebugPortReg { - ABORT = 0x0, - IDCODE = 0x0, - CTRLSTAT = 0x4, - SELECT = 0x8, - RDBUFF = 0xC -}; - -// CTRL/STAT bits -enum CtrlStatBit { - CSYSPWRUPACK = 1 << 31, - CSYSPWRUPREQ = 1 << 30, - CDBGPWRUPACK = 1 << 29, - CDBGPWRUPREQ = 1 << 28, - CDBGRSTACK = 1 << 27, - CDBGRSTREQ = 1 << 26 -}; - -// Memory Access Port registers -enum MemPortReg { - MEM_CSW = 0x00, - MEM_TAR = 0x04, - MEM_DRW = 0x0C, - MEM_IDR = 0xFC, -}; - bool ARMDebug::begin(unsigned clockPin, unsigned dataPin, LogLevel logLevel) { @@ -94,16 +67,8 @@ bool ARMDebug::begin(unsigned clockPin, unsigned dataPin, LogLevel logLevel) return false; // Wait for power-up acknowledgment - uint32_t expected = CDBGPWRUPACK | CSYSPWRUPACK; - unsigned retries = 4; uint32_t ctrlstat; - while (retries--) { - if (!dpRead(CTRLSTAT, false, ctrlstat)) - return false; - if ((ctrlstat & expected) == expected) - break; - } - if (!retries) { + if (!dpReadPoll(CTRLSTAT, ctrlstat, CDBGPWRUPACK | CSYSPWRUPACK, -1)) { log(LOG_ERROR, "ARMDebug: Debug port failed to power on (CTRLSTAT: %08x)", ctrlstat); return false; } @@ -113,15 +78,7 @@ bool ARMDebug::begin(unsigned clockPin, unsigned dataPin, LogLevel logLevel) return false; // Wait for reset acknowledgment - expected = CDBGPWRUPACK | CSYSPWRUPACK | CDBGRSTACK; - retries = 4; - while (retries--) { - if (!dpRead(CTRLSTAT, false, ctrlstat)) - return false; - if ((ctrlstat & expected) == expected) - break; - } - if (!retries) { + if (!dpReadPoll(CTRLSTAT, ctrlstat, CDBGPWRUPACK | CSYSPWRUPACK | CDBGRSTACK, -1)) { log(LOG_ERROR, "ARMDebug: Debug port failed to reset (CTRLSTAT: %08x)", ctrlstat); return false; } @@ -132,18 +89,18 @@ bool ARMDebug::begin(unsigned clockPin, unsigned dataPin, LogLevel logLevel) // Make sure the default debug access port is an AHB (memory bus) port, like we expect uint32_t idr; - if (!apRead(0, MEM_IDR, idr)) + if (!apRead(MEM_IDR, idr)) return false; if ((idr & 0xF) != 1) { log(LOG_ERROR, "ARMDebug: Default access port is not an AHB-AP as expected! (IDR: %08x)", idr); return false; } - // Set up default CSW values for the AHB-AP. Use 32-bit accesses with auto-increment. + // Set up default CSW values for the AHB-AP. uint32_t csw = (1 << 6) | // Device enable - (1 << 4) | // Increment by a single word + (0 << 4) | // Auto-increment off (2 << 0) ; // 32-bit data size - if (!apWrite(0, MEM_CSW, csw)) + if (!apWrite(MEM_CSW, csw)) return false; return true; @@ -161,13 +118,13 @@ bool ARMDebug::memLoad(uint32_t addr, uint32_t &data) bool ARMDebug::memStore(uint32_t addr, uint32_t *data, unsigned count) { - if (!apWrite(0, MEM_TAR, addr)) + if (!apWrite(MEM_TAR, addr)) return false; while (count) { log(LOG_TRACE_MEM, "MEM Store [%08x] %08x", addr, *data); - if (!apWrite(0, MEM_DRW, *data)) + if (!apWrite(MEM_DRW, *data)) return false; data++; @@ -180,11 +137,11 @@ bool ARMDebug::memStore(uint32_t addr, uint32_t *data, unsigned count) bool ARMDebug::memLoad(uint32_t addr, uint32_t *data, unsigned count) { - if (!apWrite(0, MEM_TAR, addr)) + if (!apWrite(MEM_TAR, addr)) return false; while (count) { - if (!apRead(0, MEM_DRW, *data)) + if (!apRead(MEM_DRW, *data)) return false; log(LOG_TRACE_MEM, "MEM Load [%08x] %08x", addr, *data); @@ -197,25 +154,70 @@ bool ARMDebug::memLoad(uint32_t addr, uint32_t *data, unsigned count) return true; } -bool ARMDebug::apWrite(unsigned accessPort, unsigned addr, uint32_t data) +bool ARMDebug::apWrite(unsigned addr, uint32_t data) { - return dpSelect(accessPort, addr) && dpWrite(addr, true, data); + return dpSelect(addr) && dpWrite(addr, true, data); } -bool ARMDebug::apRead(unsigned accessPort, unsigned addr, uint32_t &data) +bool ARMDebug::apRead(unsigned addr, uint32_t &data) { // XXX: Extra dummy read here seems to be necessary. Why? What bug is this covering up? - return dpSelect(accessPort, addr) && dpRead(addr, true, data) && dpRead(addr, true, data); + return dpSelect(addr) && dpRead(addr, true, data) && dpRead(addr, true, data); +} + +bool ARMDebug::dpReadPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries) +{ + expected &= mask; + do { + if (!dpRead(addr, false, data)) + return false; + if ((data & mask) == expected) + return true; + } while (retries--); + + log(LOG_ERROR, "ARMDebug: Timed out while polling DP ([%08x] & %08x == %08x). Current value: %08x", + addr, mask, expected, data); + return false; +} + +bool ARMDebug::apReadPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries) +{ + expected &= mask; + do { + if (!apRead(addr, data)) + return false; + if ((data & mask) == expected) + return true; + } while (retries--); + + log(LOG_ERROR, "ARMDebug: Timed out while polling AP ([%08x] & %08x == %08x). Current value: %08x", + addr, mask, expected, data); + return false; +} + +bool ARMDebug::memPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries) +{ + expected &= mask; + do { + if (!memLoad(addr, data)) + return false; + if ((data & mask) == expected) + return true; + } while (retries--); + + log(LOG_ERROR, "ARMDebug: Timed out while polling MEM ([%08x] & %08x == %08x). Current value: %08x", + addr, mask, expected, data); + return false; } -bool ARMDebug::dpSelect(unsigned accessPort, unsigned addr) +bool ARMDebug::dpSelect(unsigned addr) { /* - * Select a new access port and/or a bank (high nybble of AP address). - * This is cached, so redundant dpSelect()s have no effect. + * Select a new access port and/or a bank. Uses only the high byte and + * second nybble of 'addr'. This is cached, so redundant dpSelect()s have no effect. */ - uint32_t select = (accessPort << 24) | (addr & 0xF0); + uint32_t select = addr & 0xFF0000F0; if (select != cache.select) { if (!dpWrite(SELECT, false, select)) return false; @@ -449,22 +451,3 @@ void ARMDebug::log(int level, const char *fmt, ...) Serial.println(buffer); } } - -bool ARMDebug::halt() -{ - // Write to DHCSR (Debug Halting Control and Status Register) - // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGCJAHJ.html - return memStore(0xE000EDF0, 0xA05F0003); -} - -bool ARMDebug::unhalt() -{ - return memStore(0xE000EDF0, 0xA05F0000); -} - -bool ARMDebug::sysReset() -{ - // Write to AIRCR (Application Interrupt and Reset Control Register) - // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihehdge.html - return memStore(0xE000ED0C, 0x05FA0004); -} diff --git a/testjig/production/arm_debug.h b/testjig/production/arm_debug.h index 5a66fd29f588103653d8ba6d02995bc6e1078f1f..95da21414277c8059cec381574be50418610d771 100644 --- a/testjig/production/arm_debug.h +++ b/testjig/production/arm_debug.h @@ -54,10 +54,8 @@ public: bool memLoad(uint32_t addr, uint32_t &data); bool memLoad(uint32_t addr, uint32_t *data, unsigned count); - // CPU core operations - bool halt(); - bool unhalt(); - bool sysReset(); + // Poll for an expected value + bool memPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries = 32); private: uint8_t clockPin, dataPin; @@ -89,9 +87,40 @@ protected: // Debug port layer bool dpWrite(unsigned addr, bool APnDP, uint32_t data); bool dpRead(unsigned addr, bool APnDP, uint32_t &data); - bool dpSelect(unsigned accessPort, unsigned addr); + bool dpSelect(unsigned addr); // Access port layer - bool apWrite(unsigned accessPort, unsigned addr, uint32_t data); - bool apRead(unsigned accessPort, unsigned addr, uint32_t &data); + bool apWrite(unsigned addr, uint32_t data); + bool apRead(unsigned addr, uint32_t &data); + + // Poll for an expected value + bool dpReadPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries = 32); + bool apReadPoll(unsigned addr, uint32_t &data, uint32_t mask, uint32_t expected, unsigned retries = 32); + + // Debug port registers + enum DebugPortReg { + ABORT = 0x0, + IDCODE = 0x0, + CTRLSTAT = 0x4, + SELECT = 0x8, + RDBUFF = 0xC + }; + + // CTRL/STAT bits + enum CtrlStatBit { + CSYSPWRUPACK = 1 << 31, + CSYSPWRUPREQ = 1 << 30, + CDBGPWRUPACK = 1 << 29, + CDBGPWRUPREQ = 1 << 28, + CDBGRSTACK = 1 << 27, + CDBGRSTREQ = 1 << 26 + }; + + // Memory Access Port registers + enum MemPortReg { + MEM_CSW = 0x00, + MEM_TAR = 0x04, + MEM_DRW = 0x0C, + MEM_IDR = 0xFC, + }; }; diff --git a/testjig/production/arm_kinetis_debug.cpp b/testjig/production/arm_kinetis_debug.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba77e27f6621e34bc79ae0ffaa651d2112a492a9 --- /dev/null +++ b/testjig/production/arm_kinetis_debug.cpp @@ -0,0 +1,153 @@ +/* + * Simple ARM debug interface for Arduino, using the SWD (Serial Wire Debug) port. + * Extensions for Freescale Kinetis chips. + * + * Copyright (c) 2013 Micah Elizabeth Scott + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <Arduino.h> +#include "arm_kinetis_debug.h" +#include "arm_kinetis_reg.h" + + +bool ARMKinetisDebug::startup() +{ + uint32_t idr; + uint32_t status; + + // Make sure we're on a compatible chip. The MDM-AP peripheral is Freescale-specific. + if (!apRead(MDM_IDR, idr)) + return false; + if (idr != 0x001C0000) { + log(LOG_ERROR, "ARMKinetisDebug: Didn't find a supported MDM-AP peripheral"); + return false; + } + + // Reset the system, and hold the core in reset when it comes back + if (!apWrite(MDM_CONTROL, MDM_CONTROL_SYS_RESET_REQ | MDM_CONTROL_CORE_HOLD_RESET)) + return false; + if (!apReadPoll(MDM_STATUS, status, MDM_STATUS_SYS_NRESET, 0)) + return false; + if (!apWrite(MDM_CONTROL, MDM_CONTROL_CORE_HOLD_RESET)) + return false; + + // Wait until the flash controller is ready & system is out of reset + if (!apReadPoll(MDM_STATUS, status, MDM_STATUS_SYS_NRESET | MDM_STATUS_FLASH_READY, -1)) + return false; + + /* + * The rest of system startup looks a lot like what the bootloader does. This is based + * on the startup sequence used by Teensyduino. + */ + + // Enable peripheral clocks + if (!memStore(REG_SIM_SCGC5, 0x00043F82)) + return false; + if (!memStore(REG_SIM_SCGC6, REG_SIM_SCGC6_FTM0 | REG_SIM_SCGC6_FTM1 | REG_SIM_SCGC6_FTFL)) + return false; + + // Oscillator starts up in FEI mode. + // Turn on crystal capacitors + if (!memStore(REG_OSC0_CR, REG_OSC_SC8P | REG_OSC_SC2P)) + return false; + // Enable osc, 8-32 MHz range, low power + if (!memStore(REG_MCG_C2, REG_MCG_C2_RANGE0(2) | REG_MCG_C2_EREFS)) + return false; + // Switch to crystal as clock source, FLL input = 16 MHz / 512 + if (!memStore(REG_MCG_C1, REG_MCG_C1_CLKS(2) | REG_MCG_C1_FRDIV(4))) + return false; + + // Wait for crystal oscillator to begin + uint32_t mcg; + if (!memPoll(REG_MCG_S, mcg, REG_MCG_S_OSCINIT0, -1)) + return false; + + // wait for FLL to use oscillator + if (!memPoll(REG_MCG_S, mcg, REG_MCG_S_IREFST, 0)) + return false; + + // wait for MCGOUT to use oscillator + if (!memPoll(REG_MCG_S, mcg, REG_MCG_S_CLKST_MASK, REG_MCG_S_CLKST(2))) + return false; + + // Now we're in FBE mode + // config PLL input for 16 MHz Crystal / 4 = 4 MHz + if (!memStore(REG_MCG_C5, REG_MCG_C5_PRDIV0(3))) + return false; + + // config PLL for 96 MHz output + if (!memStore(REG_MCG_C6, REG_MCG_C6_PLLS | REG_MCG_C6_VDIV0(0))) + return false; + + // wait for PLL to start using xtal as its input + if (!memPoll(REG_MCG_S, mcg, REG_MCG_S_PLLST, -1)) + return false; + if (!memPoll(REG_MCG_S, mcg, REG_MCG_S_LOCK0, -1)) + return false; + + // Now we're in PBE mode + // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash + if (!memStore(REG_SIM_CLKDIV1, REG_SIM_CLKDIV1_OUTDIV1(1) | REG_SIM_CLKDIV1_OUTDIV2(1) | REG_SIM_CLKDIV1_OUTDIV4(3))) + return false; + // switch to PLL as clock source, FLL input = 16 MHz / 512 + if (!memStore(REG_MCG_C1, REG_MCG_C1_CLKS(0) | REG_MCG_C1_FRDIV(4))) + return false; + + // wait for PLL clock to be used + if (!memPoll(REG_MCG_S, mcg, MCG_S_CLKST_MASK, MCG_S_CLKST(3))) + return false; + + // Now we're in PEE mode. Ready to go! + return true; +} + +bool ARMKinetisDebug::flashMassErase() +{ + // Erase all flash, even if some of it is protected. + + uint32_t status; + if (!apRead(MDM_STATUS, status)) + return false; + if (!(status & MDM_STATUS_FLASH_READY)) { + log(LOG_ERROR, "FLASH: Flash controller not ready before mass erase"); + return false; + } + if ((status & MDM_STATUS_FLASH_ERASE_ACK)) { + log(LOG_ERROR, "FLASH: Mass erase already in progress"); + return false; + } + + log(LOG_NORMAL, "FLASH: Beginning mass erase operation"); + if (!apWrite(MDM_CONTROL, MDM_CONTROL_CORE_HOLD_RESET | MDM_CONTROL_MASS_ERASE)) + return false; + + // Wait for the mass erase to complete + if (!apReadPoll(MDM_STATUS, status, MDM_STATUS_FLASH_ERASE_ACK, 0, 10000)) { + log(LOG_ERROR, "FLASH: Timed out waiting for mass erase to complete"); + return false; + } + + if (!(status & MDM_STATUS_FLASH_READY)) { + log(LOG_ERROR, "FLASH: Flash controller not ready after mass erase"); + return false; + } + + return true; +} diff --git a/testjig/production/arm_kinetis_debug.h b/testjig/production/arm_kinetis_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..bb33477fd2b87fd15deb19e9611fa25b185d3c5b --- /dev/null +++ b/testjig/production/arm_kinetis_debug.h @@ -0,0 +1,60 @@ +/* + * Simple ARM debug interface for Arduino, using the SWD (Serial Wire Debug) port. + * Extensions for Freescale Kinetis chips. + * + * Copyright (c) 2013 Micah Elizabeth Scott + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#include "arm_debug.h" + +class ARMKinetisDebug : public ARMDebug +{ +public: + // Hold the processor core in reset, and initialize peripherals + bool startup(); + + // Flash mass-erase operation. Works even on protected devices. + bool flashMassErase(); + +protected: + // MDM-AP registers + enum MDMReg { + MDM_STATUS = 0x01000000, + MDM_CONTROL = 0x01000004, + MDM_IDR = 0x010000FC, + }; + + // MDM-AP bits + enum MDMBits { + MDM_STATUS_FLASH_ERASE_ACK = 1 << 0, + MDM_STATUS_FLASH_READY = 1 << 1, + MDM_STATUS_SYS_SECURITY = 1 << 2, + MDM_STATUS_SYS_NRESET = 1 << 3, + MDM_STATUS_MASS_ERASE_ENABLE = 1 << 4, + MDM_STATUS_CORE_HALTED = 1 << 16, + + MDM_CONTROL_MASS_ERASE = 1 << 0, + MDM_CONTROL_DEBUG_DISABLE = 1 << 1, + MDM_CONTROL_DEBUG_REQ = 1 << 2, + MDM_CONTROL_SYS_RESET_REQ = 1 << 3, + MDM_CONTROL_CORE_HOLD_RESET = 1 << 4, + }; +}; diff --git a/testjig/production/arm_kinetis_reg.h b/testjig/production/arm_kinetis_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..d715f9d51b1b6da6f9e9c45090ba44ad36145c2d --- /dev/null +++ b/testjig/production/arm_kinetis_reg.h @@ -0,0 +1,517 @@ +/* + * Register definitions for remote debugging on the Freescale Kinetis chips. + * Originally from: + * + * Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +// chapter 11: Port control and interrupts (PORT) +#define REG_PORTA_PCR0 0x40049000 // Pin Control Register n +#define REG_PORT_PCR_ISF 0x01000000 // Interrupt Status Flag +#define REG_PORT_PCR_IRQC(n) (((n) & 15) << 16) // Interrupt Configuration +#define REG_PORT_PCR_IRQC_MASK 0x000F0000 +#define REG_PORT_PCR_LK 0x00008000 // Lock Register +#define REG_PORT_PCR_MUX(n) (((n) & 7) << 8) // Pin Mux Control +#define REG_PORT_PCR_MUX_MASK 0x00000700 +#define REG_PORT_PCR_DSE 0x00000040 // Drive Strength Enable +#define REG_PORT_PCR_ODE 0x00000020 // Open Drain Enable +#define REG_PORT_PCR_PFE 0x00000010 // Passive Filter Enable +#define REG_PORT_PCR_SRE 0x00000004 // Slew Rate Enable +#define REG_PORT_PCR_PE 0x00000002 // Pull Enable +#define REG_PORT_PCR_PS 0x00000001 // Pull Select +#define REG_PORTA_PCR1 0x40049004 // Pin Control Register n +#define REG_PORTA_PCR2 0x40049008 // Pin Control Register n +#define REG_PORTA_PCR3 0x4004900C // Pin Control Register n +#define REG_PORTA_PCR4 0x40049010 // Pin Control Register n +#define REG_PORTA_PCR5 0x40049014 // Pin Control Register n +#define REG_PORTA_PCR6 0x40049018 // Pin Control Register n +#define REG_PORTA_PCR7 0x4004901C // Pin Control Register n +#define REG_PORTA_PCR8 0x40049020 // Pin Control Register n +#define REG_PORTA_PCR9 0x40049024 // Pin Control Register n +#define REG_PORTA_PCR10 0x40049028 // Pin Control Register n +#define REG_PORTA_PCR11 0x4004902C // Pin Control Register n +#define REG_PORTA_PCR12 0x40049030 // Pin Control Register n +#define REG_PORTA_PCR13 0x40049034 // Pin Control Register n +#define REG_PORTA_PCR14 0x40049038 // Pin Control Register n +#define REG_PORTA_PCR15 0x4004903C // Pin Control Register n +#define REG_PORTA_PCR16 0x40049040 // Pin Control Register n +#define REG_PORTA_PCR17 0x40049044 // Pin Control Register n +#define REG_PORTA_PCR18 0x40049048 // Pin Control Register n +#define REG_PORTA_PCR19 0x4004904C // Pin Control Register n +#define REG_PORTA_PCR20 0x40049050 // Pin Control Register n +#define REG_PORTA_PCR21 0x40049054 // Pin Control Register n +#define REG_PORTA_PCR22 0x40049058 // Pin Control Register n +#define REG_PORTA_PCR23 0x4004905C // Pin Control Register n +#define REG_PORTA_PCR24 0x40049060 // Pin Control Register n +#define REG_PORTA_PCR25 0x40049064 // Pin Control Register n +#define REG_PORTA_PCR26 0x40049068 // Pin Control Register n +#define REG_PORTA_PCR27 0x4004906C // Pin Control Register n +#define REG_PORTA_PCR28 0x40049070 // Pin Control Register n +#define REG_PORTA_PCR29 0x40049074 // Pin Control Register n +#define REG_PORTA_PCR30 0x40049078 // Pin Control Register n +#define REG_PORTA_PCR31 0x4004907C // Pin Control Register n +#define REG_PORTA_GPCLR 0x40049080 // Global Pin Control Low Register +#define REG_PORTA_GPCHR 0x40049084 // Global Pin Control High Register +#define REG_PORTA_ISFR 0x400490A0 // Interrupt Status Flag Register +#define REG_PORTB_PCR0 0x4004A000 // Pin Control Register n +#define REG_PORTB_PCR1 0x4004A004 // Pin Control Register n +#define REG_PORTB_PCR2 0x4004A008 // Pin Control Register n +#define REG_PORTB_PCR3 0x4004A00C // Pin Control Register n +#define REG_PORTB_PCR4 0x4004A010 // Pin Control Register n +#define REG_PORTB_PCR5 0x4004A014 // Pin Control Register n +#define REG_PORTB_PCR6 0x4004A018 // Pin Control Register n +#define REG_PORTB_PCR7 0x4004A01C // Pin Control Register n +#define REG_PORTB_PCR8 0x4004A020 // Pin Control Register n +#define REG_PORTB_PCR9 0x4004A024 // Pin Control Register n +#define REG_PORTB_PCR10 0x4004A028 // Pin Control Register n +#define REG_PORTB_PCR11 0x4004A02C // Pin Control Register n +#define REG_PORTB_PCR12 0x4004A030 // Pin Control Register n +#define REG_PORTB_PCR13 0x4004A034 // Pin Control Register n +#define REG_PORTB_PCR14 0x4004A038 // Pin Control Register n +#define REG_PORTB_PCR15 0x4004A03C // Pin Control Register n +#define REG_PORTB_PCR16 0x4004A040 // Pin Control Register n +#define REG_PORTB_PCR17 0x4004A044 // Pin Control Register n +#define REG_PORTB_PCR18 0x4004A048 // Pin Control Register n +#define REG_PORTB_PCR19 0x4004A04C // Pin Control Register n +#define REG_PORTB_PCR20 0x4004A050 // Pin Control Register n +#define REG_PORTB_PCR21 0x4004A054 // Pin Control Register n +#define REG_PORTB_PCR22 0x4004A058 // Pin Control Register n +#define REG_PORTB_PCR23 0x4004A05C // Pin Control Register n +#define REG_PORTB_PCR24 0x4004A060 // Pin Control Register n +#define REG_PORTB_PCR25 0x4004A064 // Pin Control Register n +#define REG_PORTB_PCR26 0x4004A068 // Pin Control Register n +#define REG_PORTB_PCR27 0x4004A06C // Pin Control Register n +#define REG_PORTB_PCR28 0x4004A070 // Pin Control Register n +#define REG_PORTB_PCR29 0x4004A074 // Pin Control Register n +#define REG_PORTB_PCR30 0x4004A078 // Pin Control Register n +#define REG_PORTB_PCR31 0x4004A07C // Pin Control Register n +#define REG_PORTB_GPCLR 0x4004A080 // Global Pin Control Low Register +#define REG_PORTB_GPCHR 0x4004A084 // Global Pin Control High Register +#define REG_PORTB_ISFR 0x4004A0A0 // Interrupt Status Flag Register +#define REG_PORTC_PCR0 0x4004B000 // Pin Control Register n +#define REG_PORTC_PCR1 0x4004B004 // Pin Control Register n +#define REG_PORTC_PCR2 0x4004B008 // Pin Control Register n +#define REG_PORTC_PCR3 0x4004B00C // Pin Control Register n +#define REG_PORTC_PCR4 0x4004B010 // Pin Control Register n +#define REG_PORTC_PCR5 0x4004B014 // Pin Control Register n +#define REG_PORTC_PCR6 0x4004B018 // Pin Control Register n +#define REG_PORTC_PCR7 0x4004B01C // Pin Control Register n +#define REG_PORTC_PCR8 0x4004B020 // Pin Control Register n +#define REG_PORTC_PCR9 0x4004B024 // Pin Control Register n +#define REG_PORTC_PCR10 0x4004B028 // Pin Control Register n +#define REG_PORTC_PCR11 0x4004B02C // Pin Control Register n +#define REG_PORTC_PCR12 0x4004B030 // Pin Control Register n +#define REG_PORTC_PCR13 0x4004B034 // Pin Control Register n +#define REG_PORTC_PCR14 0x4004B038 // Pin Control Register n +#define REG_PORTC_PCR15 0x4004B03C // Pin Control Register n +#define REG_PORTC_PCR16 0x4004B040 // Pin Control Register n +#define REG_PORTC_PCR17 0x4004B044 // Pin Control Register n +#define REG_PORTC_PCR18 0x4004B048 // Pin Control Register n +#define REG_PORTC_PCR19 0x4004B04C // Pin Control Register n +#define REG_PORTC_PCR20 0x4004B050 // Pin Control Register n +#define REG_PORTC_PCR21 0x4004B054 // Pin Control Register n +#define REG_PORTC_PCR22 0x4004B058 // Pin Control Register n +#define REG_PORTC_PCR23 0x4004B05C // Pin Control Register n +#define REG_PORTC_PCR24 0x4004B060 // Pin Control Register n +#define REG_PORTC_PCR25 0x4004B064 // Pin Control Register n +#define REG_PORTC_PCR26 0x4004B068 // Pin Control Register n +#define REG_PORTC_PCR27 0x4004B06C // Pin Control Register n +#define REG_PORTC_PCR28 0x4004B070 // Pin Control Register n +#define REG_PORTC_PCR29 0x4004B074 // Pin Control Register n +#define REG_PORTC_PCR30 0x4004B078 // Pin Control Register n +#define REG_PORTC_PCR31 0x4004B07C // Pin Control Register n +#define REG_PORTC_GPCLR 0x4004B080 // Global Pin Control Low Register +#define REG_PORTC_GPCHR 0x4004B084 // Global Pin Control High Register +#define REG_PORTC_ISFR 0x4004B0A0 // Interrupt Status Flag Register +#define REG_PORTD_PCR0 0x4004C000 // Pin Control Register n +#define REG_PORTD_PCR1 0x4004C004 // Pin Control Register n +#define REG_PORTD_PCR2 0x4004C008 // Pin Control Register n +#define REG_PORTD_PCR3 0x4004C00C // Pin Control Register n +#define REG_PORTD_PCR4 0x4004C010 // Pin Control Register n +#define REG_PORTD_PCR5 0x4004C014 // Pin Control Register n +#define REG_PORTD_PCR6 0x4004C018 // Pin Control Register n +#define REG_PORTD_PCR7 0x4004C01C // Pin Control Register n +#define REG_PORTD_PCR8 0x4004C020 // Pin Control Register n +#define REG_PORTD_PCR9 0x4004C024 // Pin Control Register n +#define REG_PORTD_PCR10 0x4004C028 // Pin Control Register n +#define REG_PORTD_PCR11 0x4004C02C // Pin Control Register n +#define REG_PORTD_PCR12 0x4004C030 // Pin Control Register n +#define REG_PORTD_PCR13 0x4004C034 // Pin Control Register n +#define REG_PORTD_PCR14 0x4004C038 // Pin Control Register n +#define REG_PORTD_PCR15 0x4004C03C // Pin Control Register n +#define REG_PORTD_PCR16 0x4004C040 // Pin Control Register n +#define REG_PORTD_PCR17 0x4004C044 // Pin Control Register n +#define REG_PORTD_PCR18 0x4004C048 // Pin Control Register n +#define REG_PORTD_PCR19 0x4004C04C // Pin Control Register n +#define REG_PORTD_PCR20 0x4004C050 // Pin Control Register n +#define REG_PORTD_PCR21 0x4004C054 // Pin Control Register n +#define REG_PORTD_PCR22 0x4004C058 // Pin Control Register n +#define REG_PORTD_PCR23 0x4004C05C // Pin Control Register n +#define REG_PORTD_PCR24 0x4004C060 // Pin Control Register n +#define REG_PORTD_PCR25 0x4004C064 // Pin Control Register n +#define REG_PORTD_PCR26 0x4004C068 // Pin Control Register n +#define REG_PORTD_PCR27 0x4004C06C // Pin Control Register n +#define REG_PORTD_PCR28 0x4004C070 // Pin Control Register n +#define REG_PORTD_PCR29 0x4004C074 // Pin Control Register n +#define REG_PORTD_PCR30 0x4004C078 // Pin Control Register n +#define REG_PORTD_PCR31 0x4004C07C // Pin Control Register n +#define REG_PORTD_GPCLR 0x4004C080 // Global Pin Control Low Register +#define REG_PORTD_GPCHR 0x4004C084 // Global Pin Control High Register +#define REG_PORTD_ISFR 0x4004C0A0 // Interrupt Status Flag Register +#define REG_PORTE_PCR0 0x4004D000 // Pin Control Register n +#define REG_PORTE_PCR1 0x4004D004 // Pin Control Register n +#define REG_PORTE_PCR2 0x4004D008 // Pin Control Register n +#define REG_PORTE_PCR3 0x4004D00C // Pin Control Register n +#define REG_PORTE_PCR4 0x4004D010 // Pin Control Register n +#define REG_PORTE_PCR5 0x4004D014 // Pin Control Register n +#define REG_PORTE_PCR6 0x4004D018 // Pin Control Register n +#define REG_PORTE_PCR7 0x4004D01C // Pin Control Register n +#define REG_PORTE_PCR8 0x4004D020 // Pin Control Register n +#define REG_PORTE_PCR9 0x4004D024 // Pin Control Register n +#define REG_PORTE_PCR10 0x4004D028 // Pin Control Register n +#define REG_PORTE_PCR11 0x4004D02C // Pin Control Register n +#define REG_PORTE_PCR12 0x4004D030 // Pin Control Register n +#define REG_PORTE_PCR13 0x4004D034 // Pin Control Register n +#define REG_PORTE_PCR14 0x4004D038 // Pin Control Register n +#define REG_PORTE_PCR15 0x4004D03C // Pin Control Register n +#define REG_PORTE_PCR16 0x4004D040 // Pin Control Register n +#define REG_PORTE_PCR17 0x4004D044 // Pin Control Register n +#define REG_PORTE_PCR18 0x4004D048 // Pin Control Register n +#define REG_PORTE_PCR19 0x4004D04C // Pin Control Register n +#define REG_PORTE_PCR20 0x4004D050 // Pin Control Register n +#define REG_PORTE_PCR21 0x4004D054 // Pin Control Register n +#define REG_PORTE_PCR22 0x4004D058 // Pin Control Register n +#define REG_PORTE_PCR23 0x4004D05C // Pin Control Register n +#define REG_PORTE_PCR24 0x4004D060 // Pin Control Register n +#define REG_PORTE_PCR25 0x4004D064 // Pin Control Register n +#define REG_PORTE_PCR26 0x4004D068 // Pin Control Register n +#define REG_PORTE_PCR27 0x4004D06C // Pin Control Register n +#define REG_PORTE_PCR28 0x4004D070 // Pin Control Register n +#define REG_PORTE_PCR29 0x4004D074 // Pin Control Register n +#define REG_PORTE_PCR30 0x4004D078 // Pin Control Register n +#define REG_PORTE_PCR31 0x4004D07C // Pin Control Register n +#define REG_PORTE_GPCLR 0x4004D080 // Global Pin Control Low Register +#define REG_PORTE_GPCHR 0x4004D084 // Global Pin Control High Register +#define REG_PORTE_ISFR 0x4004D0A0 // Interrupt Status Flag Register + +// Chapter 12: System Integration Module (SIM) +#define REG_SIM_SOPT1 0x40047000 // System Options Register 1 +#define REG_SIM_SOPT1CFG 0x40047004 // SOPT1 Configuration Register +#define REG_SIM_SOPT2 0x40048004 // System Options Register 2 +#define REG_SIM_SOPT2_USBSRC 0x00040000 // 0=USB_CLKIN, 1=FFL/PLL +#define REG_SIM_SOPT2_PLLFLLSEL 0x00010000 // 0=FLL, 1=PLL +#define REG_SIM_SOPT2_TRACECLKSEL 0x00001000 // 0=MCGOUTCLK, 1=CPU +#define REG_SIM_SOPT2_PTD7PAD 0x00000800 // 0=normal, 1=double drive PTD7 +#define REG_SIM_SOPT2_CLKOUTSEL(n) (((n) & 7) << 5) // Selects the clock to output on the CLKOUT pin. +#define REG_SIM_SOPT2_RTCCLKOUTSEL 0x00000010 // RTC clock out select +#define REG_SIM_SOPT4 0x4004800C // System Options Register 4 +#define REG_SIM_SOPT5 0x40048010 // System Options Register 5 +#define REG_SIM_SOPT7 0x40048018 // System Options Register 7 +#define REG_SIM_SDID 0x40048024 // System Device Identification Register +#define REG_SIM_SCGC4 0x40048034 // System Clock Gating Control Register 4 +#define REG_SIM_SCGC4_VREF 0x00100000 // VREF Clock Gate Control +#define REG_SIM_SCGC4_CMP 0x00080000 // Comparator Clock Gate Control +#define REG_SIM_SCGC4_USBOTG 0x00040000 // USB Clock Gate Control +#define REG_SIM_SCGC4_UART2 0x00001000 // UART2 Clock Gate Control +#define REG_SIM_SCGC4_UART1 0x00000800 // UART1 Clock Gate Control +#define REG_SIM_SCGC4_UART0 0x00000400 // UART0 Clock Gate Control +#define REG_SIM_SCGC4_I2C0 0x00000040 // I2C0 Clock Gate Control +#define REG_SIM_SCGC4_CMT 0x00000004 // CMT Clock Gate Control +#define REG_SIM_SCGC4_EWM 0x00000002 // EWM Clock Gate Control +#define REG_SIM_SCGC5 0x40048038 // System Clock Gating Control Register 5 +#define REG_SIM_SCGC5_PORTE 0x00002000 // Port E Clock Gate Control +#define REG_SIM_SCGC5_PORTD 0x00001000 // Port D Clock Gate Control +#define REG_SIM_SCGC5_PORTC 0x00000800 // Port C Clock Gate Control +#define REG_SIM_SCGC5_PORTB 0x00000400 // Port B Clock Gate Control +#define REG_SIM_SCGC5_PORTA 0x00000200 // Port A Clock Gate Control +#define REG_SIM_SCGC5_TSI 0x00000020 // Touch Sense Input TSI Clock Gate Control +#define REG_SIM_SCGC5_LPTIMER 0x00000001 // Low Power Timer Access Control +#define REG_SIM_SCGC6 0x4004803C // System Clock Gating Control Register 6 +#define REG_SIM_SCGC6_RTC 0x20000000 // RTC Access +#define REG_SIM_SCGC6_ADC0 0x08000000 // ADC0 Clock Gate Control +#define REG_SIM_SCGC6_FTM1 0x02000000 // FTM1 Clock Gate Control +#define REG_SIM_SCGC6_FTM0 0x01000000 // FTM0 Clock Gate Control +#define REG_SIM_SCGC6_PIT 0x00800000 // PIT Clock Gate Control +#define REG_SIM_SCGC6_PDB 0x00400000 // PDB Clock Gate Control +#define REG_SIM_SCGC6_USBDCD 0x00200000 // USB DCD Clock Gate Control +#define REG_SIM_SCGC6_CRC 0x00040000 // CRC Clock Gate Control +#define REG_SIM_SCGC6_I2S 0x00008000 // I2S Clock Gate Control +#define REG_SIM_SCGC6_SPI0 0x00001000 // SPI0 Clock Gate Control +#define REG_SIM_SCGC6_DMAMUX 0x00000002 // DMA Mux Clock Gate Control +#define REG_SIM_SCGC6_FTFL 0x00000001 // Flash Memory Clock Gate Control +#define REG_SIM_SCGC7 0x40048040 // System Clock Gating Control Register 7 +#define REG_SIM_SCGC7_DMA 0x00000020 // DMA Clock Gate Control +#define REG_SIM_CLKDIV1 0x40048044 // System Clock Divider Register 1 +#define REG_SIM_CLKDIV1_OUTDIV1(n) (((n) & 0x0F) << 28) // divide value for the core/system clock +#define REG_SIM_CLKDIV1_OUTDIV2(n) (((n) & 0x0F) << 24) // divide value for the peripheral clock +#define REG_SIM_CLKDIV1_OUTDIV4(n) (((n) & 0x0F) << 16) // divide value for the flash clock +#define REG_SIM_CLKDIV2 0x40048048 // System Clock Divider Register 2 +#define REG_SIM_CLKDIV2_USBDIV(n) (((n) & 0x07) << 1) +#define REG_SIM_CLKDIV2_USBFRAC 0x01 +#define REG_SIM_FCFG1 0x4004804C // Flash Configuration Register 1 +#define REG_SIM_FCFG2 0x40048050 // Flash Configuration Register 2 +#define REG_SIM_UIDH 0x40048054 // Unique Identification Register High +#define REG_SIM_UIDMH 0x40048058 // Unique Identification Register Mid-High +#define REG_SIM_UIDML 0x4004805C // Unique Identification Register Mid Low +#define REG_SIM_UIDL 0x40048060 // Unique Identification Register Low + +// Chapter 13: Reset Control Module (RCM) +#define REG_RCM_SRS0 0x4007F000 // System Reset Status Register 0 +#define REG_RCM_SRS1 0x4007F001 // System Reset Status Register 1 +#define REG_RCM_RPFC 0x4007F004 // Reset Pin Filter Control Register +#define REG_RCM_RPFW 0x4007F005 // Reset Pin Filter Width Register +#define REG_RCM_MR 0x4007F007 // Mode Register + +// Chapter 14: System Mode Controller +#define REG_SMC_PMPROT 0x4007E000 // Power Mode Protection Register +#define REG_SMC_PMPROT_AVLP 0x20 // Allow very low power modes +#define REG_SMC_PMPROT_ALLS 0x08 // Allow low leakage stop mode +#define REG_SMC_PMPROT_AVLLS 0x02 // Allow very low leakage stop mode +#define REG_SMC_PMCTRL 0x4007E001 // Power Mode Control Register +#define REG_SMC_PMCTRL_LPWUI 0x80 // Low Power Wake Up on Interrupt +#define REG_SMC_PMCTRL_RUNM(n) (((n) & 0x03) << 5) // Run Mode Control +#define REG_SMC_PMCTRL_STOPA 0x08 // Stop Aborted +#define REG_SMC_PMCTRL_STOPM(n) ((n) & 0x07) // Stop Mode Control +#define REG_SMC_VLLSCTRL 0x4007E002 // VLLS Control Register +#define REG_SMC_VLLSCTRL_PORPO 0x20 // POR Power Option +#define REG_SMC_VLLSCTRL_VLLSM(n) ((n) & 0x07) // VLLS Mode Control +#define REG_SMC_PMSTAT 0x4007E003 // Power Mode Status Register +#define REG_SMC_PMSTAT_RUN 0x01 // Current power mode is RUN +#define REG_SMC_PMSTAT_STOP 0x02 // Current power mode is STOP +#define REG_SMC_PMSTAT_VLPR 0x04 // Current power mode is VLPR +#define REG_SMC_PMSTAT_VLPW 0x08 // Current power mode is VLPW +#define REG_SMC_PMSTAT_VLPS 0x10 // Current power mode is VLPS +#define REG_SMC_PMSTAT_LLS 0x20 // Current power mode is LLS +#define REG_SMC_PMSTAT_VLLS 0x40 // Current power mode is VLLS + +// Chapter 15: Power Management Controller +#define REG_PMC_LVDSC1 0x4007D000 // Low Voltage Detect Status And Control 1 register +#define REG_PMC_LVDSC1_LVDF 0x80 // Low-Voltage Detect Flag +#define REG_PMC_LVDSC1_LVDACK 0x40 // Low-Voltage Detect Acknowledge +#define REG_PMC_LVDSC1_LVDIE 0x20 // Low-Voltage Detect Interrupt Enable +#define REG_PMC_LVDSC1_LVDRE 0x10 // Low-Voltage Detect Reset Enable +#define REG_PMC_LVDSC1_LVDV(n) ((n) & 0x03) // Low-Voltage Detect Voltage Select +#define REG_PMC_LVDSC2 0x4007D001 // Low Voltage Detect Status And Control 2 register +#define REG_PMC_LVDSC2_LVWF 0x80 // Low-Voltage Warning Flag +#define REG_PMC_LVDSC2_LVWACK 0x40 // Low-Voltage Warning Acknowledge +#define REG_PMC_LVDSC2_LVWIE 0x20 // Low-Voltage Warning Interrupt Enable +#define REG_PMC_LVDSC2_LVWV(n) ((n) & 0x03) // Low-Voltage Warning Voltage Select +#define REG_PMC_REGSC 0x4007D002 // Regulator Status And Control register +#define REG_PMC_REGSC_BGEN 0x10 // Bandgap Enable In VLPx Operation +#define REG_PMC_REGSC_ACKISO 0x08 // Acknowledge Isolation +#define REG_PMC_REGSC_REGONS 0x04 // Regulator In Run Regulation Status +#define REG_PMC_REGSC_BGBE 0x01 // Bandgap Buffer Enable + +// Chapter 17: Miscellaneous Control Module (MCM) +#define REG_MCM_PLASC 0xE0080008 // Crossbar Switch (AXBS) Slave Configuration +#define REG_MCM_PLAMC 0xE008000A // Crossbar Switch (AXBS) Master Configuration +#define REG_MCM_PLACR 0xE008000C // Crossbar Switch (AXBS) Control Register + +// Chapter 24: Multipurpose Clock Generator (MCG) +#define REG_MCG_C1 0x40064000 // MCG Control 1 Register +#define REG_MCG_C1_IREFSTEN 0x01 // Internal Reference Stop Enable, Controls whether or not the internal reference clock remains enabled when the MCG enters Stop mode. +#define REG_MCG_C1_IRCLKEN 0x02 // Internal Reference Clock Enable, Enables the internal reference clock for use as MCGIRCLK. +#define REG_MCG_C1_IREFS 0x04 // Internal Reference Select, Selects the reference clock source for the FLL. +#define REG_MCG_C1_FRDIV(n) (((n) & 0x07) << 3) // FLL External Reference Divider, Selects the amount to divide down the external reference clock for the FLL +#define REG_MCG_C1_CLKS(n) (((n) & 0x03) << 6) // Clock Source Select, Selects the clock source for MCGOUTCLK +#define REG_MCG_C2 0x40064001 // MCG Control 2 Register +#define REG_MCG_C2_IRCS 0x01 // Internal Reference Clock Select, Selects between the fast or slow internal reference clock source. +#define REG_MCG_C2_LP 0x02 // Low Power Select, Controls whether the FLL or PLL is disabled in BLPI and BLPE modes. +#define REG_MCG_C2_EREFS 0x04 // External Reference Select, Selects the source for the external reference clock. +#define REG_MCG_C2_HGO0 0x08 // High Gain Oscillator Select, Controls the crystal oscillator mode of operation +#define REG_MCG_C2_RANGE0(n) (((n) & 0x03) << 4) // Frequency Range Select, Selects the frequency range for the crystal oscillator +#define REG_MCG_C2_LOCRE0 0x80 // Loss of Clock Reset Enable, Determines whether an interrupt or a reset request is made following a loss of OSC0 +#define REG_MCG_C3 0x40064002 // MCG Control 3 Register +#define REG_MCG_C3_SCTRIM(n) (n) // Slow Internal Reference Clock Trim Setting +#define REG_MCG_C4 0x40064003 // MCG Control 4 Register +#define REG_MCG_C4_SCFTRIM 0x01 // Slow Internal Reference Clock Fine Trim +#define REG_MCG_C4_FCTRIM(n) (((n) & 0x0F) << 1) // Fast Internal Reference Clock Trim Setting +#define REG_MCG_C4_DRST_DRS(n) (((n) & 0x03) << 5) // DCO Range Select +#define REG_MCG_C4_DMX32 0x80 // DCO Maximum Frequency with 32.768 kHz Reference, controls whether the DCO frequency range is narrowed +#define REG_MCG_C5 0x40064004 // MCG Control 5 Register +#define REG_MCG_C5_PRDIV0(n) ((n) & 0x1F) // PLL External Reference Divider +#define REG_MCG_C5_PLLSTEN0 0x20 // PLL Stop Enable +#define REG_MCG_C5_PLLCLKEN0 0x40 // PLL Clock Enable +#define REG_MCG_C6 0x40064005 // MCG Control 6 Register +#define REG_MCG_C6_VDIV0(n) ((n) & 0x1F) // VCO 0 Divider +#define REG_MCG_C6_CME0 0x20 // Clock Monitor Enable +#define REG_MCG_C6_PLLS 0x40 // PLL Select, Controls whether the PLL or FLL output is selected as the MCG source when CLKS[1:0]=00. +#define REG_MCG_C6_LOLIE0 0x80 // Loss of Lock Interrrupt Enable +#define REG_MCG_S 0x40064006 // MCG Status Register +#define REG_MCG_S_IRCST 0x01 // Internal Reference Clock Status +#define REG_MCG_S_OSCINIT0 0x02 // OSC Initialization, resets to 0, is set to 1 after the initialization cycles of the crystal oscillator +#define REG_MCG_S_CLKST(n) (((n) & 0x03) << 2) // Clock Mode Status, 0=FLL is selected, 1= Internal ref, 2=External ref, 3=PLL +#define REG_MCG_S_CLKST_MASK 0x0C +#define REG_MCG_S_IREFST 0x10 // Internal Reference Status +#define REG_MCG_S_PLLST 0x20 // PLL Select Status +#define REG_MCG_S_LOCK0 0x40 // Lock Status, 0=PLL Unlocked, 1=PLL Locked +#define REG_MCG_S_LOLS0 0x80 // Loss of Lock Status +#define REG_MCG_SC 0x40064008 // MCG Status and Control Register +#define REG_MCG_SC_LOCS0 0x01 // OSC0 Loss of Clock Status +#define REG_MCG_SC_FCRDIV(n) (((n) & 0x07) << 1) // Fast Clock Internal Reference Divider +#define REG_MCG_SC_FLTPRSRV 0x10 // FLL Filter Preserve Enable +#define REG_MCG_SC_ATMF 0x20 // Automatic Trim Machine Fail Flag +#define REG_MCG_SC_ATMS 0x40 // Automatic Trim Machine Select +#define REG_MCG_SC_ATME 0x80 // Automatic Trim Machine Enable +#define REG_MCG_ATCVH 0x4006400A // MCG Auto Trim Compare Value High Register +#define REG_MCG_ATCVL 0x4006400B // MCG Auto Trim Compare Value Low Register +#define REG_MCG_C7 0x4006400C // MCG Control 7 Register +#define REG_MCG_C8 0x4006400D // MCG Control 8 Register + +// Chapter 25: Oscillator (OSC) +#define REG_OSC0_CR 0x40065000 // OSC Control Register +#define REG_OSC_SC16P 0x01 // Oscillator 16 pF Capacitor Load Configure +#define REG_OSC_SC8P 0x02 // Oscillator 8 pF Capacitor Load Configure +#define REG_OSC_SC4P 0x04 // Oscillator 4 pF Capacitor Load Configure +#define REG_OSC_SC2P 0x08 // Oscillator 2 pF Capacitor Load Configure +#define REG_OSC_EREFSTEN 0x20 // External Reference Stop Enable, Controls whether or not the external reference clock (OSCERCLK) remains enabled when MCU enters Stop mode. +#define REG_OSC_ERCLKEN 0x80 // External Reference Enable, Enables external reference clock (OSCERCLK). + +// Chapter 27: Flash Memory Controller (FMC) +#define REG_FMC_PFAPR 0x4001F000 // Flash Access Protection +#define REG_FMC_PFB0CR 0x4001F004 // Flash Control +#define REG_FMC_TAGVDW0S0 0x4001F100 // Cache Tag Storage +#define REG_FMC_TAGVDW0S1 0x4001F104 // Cache Tag Storage +#define REG_FMC_TAGVDW1S0 0x4001F108 // Cache Tag Storage +#define REG_FMC_TAGVDW1S1 0x4001F10C // Cache Tag Storage +#define REG_FMC_TAGVDW2S0 0x4001F110 // Cache Tag Storage +#define REG_FMC_TAGVDW2S1 0x4001F114 // Cache Tag Storage +#define REG_FMC_TAGVDW3S0 0x4001F118 // Cache Tag Storage +#define REG_FMC_TAGVDW3S1 0x4001F11C // Cache Tag Storage +#define REG_FMC_DATAW0S0 0x4001F200 // Cache Data Storage +#define REG_FMC_DATAW0S1 0x4001F204 // Cache Data Storage +#define REG_FMC_DATAW1S0 0x4001F208 // Cache Data Storage +#define REG_FMC_DATAW1S1 0x4001F20C // Cache Data Storage +#define REG_FMC_DATAW2S0 0x4001F210 // Cache Data Storage +#define REG_FMC_DATAW2S1 0x4001F214 // Cache Data Storage +#define REG_FMC_DATAW3S0 0x4001F218 // Cache Data Storage +#define REG_FMC_DATAW3S1 0x4001F21C // Cache Data Storage + +// Chapter 28: Flash Memory Module (FTFL) +#define REG_FTFL_FSTAT 0x40020000 // Flash Status Register +#define REG_FTFL_FSTAT_CCIF 0x80 // Command Complete Interrupt Flag +#define REG_FTFL_FSTAT_RDCOLERR 0x40 // Flash Read Collision Error Flag +#define REG_FTFL_FSTAT_ACCERR 0x20 // Flash Access Error Flag +#define REG_FTFL_FSTAT_FPVIOL 0x10 // Flash Protection Violation Flag +#define REG_FTFL_FSTAT_MGSTAT0 0x01 // Memory Controller Command Completion Status Flag +#define REG_FTFL_FCNFG 0x40020001 // Flash Configuration Register +#define REG_FTFL_FCNFG_CCIE 0x80 // Command Complete Interrupt Enable +#define REG_FTFL_FCNFG_RDCOLLIE 0x40 // Read Collision Error Interrupt Enable +#define REG_FTFL_FCNFG_ERSAREQ 0x20 // Erase All Request +#define REG_FTFL_FCNFG_ERSSUSP 0x10 // Erase Suspend +#define REG_FTFL_FCNFG_PFLSH 0x04 // Flash memory configuration +#define REG_FTFL_FCNFG_RAMRDY 0x02 // RAM Ready +#define REG_FTFL_FCNFG_EEERDY 0x01 // EEPROM Ready +#define REG_FTFL_FSEC 0x40020002 // Flash Security Register +#define REG_FTFL_FOPT 0x40020003 // Flash Option Register +#define REG_FTFL_FCCOB3 0x40020004 // Flash Common Command Object Registers +#define REG_FTFL_FCCOB2 0x40020005 +#define REG_FTFL_FCCOB1 0x40020006 +#define REG_FTFL_FCCOB0 0x40020007 +#define REG_FTFL_FCCOB7 0x40020008 +#define REG_FTFL_FCCOB6 0x40020009 +#define REG_FTFL_FCCOB5 0x4002000A +#define REG_FTFL_FCCOB4 0x4002000B +#define REG_FTFL_FCCOBB 0x4002000C +#define REG_FTFL_FCCOBA 0x4002000D +#define REG_FTFL_FCCOB9 0x4002000E +#define REG_FTFL_FCCOB8 0x4002000F +#define REG_FTFL_FPROT3 0x40020010 // Program Flash Protection Registers +#define REG_FTFL_FPROT2 0x40020011 // Program Flash Protection Registers +#define REG_FTFL_FPROT1 0x40020012 // Program Flash Protection Registers +#define REG_FTFL_FPROT0 0x40020013 // Program Flash Protection Registers +#define REG_FTFL_FEPROT 0x40020016 // EEPROM Protection Register +#define REG_FTFL_FDPROT 0x40020017 // Data Flash Protection Register + +// Chapter 47: General-Purpose Input/Output (GPIO) +#define REG_GPIOA_PDOR 0x400FF000 // Port Data Output Register +#define REG_GPIOA_PSOR 0x400FF004 // Port Set Output Register +#define REG_GPIOA_PCOR 0x400FF008 // Port Clear Output Register +#define REG_GPIOA_PTOR 0x400FF00C // Port Toggle Output Register +#define REG_GPIOA_PDIR 0x400FF010 // Port Data Input Register +#define REG_GPIOA_PDDR 0x400FF014 // Port Data Direction Register +#define REG_GPIOB_PDOR 0x400FF040 // Port Data Output Register +#define REG_GPIOB_PSOR 0x400FF044 // Port Set Output Register +#define REG_GPIOB_PCOR 0x400FF048 // Port Clear Output Register +#define REG_GPIOB_PTOR 0x400FF04C // Port Toggle Output Register +#define REG_GPIOB_PDIR 0x400FF050 // Port Data Input Register +#define REG_GPIOB_PDDR 0x400FF054 // Port Data Direction Register +#define REG_GPIOC_PDOR 0x400FF080 // Port Data Output Register +#define REG_GPIOC_PSOR 0x400FF084 // Port Set Output Register +#define REG_GPIOC_PCOR 0x400FF088 // Port Clear Output Register +#define REG_GPIOC_PTOR 0x400FF08C // Port Toggle Output Register +#define REG_GPIOC_PDIR 0x400FF090 // Port Data Input Register +#define REG_GPIOC_PDDR 0x400FF094 // Port Data Direction Register +#define REG_GPIOD_PDOR 0x400FF0C0 // Port Data Output Register +#define REG_GPIOD_PSOR 0x400FF0C4 // Port Set Output Register +#define REG_GPIOD_PCOR 0x400FF0C8 // Port Clear Output Register +#define REG_GPIOD_PTOR 0x400FF0CC // Port Toggle Output Register +#define REG_GPIOD_PDIR 0x400FF0D0 // Port Data Input Register +#define REG_GPIOD_PDDR 0x400FF0D4 // Port Data Direction Register +#define REG_GPIOE_PDOR 0x400FF100 // Port Data Output Register +#define REG_GPIOE_PSOR 0x400FF104 // Port Set Output Register +#define REG_GPIOE_PCOR 0x400FF108 // Port Clear Output Register +#define REG_GPIOE_PTOR 0x400FF10C // Port Toggle Output Register +#define REG_GPIOE_PDIR 0x400FF110 // Port Data Input Register +#define REG_GPIOE_PDDR 0x400FF114 // Port Data Direction Register + +// System Control Space (SCS), ARMv7 ref manual, B3.2, page 708 +#define REG_SCB_CPUID 0xE000ED00 // CPUID Base Register +#define REG_SCB_ICSR 0xE000ED04 // Interrupt Control and State +#define REG_SCB_ICSR_PENDSTSET 0x04000000 +#define REG_SCB_VTOR 0xE000ED08 // Vector Table Offset +#define REG_SCB_AIRCR 0xE000ED0C // Application Interrupt and Reset Control +#define REG_SCB_SCR 0xE000ED10 // System Control Register +#define REG_SCB_CCR 0xE000ED14 // Configuration and Control +#define REG_SCB_SHPR1 0xE000ED18 // System Handler Priority Register 1 +#define REG_SCB_SHPR2 0xE000ED1C // System Handler Priority Register 2 +#define REG_SCB_SHPR3 0xE000ED20 // System Handler Priority Register 3 +#define REG_SCB_SHCSR 0xE000ED24 // System Handler Control and State +#define REG_SCB_CFSR 0xE000ED28 // Configurable Fault Status Register +#define REG_SCB_HFSR 0xE000ED2C // HardFault Status +#define REG_SCB_DFSR 0xE000ED30 // Debug Fault Status +#define REG_SCB_MMFAR 0xE000ED34 // MemManage Fault Address + +#define REG_SYST_CSR 0xE000E010 // SysTick Control and Status +#define REG_SYST_CSR_COUNTFLAG 0x00010000 +#define REG_SYST_CSR_CLKSOURCE 0x00000004 +#define REG_SYST_CSR_TICKINT 0x00000002 +#define REG_SYST_CSR_ENABLE 0x00000001 +#define REG_SYST_RVR 0xE000E014 // SysTick Reload Value Register +#define REG_SYST_CVR 0xE000E018 // SysTick Current Value Register +#define REG_SYST_CALIB 0xE000E01C // SysTick Calibration Value + +#define REG_ARM_DEMCR 0xE000EDFC // Debug Exception and Monitor Control +#define REG_ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks +#define REG_ARM_DWT_CTRL 0xE0001000 // DWT control register +#define REG_ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count +#define REG_ARM_DWT_CYCCNT 0xE0001004 // Cycle count register diff --git a/testjig/production/production.ino b/testjig/production/production.ino index 0cd0e6183e51ae130d93698574fd17c2a2bec5d4..4d0e9d0eef9fbf04fd72db1b4f3e57ced7eaf3f3 100644 --- a/testjig/production/production.ino +++ b/testjig/production/production.ino @@ -6,13 +6,13 @@ * Final OK / Error status shows up on WS2811 LEDs attached to the DUT. */ -#include "arm_debug.h" +#include "arm_kinetis_debug.h" const unsigned buttonPin = 2; const unsigned ledPin = 13; const unsigned swclkPin = 3; const unsigned swdioPin = 4; -ARMDebug target; +ARMKinetisDebug target; void setup() { @@ -37,32 +37,9 @@ void loop() } digitalWrite(ledPin, HIGH); - if (!target.begin(swclkPin, swdioPin, target.LOG_TRACE_MEM)) + if (!target.begin(swclkPin, swdioPin, target.LOG_TRACE_DP)) return; - if (!target.halt()) - return; - if (!target.sysReset()) - return; - - uint32_t data; - if (!target.memLoad(0x00000000, data)) - return; - if (!target.memLoad(0x00000000, data)) - return; - if (!target.memLoad(0x00000004, data)) - return; - if (!target.memLoad(0x00000004, data)) - return; - if (!target.memLoad(0x00000008, data)) - return; - if (!target.memLoad(0x00000008, data)) - return; - if (!target.memLoad(0x20000000, data)) - return; - - data ^= 0xFFFFFFFF; - if (!target.memStore(0x20000000, data)) - return; - if (!target.memLoad(0x20000000, data)) + if (!target.startup()) return; + target.flashMassErase(); }