MIMXRT1062: hal: port Arduino Teensy 4 Core startup code and linker script
The one oddity of this platform is that it requires using XIP (eXecute In Place), which for us largely means setting up a few special sections at special flash locations. References: https://www.nxp.com/docs/en/application-note/AN12107.pdf https://github.com/PaulStoffregen/cores/blob/master/teensy4/imxrt1062_t41.ld https://www.pjrc.com/store/teensy40.html#memory_layout
This commit is contained in:
parent
334fe4f499
commit
22b4ec3b6b
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2016 Fabio Utzig, http://fabioutzig.com
|
||||
* (C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MIMXRT1062 memory setup.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
/*
|
||||
* The top 64K of flash are unavailable:
|
||||
*
|
||||
* 60K are reserved for EEPROM emulation,
|
||||
* 4K are special read-only memory containing a known-good blink program
|
||||
*
|
||||
* See also https://www.pjrc.com/store/teensy40.html#memory_layout
|
||||
*/
|
||||
flash0 : org = 0x60000000, len = 1984K /* FLASH */
|
||||
flash1 : org = 0x00000000, len = 0
|
||||
flash2 : org = 0x00000000, len = 0
|
||||
flash3 : org = 0x00000000, len = 0
|
||||
flash4 : org = 0x00000000, len = 0
|
||||
flash5 : org = 0x00000000, len = 0
|
||||
flash6 : org = 0x00000000, len = 0
|
||||
flash7 : org = 0x00000000, len = 0
|
||||
|
||||
/* NOTE: ram0, ram1 and ram2 can be configured to use various
|
||||
* percentages of the available 512K of FlexRAM.
|
||||
*
|
||||
* The teensy linker script defines each with a 512k size.
|
||||
*
|
||||
* That is not safe to do with ChibiOS, where the full size
|
||||
* of an individual entry (e.g. 512K for ram1) will be used
|
||||
* in full, e.g. for the heap.
|
||||
*
|
||||
* We get around this limitation by allocating all 512K of
|
||||
* FlexRAM as DTCM (ram1), and not using ram0 and ram2 at all.
|
||||
*
|
||||
* See also:
|
||||
* IMXRT1060RM: Page 36 Table 3-1 System memory map (CM7)
|
||||
*/
|
||||
|
||||
/* Our startup code configures all of the flexram as DTCM. */
|
||||
/* ram0: DTCM, general purpose only
|
||||
2000_0000, up to 512KB */
|
||||
ram0 : org = 0x20000000, len = 512k
|
||||
|
||||
/* Our startup code does not configure any ram1. */
|
||||
/* Possible optimization: copy .text code into ram0 */
|
||||
/* ram1: ITCM, can be TCM or general purpose
|
||||
0000_0000, up to 512KB */
|
||||
/* ram1 : org = 0x00000000, len = 512k */
|
||||
ram1 : org = 0x00000000, len = 0
|
||||
|
||||
/* Our startup code does not configure any ram2. */
|
||||
/* ram2: OCRAM (On-Chip RAM), general purpose but not TCM (slower)
|
||||
2020_0000 Size: 512KB OCRAM2 */
|
||||
/* ram2 : org = 0x20200000, len = 512k */
|
||||
ram2 : org = 0x00000000, len = 0
|
||||
|
||||
ram3 : org = 0x00000000, len = 0
|
||||
ram4 : org = 0x00000000, len = 0
|
||||
ram5 : org = 0x00000000, len = 0
|
||||
ram6 : org = 0x00000000, len = 0
|
||||
ram7 : org = 0x00000000, len = 0
|
||||
}
|
||||
|
||||
/* Flash region for the configuration bytes.*/
|
||||
SECTIONS
|
||||
{
|
||||
.text.progmem : ALIGN(4)
|
||||
{
|
||||
. = 0;
|
||||
KEEP(*(.flashconfig))
|
||||
FILL(0xFF)
|
||||
/* IVT offset is 0x1000 from the bootable image as per section 2.5
|
||||
of https://www.nxp.com/docs/en/application-note/AN12107.pdf */
|
||||
. = ORIGIN(flash0) + 0x1000;
|
||||
KEEP(*(.ivt))
|
||||
KEEP(*(.bootdata))
|
||||
|
||||
/* .vectors get placed in rules_code.ld */
|
||||
} > flash0
|
||||
|
||||
.cfmprotect : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.cfmconfig))
|
||||
} > flash0
|
||||
}
|
||||
|
||||
/* For each data/text section two region are defined, a virtual region
|
||||
and a load region (_LMA suffix).*/
|
||||
|
||||
/* Flash region to be used for exception vectors.*/
|
||||
REGION_ALIAS("VECTORS_FLASH", flash0);
|
||||
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for constructors and destructors.*/
|
||||
REGION_ALIAS("XTORS_FLASH", flash0);
|
||||
REGION_ALIAS("XTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for code text.*/
|
||||
REGION_ALIAS("TEXT_FLASH", flash0);
|
||||
REGION_ALIAS("TEXT_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for read only data.*/
|
||||
REGION_ALIAS("RODATA_FLASH", flash0);
|
||||
REGION_ALIAS("RODATA_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for various.*/
|
||||
REGION_ALIAS("VARIOUS_FLASH", flash0);
|
||||
REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for RAM(n) initialization data.*/
|
||||
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
|
||||
|
||||
/* RAM region to be used for Main stack. This stack accommodates the processing
|
||||
of all exceptions and interrupts.*/
|
||||
REGION_ALIAS("MAIN_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for the process stack. This is the stack used by
|
||||
the main() function.*/
|
||||
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for data segment.*/
|
||||
/* .data in teensy-arduino-core/imxrt1062.ld */
|
||||
REGION_ALIAS("DATA_RAM", ram0);
|
||||
REGION_ALIAS("DATA_RAM_LMA", flash0);
|
||||
|
||||
/* RAM region to be used for BSS segment.*/
|
||||
/* .bss in imxrt1062.ld */
|
||||
REGION_ALIAS("BSS_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for the default heap.*/
|
||||
/* _heap_start in imxrt1062.ld */
|
||||
REGION_ALIAS("HEAP_RAM", ram0);
|
||||
|
||||
/* Generic rules inclusion.*/
|
||||
INCLUDE rules.ld
|
|
@ -204,8 +204,11 @@ const PALConfig pal_default_config =
|
|||
* and before any other initialization.
|
||||
*/
|
||||
void __early_init(void) {
|
||||
}
|
||||
|
||||
void __late_init(void) {
|
||||
MIMXRT1062_clock_init();
|
||||
MIMXRT1062_MPU_init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Portions Copyright (C) 2017 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.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file MIMXRT1062/bootable_image.c
|
||||
* @brief Additional information for the NXP BootROM.
|
||||
* With these extra sections, we define a bootable image,
|
||||
* allowing the BootROM to start our code from flash.
|
||||
* @note https://www.nxp.com/docs/en/nxp/application-notes/AN12238.pdf
|
||||
* @note https://www.nxp.com/docs/en/application-note/AN12107.pdf
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#include "printf_debug.h"
|
||||
|
||||
#include "clock_config.h"
|
||||
|
||||
#define NVIC_NUM_INTERRUPTS 160
|
||||
extern uint32_t _vectors[NVIC_NUM_INTERRUPTS];
|
||||
|
||||
extern void Reset_Handler(void);
|
||||
|
||||
// trampoline_reset_handler initializes FlexRAM, then jumps to the ChibiOS
|
||||
// Reset_Handler. This is required because the ChibiOS crt0 does not provide a
|
||||
// hook in a suitable place to integrate FlexRAM configuration.
|
||||
//
|
||||
// Note that when loading an image into the debugger, the ELF entry point
|
||||
// (specified by ENTRY(Reset_Handler) in rules_code.ld) is used directly, and
|
||||
// our trampoline_reset_handler that we configure in the Image Vector Table
|
||||
// (IVT) is not called. Instead, the debugger Connect Script
|
||||
// (e.g. rt1060_connect.scp) is responsible for setting up FlexRAM. Instead of
|
||||
// modifying the Connect Script accordingly, it might be easier to change
|
||||
// ENTRY(Reset_Handler) to ENTRY(trampoline_reset_handler) for debugging.
|
||||
__attribute__((target("thumb"), aligned(2)))
|
||||
void trampoline_reset_handler(void) {
|
||||
__disable_irq();
|
||||
|
||||
// Switch to final VTOR as quickly as possible to have fault handlers set up
|
||||
// (e.g. HardFault) for easier debugging. When encountering a fault without a
|
||||
// usable VTOR table, the MCU will raise another fault and end up in lockup.
|
||||
SCB->VTOR = (uint32_t)&_vectors;
|
||||
|
||||
IOMUXC_GPR->GPR17 = 0xaaaaaaaa;
|
||||
__DSB();
|
||||
__ISB();
|
||||
IOMUXC_GPR->GPR16 &= ~IOMUXC_GPR_GPR16_INIT_ITCM_EN_MASK;
|
||||
IOMUXC_GPR->GPR16 |=
|
||||
IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL(1) |
|
||||
IOMUXC_GPR_GPR16_INIT_DTCM_EN(1) |
|
||||
IOMUXC_GPR_GPR16_INIT_ITCM_EN(0);
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
uint32_t current_gpr14 = IOMUXC_GPR->GPR14;
|
||||
current_gpr14 &= ~IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK;
|
||||
current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ(10);
|
||||
current_gpr14 &= ~IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK;
|
||||
current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(0);
|
||||
IOMUXC_GPR->GPR14 = current_gpr14;
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
Reset_Handler();
|
||||
}
|
||||
|
||||
// IMXRT1060RM: 9.5.5 Exception handling
|
||||
// A minimal vector table with only the first 2 elements, i.e. initial SP (stack
|
||||
// pointer) and PC (program count) values.
|
||||
__attribute__ ((section(".vectors"), used, aligned(1024)))
|
||||
const uint32_t vector_table[] = {
|
||||
// Initial SP (stack pointer) value when booting.
|
||||
// Will be updated to point to DTCM FlexRAM by ChibiOS crt0_v7m.S.
|
||||
0x20201000, // OCRAM, always available regardless of FlexRAM setting.
|
||||
|
||||
// Initial PC (program count) value when booting.
|
||||
(uint32_t)&trampoline_reset_handler, // jumps to Reset_Handler
|
||||
};
|
||||
|
||||
/* See section 2.5.2 in https://www.nxp.com/docs/en/application-note/AN12107.pdf */
|
||||
__attribute__ ((section(".bootdata"), used))
|
||||
const uint32_t BootData[3] = {
|
||||
// destination address is equal to the external flash address, so the i.MX
|
||||
// BootROM will skip any remaining memory copies and start up the application
|
||||
// binary directly in the flash address space.
|
||||
// See section 3.2.2 in https://www.nxp.com/docs/en/nxp/application-notes/AN12238.pdf
|
||||
0x60000000, // absolute address of the bootable image
|
||||
// The following size normally determines how many bytes are copied from
|
||||
// flash to RAM, but because the destination address is equal to the
|
||||
// flash address, no copying is taking place.
|
||||
//
|
||||
// So, logically, we would set this field to 0, but 32 is the minimum
|
||||
// size that works in practice. My guess is that 32 is the size of the
|
||||
// IVT, and perhaps the BootROM code needs the IVT to be present and
|
||||
// accounted for. The NXP examples just set this to the size of the
|
||||
// flash, so we do the same:
|
||||
1984*1024,
|
||||
0, // plugin flag, 0 = normal boot image
|
||||
};
|
||||
|
||||
|
||||
/* See section 2.5.1 in https://www.nxp.com/docs/en/application-note/AN12107.pdf */
|
||||
__attribute__ ((section(".ivt"), used))
|
||||
const uint32_t ImageVectorTable[8] = {
|
||||
0x402000D1, // header
|
||||
(uint32_t)vector_table, // docs are wrong, needs to be vec table, not start addr
|
||||
0, // reserved
|
||||
|
||||
// DCD (Device Configuration Data), e.g. for SDRAM during boot. Note
|
||||
// that the BootROM of the i.MX RT 1060 does not actually support DCD,
|
||||
// so this field must always be set to 0:
|
||||
//
|
||||
// IMXRT1060RM: NOTE: The DCD is not supported in the BootROM, in this
|
||||
// device. It must be set to 0x00.
|
||||
0,
|
||||
|
||||
(uint32_t)BootData, // abs address of boot data
|
||||
(uint32_t)ImageVectorTable, // self
|
||||
0, // command sequence file
|
||||
0 // reserved
|
||||
};
|
||||
|
||||
__attribute__ ((section(".flashconfig"), used))
|
||||
uint32_t FlexSPI_NOR_Config[128] = {
|
||||
// 448 byte common FlexSPI configuration block, 8.6.3.1 page 223 (RT1060 rev 0)
|
||||
// MCU_Flashloader_Reference_Manual.pdf, 8.2.1, Table 8-2, page 72-75
|
||||
0x42464346, // Tag 0x00
|
||||
0x56010000, // Version
|
||||
0, // reserved
|
||||
0x00030301, // columnAdressWidth,dataSetupTime,dataHoldTime,readSampleClkSrc
|
||||
|
||||
0x00000000, // waitTimeCfgCommands,-,deviceModeCfgEnable
|
||||
0, // deviceModeSeq
|
||||
0, // deviceModeArg
|
||||
0x00000000, // -,-,-,configCmdEnable
|
||||
|
||||
0, // configCmdSeqs 0x20
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
0, // cfgCmdArgs 0x30
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
0x00000000, // controllerMiscOption 0x40
|
||||
// The Teensy 4 config used to run the FlexSPI Serial Clock at 60 MHz:
|
||||
// https://github.com/PaulStoffregen/cores/commit/c346fc36ed97dcaed2fa1d70626fbd80cf35586d
|
||||
// whereas NXP is running it with 100 MHz. With the old default of 60
|
||||
// MHz, I occasionally get hard faults when reading data from flash.
|
||||
0x00080401, // lutCustomSeqEnable,serialClkFreq,sflashPadType,deviceType
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
// TODO:
|
||||
#define ARDUINO_TEENSY41 1
|
||||
|
||||
#if defined(ARDUINO_TEENSY40)
|
||||
0x00200000, // sflashA1Size 0x50
|
||||
#elif defined(ARDUINO_TEENSY41)
|
||||
0x00800000, // sflashA1Size 0x50
|
||||
#else
|
||||
#error "Unknow flash chip size";
|
||||
#endif
|
||||
0, // sflashA2Size
|
||||
0, // sflashB1Size
|
||||
0, // sflashB2Size
|
||||
|
||||
0, // csPadSettingOverride 0x60
|
||||
0, // sclkPadSettingOverride
|
||||
0, // dataPadSettingOverride
|
||||
0, // dqsPadSettingOverride
|
||||
|
||||
0, // timeoutInMs 0x70
|
||||
0, // commandInterval
|
||||
0, // dataValidTime
|
||||
0x00000000, // busyBitPolarity,busyOffset
|
||||
|
||||
0x0A1804EB, // lookupTable[0] 0x80
|
||||
0x26043206, // lookupTable[1]
|
||||
0, // lookupTable[2]
|
||||
0, // lookupTable[3]
|
||||
|
||||
0x24040405, // lookupTable[4] 0x90
|
||||
0, // lookupTable[5]
|
||||
0, // lookupTable[6]
|
||||
0, // lookupTable[7]
|
||||
|
||||
0, // lookupTable[8] 0xA0
|
||||
0, // lookupTable[9]
|
||||
0, // lookupTable[10]
|
||||
0, // lookupTable[11]
|
||||
|
||||
0x00000406, // lookupTable[12] 0xB0
|
||||
0, // lookupTable[13]
|
||||
0, // lookupTable[14]
|
||||
0, // lookupTable[15]
|
||||
|
||||
0, // lookupTable[16] 0xC0
|
||||
0, // lookupTable[17]
|
||||
0, // lookupTable[18]
|
||||
0, // lookupTable[19]
|
||||
|
||||
0x08180420, // lookupTable[20] 0xD0
|
||||
0, // lookupTable[21]
|
||||
0, // lookupTable[22]
|
||||
0, // lookupTable[23]
|
||||
|
||||
0, // lookupTable[24] 0xE0
|
||||
0, // lookupTable[25]
|
||||
0, // lookupTable[26]
|
||||
0, // lookupTable[27]
|
||||
|
||||
0, // lookupTable[28] 0xF0
|
||||
0, // lookupTable[29]
|
||||
0, // lookupTable[30]
|
||||
0, // lookupTable[31]
|
||||
|
||||
0x081804D8, // lookupTable[32] 0x100
|
||||
0, // lookupTable[33]
|
||||
0, // lookupTable[34]
|
||||
0, // lookupTable[35]
|
||||
|
||||
0x08180402, // lookupTable[36] 0x110
|
||||
0x00002004, // lookupTable[37]
|
||||
0, // lookupTable[38]
|
||||
0, // lookupTable[39]
|
||||
|
||||
0, // lookupTable[40] 0x120
|
||||
0, // lookupTable[41]
|
||||
0, // lookupTable[42]
|
||||
0, // lookupTable[43]
|
||||
|
||||
0x00000460, // lookupTable[44] 0x130
|
||||
0, // lookupTable[45]
|
||||
0, // lookupTable[46]
|
||||
0, // lookupTable[47]
|
||||
|
||||
0, // lookupTable[48] 0x140
|
||||
0, // lookupTable[49]
|
||||
0, // lookupTable[50]
|
||||
0, // lookupTable[51]
|
||||
|
||||
0, // lookupTable[52] 0x150
|
||||
0, // lookupTable[53]
|
||||
0, // lookupTable[54]
|
||||
0, // lookupTable[55]
|
||||
|
||||
0, // lookupTable[56] 0x160
|
||||
0, // lookupTable[57]
|
||||
0, // lookupTable[58]
|
||||
0, // lookupTable[59]
|
||||
|
||||
0, // lookupTable[60] 0x170
|
||||
0, // lookupTable[61]
|
||||
0, // lookupTable[62]
|
||||
0, // lookupTable[63]
|
||||
|
||||
0, // LUT 0: Read 0x180
|
||||
0, // LUT 1: ReadStatus
|
||||
0, // LUT 3: WriteEnable
|
||||
0, // LUT 5: EraseSector
|
||||
|
||||
0, // LUT 9: PageProgram 0x190
|
||||
0, // LUT 11: ChipErase
|
||||
0, // LUT 15: Dummy
|
||||
0, // LUT unused?
|
||||
|
||||
0, // LUT unused? 0x1A0
|
||||
0, // LUT unused?
|
||||
0, // LUT unused?
|
||||
0, // LUT unused?
|
||||
|
||||
0, // reserved 0x1B0
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
|
||||
// 64 byte Serial NOR configuration block, 8.6.3.2, page 346
|
||||
|
||||
256, // pageSize 0x1C0
|
||||
4096, // sectorSize
|
||||
1, // ipCmdSerialClkFreq
|
||||
0, // reserved
|
||||
|
||||
0x00010000, // block size 0x1D0
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
|
||||
0, // reserved 0x1E0
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
|
||||
0, // reserved 0x1F0
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
0 // reserved
|
||||
};
|
|
@ -256,6 +256,9 @@ void BOARD_BootClockRUN(void)
|
|||
/* Set Flexspi clock source. */
|
||||
CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
|
||||
#endif
|
||||
// The following code results in a fault and seems incorrect: why set clock
|
||||
// detail settings after disabling the clock?
|
||||
#if 0
|
||||
/* Disable Flexspi2 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_FlexSpi2);
|
||||
/* Set FLEXSPI2_PODF. */
|
||||
|
@ -268,6 +271,7 @@ void BOARD_BootClockRUN(void)
|
|||
CLOCK_SetDiv(kCLOCK_CsiDiv, 1);
|
||||
/* Set Csi clock source. */
|
||||
CLOCK_SetMux(kCLOCK_CsiMux, 0);
|
||||
#endif
|
||||
/* Disable LPSPI clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi1);
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi2);
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file MK66F18/hal_lld.c
|
||||
* @brief Kinetis MK66F18 HAL Driver subsystem low level driver source template.
|
||||
* @file MIMXRT1062/hal_lld.c
|
||||
* @brief MIMXRT1062 HAL Driver subsystem low level driver source template.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
|
@ -52,6 +52,10 @@
|
|||
|
||||
#include "hal.h"
|
||||
|
||||
#include "printf_debug.h"
|
||||
|
||||
#include "clock_config.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -108,227 +112,54 @@ const uint8_t _cfm[0x10] = {
|
|||
* @notapi
|
||||
*/
|
||||
void hal_lld_init(void) {
|
||||
|
||||
#if defined(MK66F18)
|
||||
/* Disable the MPU by default */
|
||||
SYSMPU->CESR &= ~SYSMPU_CESR_VLD_MASK;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MK66F18 clock initialization.
|
||||
* @note All the involved constants come from the file @p board.h.
|
||||
* @note This function is meant to be invoked early during the system
|
||||
* initialization, it is usually invoked from the file
|
||||
* @p board.c.
|
||||
* @todo This function needs to be more generic.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void MK66F18_clock_init(void) {
|
||||
#if !KINETIS_NO_INIT
|
||||
|
||||
/* Disable the watchdog */
|
||||
WDOG->UNLOCK = 0xC520;
|
||||
WDOG->UNLOCK = 0xD928;
|
||||
WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN;
|
||||
#define NVIC_NUM_INTERRUPTS 160
|
||||
extern uint32_t _vectors[NVIC_NUM_INTERRUPTS];
|
||||
|
||||
SIM->SCGC5 |= SIM_SCGC5_PORTA |
|
||||
SIM_SCGC5_PORTB |
|
||||
SIM_SCGC5_PORTC |
|
||||
SIM_SCGC5_PORTD |
|
||||
SIM_SCGC5_PORTE;
|
||||
uint32_t SystemCoreClock = 528000000UL; // default system clock
|
||||
|
||||
void MIMXRT1062_clock_init(void) {
|
||||
// We need the IOMUXC for GPIO to work. We do not need BOARD_InitPins() from
|
||||
// the NXP SDK, we use the ChibiOS PAL HAL instead.
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc);
|
||||
|
||||
/* Ported from the Teensyduino Core Library at
|
||||
https://github.com/PaulStoffregen/cores/blob/master/teensy3/mk20dx128.c
|
||||
*/
|
||||
/* Allow the MCU to enter High Speed Run mode (HSRUN) */
|
||||
SMC->PMPROT = SMC_PMPROT_AHSRUN_SET(1) | SMC_PMPROT_AVLP_SET(1) | SMC_PMPROT_ALLS_SET(1) | SMC_PMPROT_AVLLS_SET(1);
|
||||
BOARD_InitBootClocks();
|
||||
//SystemCoreClockUpdate();
|
||||
|
||||
#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
|
||||
/* This is the default mode at reset. */
|
||||
// TODO: is the following covered by NXP startup code somewhere?
|
||||
|
||||
/* Configure FEI mode */
|
||||
MCG->C4 = MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS) |
|
||||
(KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0);
|
||||
// Configure the GPIO pins from the standard-speed GPIOs onto the high-speed
|
||||
// GPIOs GPIO6, GPIO7, GPIO8, and GPIO9:
|
||||
//
|
||||
// See also IMXRT1060RM, page 949, 12.1 Chip-specific GPIO information.
|
||||
IOMUXC_GPR->GPR26 = 0xFFFFFFFF;
|
||||
IOMUXC_GPR->GPR27 = 0xFFFFFFFF;
|
||||
IOMUXC_GPR->GPR28 = 0xFFFFFFFF;
|
||||
IOMUXC_GPR->GPR29 = 0xFFFFFFFF;
|
||||
|
||||
// Turn on the Teensy power LED on pin 13, which users generally expect:
|
||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03] =
|
||||
PIN_MUX_ALTERNATIVE(5);
|
||||
GPIO7->GDIR |= ((uint32_t) 1 << 3);
|
||||
GPIO7->DR_SET = ((uint32_t) 1 << 3);
|
||||
|
||||
printf_debug_init();
|
||||
printf_debug("\n***********IMXRT Chibi Startup**********\n");
|
||||
printf_debug("test %d %d %d\n", 1, -1234567, 3);
|
||||
|
||||
/* Set clock dividers */
|
||||
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
|
||||
SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
|
||||
#if defined(MK66F18)
|
||||
SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3-1) |
|
||||
#endif
|
||||
SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
|
||||
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0); /* not strictly necessary since usb_lld will set this */
|
||||
|
||||
#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
|
||||
|
||||
uint32_t ratio, frdiv;
|
||||
uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 };
|
||||
uint8_t ratio_quantity = sizeof(ratios) / sizeof(ratios[0]);
|
||||
uint8_t i;
|
||||
|
||||
/* EXTAL0 and XTAL0 */
|
||||
PORTA->PCR[18] = 0;
|
||||
PORTA->PCR[19] = 0;
|
||||
|
||||
/*
|
||||
* Start in FEI mode
|
||||
*/
|
||||
|
||||
/* Internal capacitors for crystal */
|
||||
#if defined(KINETIS_BOARD_OSCILLATOR_SETTING)
|
||||
OSC0->CR = KINETIS_BOARD_OSCILLATOR_SETTING;
|
||||
#else /* KINETIS_BOARD_OSCILLATOR_SETTING */
|
||||
/* Disable the internal capacitors */
|
||||
OSC0->CR = 0;
|
||||
#endif /* KINETIS_BOARD_OSCILLATOR_SETTING */
|
||||
|
||||
/* TODO: need to add more flexible calculation, specially regarding
|
||||
* divisors which may not be available depending on the XTAL
|
||||
* frequency, which would required other registers to be modified.
|
||||
*/
|
||||
/* Enable OSC, low power mode */
|
||||
if (KINETIS_XTAL_FREQUENCY > 8000000UL)
|
||||
MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0_SET(2);
|
||||
else
|
||||
MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0_SET(1);
|
||||
|
||||
frdiv = 7;
|
||||
ratio = KINETIS_XTAL_FREQUENCY / 31250UL;
|
||||
for (i = 0; i < ratio_quantity; ++i) {
|
||||
if (ratio == ratios[i]) {
|
||||
frdiv = i;
|
||||
break;
|
||||
}
|
||||
// Explicitly warn for a few issues I ran into, to catch possible
|
||||
// problems automatically when working on startup code:
|
||||
if (SCB->VTOR != (uint32_t)&_vectors) {
|
||||
printf_debug("WARNING: unexpected SCB->VTOR value %x, expected &_vectors = %x\n", SCB->VTOR, (uint32_t)&_vectors);
|
||||
}
|
||||
|
||||
/* Switch to crystal as clock source, FLL input of 31.25 KHz */
|
||||
MCG->C1 = MCG_C1_CLKS_SET(2) | MCG_C1_FRDIV_SET(frdiv);
|
||||
|
||||
/* Wait for crystal oscillator to begin */
|
||||
while (!(MCG->S & MCG_S_OSCINIT0));
|
||||
|
||||
/* Wait for the FLL to use the oscillator */
|
||||
while (MCG->S & MCG_S_IREFST);
|
||||
|
||||
/* Wait for the MCGOUTCLK to use the oscillator */
|
||||
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_SET(2));
|
||||
|
||||
/* Ported from the Teensyduino Core Library at
|
||||
https://github.com/PaulStoffregen/cores/blob/master/teensy3/mk20dx128.c
|
||||
*/
|
||||
#define F_CPU KINETIS_SYSCLK_FREQUENCY
|
||||
#define MCG_C5 MCG->C5
|
||||
#undef MCG_C5_PRDIV0
|
||||
#define MCG_C5_PRDIV0 MCG_C5_PRDIV0_SET
|
||||
#define MCG_C6 MCG->C6
|
||||
#undef MCG_C6_VDIV0
|
||||
#define MCG_C6_VDIV0 MCG_C6_VDIV0_SET
|
||||
#if 1 /* PJRC_HSRUN */
|
||||
// if we need faster than the crystal, turn on the PLL
|
||||
|
||||
SMC->PMCTRL = SMC_PMCTRL_RUNM_SET(3); // enter HSRUN mode
|
||||
#define SMC_PMSTAT_HSRUN ((uint8_t)0x80)
|
||||
while (SMC->PMSTAT != SMC_PMSTAT_HSRUN)
|
||||
; // wait for HSRUN
|
||||
|
||||
#if F_CPU == 256000000
|
||||
//See table in 27.4.6 MCG Control 6 Register (MCG_C6)
|
||||
//16 -> Multiply factor 32. 32*8MHz =256MHz
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(16);
|
||||
#elif F_CPU == 240000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(14);
|
||||
#elif F_CPU == 216000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(11);
|
||||
#elif F_CPU == 192000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(8);
|
||||
#elif F_CPU == 180000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(1);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(29);
|
||||
#elif F_CPU == 168000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(5);
|
||||
#elif F_CPU == 144000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(0);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(2);
|
||||
#elif F_CPU == 120000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(1);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(14);
|
||||
#elif F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(1);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(8);
|
||||
#elif F_CPU == 72000000
|
||||
MCG_C5 = MCG_C5_PRDIV0(1);
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(2);
|
||||
#elif F_CPU > 16000000
|
||||
#error "MK66FX1M0 does not support this clock speed yet...."
|
||||
#endif
|
||||
|
||||
#else /* PJRC_HSRUN */
|
||||
|
||||
/*
|
||||
* Now in FBE mode
|
||||
*/
|
||||
#define KINETIS_PLLIN_FREQUENCY 2000000UL
|
||||
/*
|
||||
* Config PLL input for 2 MHz
|
||||
* TODO: Make sure KINETIS_XTAL_FREQUENCY >= 2Mhz && <= 50Mhz
|
||||
*/
|
||||
MCG->C5 = MCG_C5_PRDIV0_SET((KINETIS_XTAL_FREQUENCY/KINETIS_PLLIN_FREQUENCY) - 1);
|
||||
|
||||
/*
|
||||
* Config PLL output to match KINETIS_SYSCLK_FREQUENCY
|
||||
* TODO: make sure KINETIS_SYSCLK_FREQUENCY is a match
|
||||
*/
|
||||
for(i = 24; i < 56; i++)
|
||||
{
|
||||
if(i == (KINETIS_PLLCLK_FREQUENCY/KINETIS_PLLIN_FREQUENCY))
|
||||
{
|
||||
/* Config PLL to match KINETIS_PLLCLK_FREQUENCY */
|
||||
MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0_SET(i-24);
|
||||
break;
|
||||
}
|
||||
if ((uint32_t)&_vectors % 4 != 0) {
|
||||
printf_debug("WARNING: &_vectors = %x is unexpectedly not aligned by 4\n", (uint32_t)&_vectors);
|
||||
}
|
||||
if (CORTEX_NUM_VECTORS != 160) {
|
||||
printf_debug("WARNING: unexpected CORTEX_NUM_VECTORS = %d, want %d", CORTEX_NUM_VECTORS, 160);
|
||||
}
|
||||
|
||||
if(i>=56) /* Config PLL for 96 MHz output as default setting */
|
||||
MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0_SET(0);
|
||||
#endif /* PJRC_HSRUN */
|
||||
|
||||
/* Wait for PLL to start using crystal as its input, and to lock */
|
||||
while ((MCG->S & (MCG_S_PLLST|MCG_S_LOCK0))!=(MCG_S_PLLST|MCG_S_LOCK0));
|
||||
|
||||
/*
|
||||
* Now in PBE mode
|
||||
*/
|
||||
/* Set the PLL dividers for the different clocks */
|
||||
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
|
||||
SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
|
||||
SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
|
||||
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0);
|
||||
|
||||
/* Configure peripherals to use MCGPLLCLK */
|
||||
SIM->SOPT2 = SIM_SOPT2_PLLFLLSEL;
|
||||
|
||||
/* Switch to PLL as clock source */
|
||||
MCG->C1 = MCG_C1_CLKS_SET(0);
|
||||
|
||||
/* Wait for PLL clock to be used */
|
||||
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL);
|
||||
|
||||
/*
|
||||
* Now in PEE mode
|
||||
*/
|
||||
#else /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */
|
||||
#error Unimplemented KINETIS_MCG_MODE
|
||||
#endif /* KINETIS_MCG_MODE == ... */
|
||||
|
||||
#endif /* !KINETIS_NO_INIT */
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -40,227 +40,17 @@
|
|||
* @name Platform identification
|
||||
* @{
|
||||
*/
|
||||
#define PLATFORM_NAME "Kinetis"
|
||||
#define PLATFORM_NAME "MIMXRT1062"
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Internal clock sources
|
||||
* @{
|
||||
*/
|
||||
#define KINETIS_IRCLK_F 4000000 /**< Fast internal reference clock, factory trimmed. */
|
||||
#define KINETIS_IRCLK_S 32768 /**< Slow internal reference clock, factory trimmed. */
|
||||
/** @} */
|
||||
|
||||
#define KINETIS_MCG_MODE_FEI 1 /**< FLL Engaged Internal. */
|
||||
#define KINETIS_MCG_MODE_FEE 2 /**< FLL Engaged External. */
|
||||
#define KINETIS_MCG_MODE_FBI 3 /**< FLL Bypassed Internal. */
|
||||
#define KINETIS_MCG_MODE_FBE 4 /**< FLL Bypassed External. */
|
||||
#define KINETIS_MCG_MODE_PEE 5 /**< PLL Engaged External. */
|
||||
#define KINETIS_MCG_MODE_PBE 6 /**< PLL Bypassed External. */
|
||||
#define KINETIS_MCG_MODE_BLPI 7 /**< Bypassed Low Power Internal. */
|
||||
#define KINETIS_MCG_MODE_BLPE 8 /**< Bypassed Low Power External. */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Disables the MCG/system clock initialization in the HAL.
|
||||
*/
|
||||
#if !defined(KINETIS_NO_INIT) || defined(__DOXYGEN__)
|
||||
#define KINETIS_NO_INIT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MCG mode selection.
|
||||
*/
|
||||
#if !defined(KINETIS_MCG_MODE) || defined(__DOXYGEN__)
|
||||
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MCU PLL clock frequency.
|
||||
*/
|
||||
#if !defined(KINETIS_PLLCLK_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define KINETIS_PLLCLK_FREQUENCY 96000000UL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clock divider for core/system clocks (OUTDIV1).
|
||||
* @note The allowed range is 1..16
|
||||
* @note The default value is calculated for a 48 MHz system clock
|
||||
* from a 96 MHz PLL output.
|
||||
*/
|
||||
#if !defined(KINETIS_CLKDIV1_OUTDIV1) || defined(__DOXYGEN__)
|
||||
#if defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV1 (KINETIS_PLLCLK_FREQUENCY/KINETIS_SYSCLK_FREQUENCY)
|
||||
#else
|
||||
#define KINETIS_CLKDIV1_OUTDIV1 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clock divider for bus clock (OUTDIV2).
|
||||
* @note The allowed range is 1..16
|
||||
* @note The default value is calculated for a 48 MHz bus clock
|
||||
* from a 96 MHz PLL output.
|
||||
*/
|
||||
#if !defined(KINETIS_CLKDIV1_OUTDIV2) || defined(__DOXYGEN__)
|
||||
#if defined(KINETIS_BUSCLK_FREQUENCY) && KINETIS_BUSCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV2 (KINETIS_PLLCLK_FREQUENCY/KINETIS_BUSCLK_FREQUENCY)
|
||||
#elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV2 KINETIS_CLKDIV1_OUTDIV1
|
||||
#else
|
||||
#define KINETIS_CLKDIV1_OUTDIV2 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clock divider for FlexBus clock (OUTDIV3).
|
||||
* @note The allowed range is 1..16
|
||||
* @note The default value is calculated for a 48 MHz clock
|
||||
* from a 96 MHz PLL output.
|
||||
*/
|
||||
#if !defined(KINETIS_CLKDIV1_OUTDIV3) || defined(__DOXYGEN__)
|
||||
#if defined(KINETIS_FLEXBUSCLK_FREQUENCY) && KINETIS_FLEXBUSCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV3 (KINETIS_PLLCLK_FREQUENCY/KINETIS_FLEXBUSCLK_FREQUENCY)
|
||||
#else
|
||||
/* If no FlexBus frequency provided, use bus speed divider */
|
||||
#define KINETIS_CLKDIV1_OUTDIV3 KINETIS_CLKDIV1_OUTDIV2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clock divider for flash clock (OUTDIV4).
|
||||
* @note The allowed range is 1..16
|
||||
* @note The default value is calculated for a 24 MHz flash clock
|
||||
* from a 96 MHz PLL output
|
||||
*/
|
||||
#if !defined(KINETIS_CLKDIV1_OUTDIV4) || defined(__DOXYGEN__)
|
||||
#if defined(KINETIS_FLASHCLK_FREQUENCY) && KINETIS_FLASHCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_PLLCLK_FREQUENCY/KINETIS_FLASHCLK_FREQUENCY)
|
||||
#elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
|
||||
#define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_CLKDIV1_OUTDIV1*2)
|
||||
#else
|
||||
#define KINETIS_CLKDIV1_OUTDIV4 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FLL DCO tuning enable for 32.768 kHz reference.
|
||||
* @note Set to 1 for fine-tuning DCO for maximum frequency with
|
||||
* a 32.768 kHz reference.
|
||||
* @note The default value is for a 32.768 kHz external crystal.
|
||||
*/
|
||||
#if !defined(KINETIS_MCG_FLL_DMX32) || defined(__DOXYGEN__)
|
||||
#define KINETIS_MCG_FLL_DMX32 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FLL DCO range selection.
|
||||
* @note The allowed range is 0...3.
|
||||
* @note The default value is calculated for 48 MHz FLL output
|
||||
* from a 32.768 kHz external crystal.
|
||||
* (DMX32 && DRST_DRS=1 => F=1464; 32.768 kHz * F ~= 48 MHz.)
|
||||
*
|
||||
*/
|
||||
#if !defined(KINETIS_MCG_FLL_DRS) || defined(__DOXYGEN__)
|
||||
#define KINETIS_MCG_FLL_DRS 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MCU system/core clock frequency.
|
||||
*/
|
||||
#if !defined(KINETIS_SYSCLK_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define KINETIS_SYSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MCU bus clock frequency.
|
||||
*/
|
||||
#if !defined(KINETIS_BUSCLK_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define KINETIS_BUSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MCU flash clock frequency.
|
||||
*/
|
||||
#if !defined(KINETIS_FLASHCLK_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define KINETIS_FLASHCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV4)
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(KINETIS_SYSCLK_FREQUENCY)
|
||||
#error KINETIS_SYSCLK_FREQUENCY must be defined
|
||||
#endif
|
||||
|
||||
#if KINETIS_SYSCLK_FREQUENCY <= 0 || KINETIS_SYSCLK_FREQUENCY > KINETIS_SYSCLK_MAX
|
||||
#error KINETIS_SYSCLK_FREQUENCY out of range
|
||||
#endif
|
||||
|
||||
#if !defined(KINETIS_BUSCLK_FREQUENCY)
|
||||
#error KINETIS_BUSCLK_FREQUENCY must be defined
|
||||
#endif
|
||||
|
||||
#if KINETIS_BUSCLK_FREQUENCY <= 0 || KINETIS_BUSCLK_FREQUENCY > KINETIS_BUSCLK_MAX
|
||||
#error KINETIS_BUSCLK_FREQUENCY out of range
|
||||
#endif
|
||||
|
||||
#if KINETIS_BUSCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
|
||||
#error KINETIS_BUSCLK_FREQUENCY must be an integer divide of\
|
||||
KINETIS_SYSCLK_FREQUENCY
|
||||
#endif
|
||||
|
||||
#if !defined(KINETIS_FLASHCLK_FREQUENCY)
|
||||
#error KINETIS_FLASHCLK_FREQUENCY must be defined
|
||||
#endif
|
||||
|
||||
#if KINETIS_FLASHCLK_FREQUENCY <= 0 || KINETIS_FLASHCLK_FREQUENCY > KINETIS_FLASHCLK_MAX
|
||||
#error KINETIS_FLASHCLK_FREQUENCY out of range
|
||||
#endif
|
||||
|
||||
#if KINETIS_FLASHCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
|
||||
#error KINETIS_FLASHCLK_FREQUENCY must be an integer divide of\
|
||||
KINETIS_SYSCLK_FREQUENCY
|
||||
#endif
|
||||
|
||||
#if !(defined(KINETIS_CLKDIV1_OUTDIV1) && \
|
||||
KINETIS_CLKDIV1_OUTDIV1 >= 1 && KINETIS_CLKDIV1_OUTDIV1 <= 16)
|
||||
#error KINETIS_CLKDIV1_OUTDIV1 must be 1 through 16
|
||||
#endif
|
||||
|
||||
#if !(defined(KINETIS_CLKDIV1_OUTDIV2) && \
|
||||
KINETIS_CLKDIV1_OUTDIV2 >= 1 && KINETIS_CLKDIV1_OUTDIV2 <= 16)
|
||||
#error KINETIS_CLKDIV1_OUTDIV2 must be 1 through 16
|
||||
#endif
|
||||
|
||||
#if !(defined(KINETIS_CLKDIV1_OUTDIV3) && \
|
||||
KINETIS_CLKDIV1_OUTDIV3 >= 1 && KINETIS_CLKDIV1_OUTDIV3 <= 16)
|
||||
#error KINETIS_CLKDIV1_OUTDIV3 must be 1 through 16
|
||||
#endif
|
||||
|
||||
#if !(defined(KINETIS_CLKDIV1_OUTDIV4) && \
|
||||
KINETIS_CLKDIV1_OUTDIV4 >= 1 && KINETIS_CLKDIV1_OUTDIV4 <= 16)
|
||||
#error KINETIS_CLKDIV1_OUTDIV4 must be 1 through 16
|
||||
#endif
|
||||
|
||||
#if !(KINETIS_MCG_FLL_DMX32 == 0 || KINETIS_MCG_FLL_DMX32 == 1)
|
||||
#error Invalid KINETIS_MCG_FLL_DMX32 value, must be 0 or 1
|
||||
#endif
|
||||
|
||||
#if !(0 <= KINETIS_MCG_FLL_DRS && KINETIS_MCG_FLL_DRS <= 3)
|
||||
#error Invalid KINETIS_MCG_FLL_DRS value, must be 0...3
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -312,7 +102,8 @@ typedef uint32_t halrtcnt_t;
|
|||
extern "C" {
|
||||
#endif
|
||||
void hal_lld_init(void);
|
||||
void MK66F18_clock_init(void);
|
||||
void MIMXRT1062_clock_init(void);
|
||||
void MIMXRT1062_MPU_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Portions Copyright (C) 2017 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.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file MIMXRT1062/mpu.c
|
||||
* @brief Memory Protection Unit (MPU) configuration.
|
||||
* @note Be careful when changing the linker script or FlexRAM config:
|
||||
* do not configure MPU regions for memory regions that are
|
||||
* not currently available, otherwise the device may hang.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#include "printf_debug.h"
|
||||
|
||||
#include "clock_config.h"
|
||||
|
||||
// TODO: port this to CMSIS style headers
|
||||
#define SCB_MPU_TYPE (*(volatile uint32_t *)0xE000ED90) //
|
||||
#define SCB_MPU_CTRL (*(volatile uint32_t *)0xE000ED94) //
|
||||
#define SCB_MPU_CTRL_PRIVDEFENA ((uint32_t)(1<<2)) // Enables default memory map
|
||||
#define SCB_MPU_CTRL_HFNMIENA ((uint32_t)(1<<1)) // Use MPU for HardFault & NMI
|
||||
#define SCB_MPU_CTRL_ENABLE ((uint32_t)(1<<0)) // Enables MPU
|
||||
#define SCB_MPU_RNR (*(volatile uint32_t *)0xE000ED98) //
|
||||
#define SCB_MPU_RBAR (*(volatile uint32_t *)0xE000ED9C) //
|
||||
#define SCB_MPU_RBAR_ADDR_MASK ((uint32_t)(0xFFFFFFE0))
|
||||
#define SCB_MPU_RBAR_VALID ((uint32_t)(1<<4))
|
||||
#define SCB_MPU_RBAR_REGION(n) ((uint32_t)((n) & 15))
|
||||
#define SCB_MPU_RASR (*(volatile uint32_t *)0xE000EDA0) // ARM DDI0403E, pg 696
|
||||
#define SCB_MPU_RASR_XN ((uint32_t)(1<<28))
|
||||
#define SCB_MPU_RASR_AP(n) ((uint32_t)(((n) & 7) << 24))
|
||||
#define SCB_MPU_RASR_TEX(n) ((uint32_t)(((n) & 7) << 19))
|
||||
#define SCB_MPU_RASR_S ((uint32_t)(1<<18))
|
||||
#define SCB_MPU_RASR_C ((uint32_t)(1<<17))
|
||||
#define SCB_MPU_RASR_B ((uint32_t)(1<<16))
|
||||
#define SCB_MPU_RASR_SRD(n) ((uint32_t)(((n) & 255) << 8))
|
||||
#define SCB_MPU_RASR_SIZE(n) ((uint32_t)(((n) & 31) << 1))
|
||||
#define SCB_MPU_RASR_ENABLE ((uint32_t)(1<<0))
|
||||
#define SCB_MPU_RBAR_A1 (*(volatile uint32_t *)0xE000EDA4) //
|
||||
#define SCB_MPU_RASR_A1 (*(volatile uint32_t *)0xE000EDA8) //
|
||||
#define SCB_MPU_RBAR_A2 (*(volatile uint32_t *)0xE000EDAC) //
|
||||
#define SCB_MPU_RASR_A2 (*(volatile uint32_t *)0xE000EDB0) //
|
||||
#define SCB_MPU_RBAR_A3 (*(volatile uint32_t *)0xE000EDB4) //
|
||||
#define SCB_MPU_RASR_A3 (*(volatile uint32_t *)0xE000EDB8) //
|
||||
|
||||
|
||||
// concise defines for SCB_MPU_RASR and SCB_MPU_RBAR, ARM DDI0403E, pg 696
|
||||
#define NOEXEC SCB_MPU_RASR_XN
|
||||
#define READONLY SCB_MPU_RASR_AP(7)
|
||||
#define READWRITE SCB_MPU_RASR_AP(3)
|
||||
#define NOACCESS SCB_MPU_RASR_AP(0)
|
||||
#define MEM_CACHE_WT SCB_MPU_RASR_TEX(0) | SCB_MPU_RASR_C
|
||||
#define MEM_CACHE_WB SCB_MPU_RASR_TEX(0) | SCB_MPU_RASR_C | SCB_MPU_RASR_B
|
||||
#define MEM_CACHE_WBWA SCB_MPU_RASR_TEX(1) | SCB_MPU_RASR_C | SCB_MPU_RASR_B
|
||||
#define MEM_NOCACHE SCB_MPU_RASR_TEX(1)
|
||||
#define DEV_NOCACHE SCB_MPU_RASR_TEX(2)
|
||||
#define SIZE_32B (SCB_MPU_RASR_SIZE(4) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_64B (SCB_MPU_RASR_SIZE(5) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_128B (SCB_MPU_RASR_SIZE(6) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_256B (SCB_MPU_RASR_SIZE(7) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_512B (SCB_MPU_RASR_SIZE(8) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_1K (SCB_MPU_RASR_SIZE(9) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_2K (SCB_MPU_RASR_SIZE(10) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_4K (SCB_MPU_RASR_SIZE(11) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_8K (SCB_MPU_RASR_SIZE(12) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_16K (SCB_MPU_RASR_SIZE(13) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_32K (SCB_MPU_RASR_SIZE(14) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_64K (SCB_MPU_RASR_SIZE(15) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_128K (SCB_MPU_RASR_SIZE(16) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_256K (SCB_MPU_RASR_SIZE(17) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_512K (SCB_MPU_RASR_SIZE(18) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_1M (SCB_MPU_RASR_SIZE(19) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_2M (SCB_MPU_RASR_SIZE(20) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_4M (SCB_MPU_RASR_SIZE(21) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_8M (SCB_MPU_RASR_SIZE(22) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_16M (SCB_MPU_RASR_SIZE(23) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_32M (SCB_MPU_RASR_SIZE(24) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_64M (SCB_MPU_RASR_SIZE(25) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_128M (SCB_MPU_RASR_SIZE(26) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_256M (SCB_MPU_RASR_SIZE(27) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_512M (SCB_MPU_RASR_SIZE(28) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_1G (SCB_MPU_RASR_SIZE(29) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_2G (SCB_MPU_RASR_SIZE(30) | SCB_MPU_RASR_ENABLE)
|
||||
#define SIZE_4G (SCB_MPU_RASR_SIZE(31) | SCB_MPU_RASR_ENABLE)
|
||||
#define REGION(n) (SCB_MPU_RBAR_REGION(n) | SCB_MPU_RBAR_VALID)
|
||||
|
||||
void MIMXRT1062_MPU_init(void)
|
||||
{
|
||||
MPU->CTRL = 0; // turn off MPU
|
||||
|
||||
uint32_t i = 0;
|
||||
MPU->RBAR = 0x00000000 | REGION(i++); //https://developer.arm.com/docs/146793866/10/why-does-the-cortex-m7-initiate-axim-read-accesses-to-memory-addresses-that-do-not-fall-under-a-defined-mpu-region
|
||||
MPU->RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_4G;
|
||||
|
||||
/* MPU->RBAR = 0x00000000 | REGION(i++); // ITCM */
|
||||
/* MPU->RASR = MEM_NOCACHE | READWRITE | SIZE_512K; */
|
||||
|
||||
// TODO: trap regions should be created last, because the hardware gives
|
||||
// priority to the higher number ones.
|
||||
MPU->RBAR = 0x00000000 | REGION(i++); // trap NULL pointer deref
|
||||
MPU->RASR = DEV_NOCACHE | NOACCESS | SIZE_32B;
|
||||
|
||||
MPU->RBAR = 0x00200000 | REGION(i++); // Boot ROM
|
||||
MPU->RASR = MEM_CACHE_WT | READONLY | SIZE_128K;
|
||||
|
||||
MPU->RBAR = 0x20000000 | REGION(i++); // DTCM
|
||||
MPU->RASR = MEM_NOCACHE | READWRITE | NOEXEC | SIZE_512K;
|
||||
|
||||
// teensy4/startup.c sets up a region on the stack to detect stack overflow.
|
||||
// ChibiOS, at the time of writing, does not.
|
||||
// MPU->RBAR = ((uint32_t)&_ebss) | REGION(i++); // trap stack overflow
|
||||
// MPU->RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_32B;
|
||||
|
||||
MPU->RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
|
||||
MPU->RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1M;
|
||||
|
||||
MPU->RBAR = 0x40000000 | REGION(i++); // Peripherals
|
||||
MPU->RASR = DEV_NOCACHE | READWRITE | NOEXEC | SIZE_64M;
|
||||
|
||||
MPU->RBAR = 0x60000000 | REGION(i++); // QSPI Flash
|
||||
MPU->RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M;
|
||||
|
||||
MPU->RBAR = 0x70000000 | REGION(i++); // FlexSPI2
|
||||
MPU->RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M;
|
||||
|
||||
// TODO: protect access to power supply config
|
||||
|
||||
MPU->CTRL = SCB_MPU_CTRL_ENABLE;
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -1,11 +1,15 @@
|
|||
PLATFORMSRC_CONTRIB := ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062/hal_lld.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/PITv1/hal_st_lld.c
|
||||
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062/clock_config.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062/printf_debug.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062/bootable_image.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062/mpu.c
|
||||
|
||||
PLATFORMINC_CONTRIB := ${CHIBIOS}/os/hal/ports/common/ARMCMx \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD \
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062
|
||||
|
||||
${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/MIMXRT1062 \
|
||||
${CHIBIOS_CONTRIB}/ext/mcux-sdk/devices/MIMXRT1062/drivers
|
||||
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
|
||||
# Configuration files directory
|
||||
|
@ -19,15 +23,16 @@ endif
|
|||
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/GPIOv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/UARTv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/SPIv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/I2Cv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/PORTv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/ADCv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/PITv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/SDHCv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/FTMv1/driver.mk
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/MIMXRT1062/LLD/USBHSv1/driver.mk
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(PLATFORMSRC_CONTRIB)
|
||||
ALLINC += $(PLATFORMINC_CONTRIB)
|
||||
|
||||
MIMXRT1062_DEFS = -DCPU_MIMXRT1062DVL6A -DXIP_EXTERNAL_FLASH=1
|
||||
|
||||
# The ChibiOS build system uses DDEFS:
|
||||
DDEFS += ${MIMXRT1062_DEFS}
|
||||
# The QMK ChibiOS build rules use OPT_DEFS:
|
||||
OPT_DEFS += ${MIMXRT1062_DEFS}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
// Enable to get startup debug on ChibiOS LPUART3 (== NXP peripheral LPUART4),
|
||||
// i.e. pin 17 on the Teensy 4.1:
|
||||
#if 0 /* PRINT_DEBUG_STUFF */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "fsl_lpuart.h"
|
||||
|
||||
void putchar_debug(char c);
|
||||
static void puint_debug(unsigned int num);
|
||||
|
||||
|
||||
void printf_debug(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
unsigned int val;
|
||||
int n;
|
||||
|
||||
va_start(args, format);
|
||||
for (; *format != 0; format++) { // no-frills stand-alone printf
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
if (*format == '%') goto out;
|
||||
if (*format == '-') format++; // ignore size
|
||||
while (*format >= '0' && *format <= '9') format++; // ignore size
|
||||
if (*format == 'l') format++; // ignore long
|
||||
if (*format == '\0') break;
|
||||
if (*format == 's') {
|
||||
printf_debug((char *)va_arg(args, int));
|
||||
} else if (*format == 'd') {
|
||||
n = va_arg(args, int);
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
putchar_debug('-');
|
||||
}
|
||||
puint_debug(n);
|
||||
} else if (*format == 'u') {
|
||||
puint_debug(va_arg(args, unsigned int));
|
||||
} else if (*format == 'x' || *format == 'X') {
|
||||
val = va_arg(args, unsigned int);
|
||||
for (n=0; n < 8; n++) {
|
||||
unsigned int d = (val >> 28) & 15;
|
||||
putchar_debug((d < 10) ? d + '0' : d - 10 + 'A');
|
||||
val <<= 4;
|
||||
}
|
||||
} else if (*format == 'c' ) {
|
||||
putchar_debug((char)va_arg(args, int));
|
||||
}
|
||||
} else {
|
||||
out:
|
||||
if (*format == '\n') putchar_debug('\r');
|
||||
putchar_debug(*format);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void puint_debug(unsigned int num)
|
||||
{
|
||||
char buf[12];
|
||||
unsigned int i = sizeof(buf)-2;
|
||||
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
while (1) {
|
||||
buf[i] = (num % 10) + '0';
|
||||
num /= 10;
|
||||
if (num == 0) break;
|
||||
i--;
|
||||
}
|
||||
printf_debug(buf + i);
|
||||
}
|
||||
|
||||
void putchar_debug(char c)
|
||||
{
|
||||
while (!(LPUART3->STAT & LPUART_STAT_TDRE(1))) ; // wait
|
||||
LPUART3->DATA = c;
|
||||
}
|
||||
|
||||
void printf_debug_init(void)
|
||||
{
|
||||
CCM->CCGR0 |= CCM_CCGR0_CG6(1); // turn on Serial4
|
||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06] = 2; // Arduino pin 17
|
||||
LPUART3->BAUD = LPUART_BAUD_OSR(25) | LPUART_BAUD_SBR(8); // ~115200 baud
|
||||
LPUART3->CTRL = LPUART_CTRL_TE(1);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#define printf_init()
|
||||
#define printf(...)
|
||||
#define printf_debug_init()
|
||||
#define printf_debug(...)
|
||||
|
||||
// Comment out to enable debug messages by a printf_debug implementation of your
|
||||
// choice, e.g. os/hal/ports/MIMXRT1062/MIMXRT1062/printf_debug.c:
|
||||
//
|
||||
// #include "chprintf.h"
|
||||
// #undef printf_debug
|
||||
// extern void printf_debug(const char *format, ...);
|
Loading…
Reference in New Issue