2014-02-03 00:14:57 +00:00
/* Teensyduino Core Library
* http : //www.pjrc.com/teensy/
* Copyright ( c ) 2013 PJRC . COM , LLC .
2015-01-11 03:53:46 +00:00
* Modifications by Jacob Alexander 2014 - 2015
2014-02-03 00:14:57 +00:00
*
* 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 :
*
2014-06-15 18:09:08 +00:00
* 1. The above copyright notice and this permission notice shall be
2014-02-03 00:14:57 +00:00
* included in all copies or substantial portions of the Software .
*
2014-06-15 18:09:08 +00:00
* 2. If the Software is incorporated into a build system that allows
2014-02-03 00:14:57 +00:00
* 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 .
*/
2015-01-11 03:53:46 +00:00
// ----- Includes -----
2015-06-14 03:42:12 +00:00
// Debug Includes
# if defined(_bootloader_)
# include <inttypes.h>
# include <debug.h>
# else
# include <print.h>
# endif
2014-07-01 06:52:24 +00:00
// Local Includes
2014-02-03 01:33:23 +00:00
# include "mk20dx.h"
2013-01-27 06:47:52 +00:00
2014-07-01 06:52:24 +00:00
// ----- Variables -----
2013-01-27 06:47:52 +00:00
extern unsigned long _stext ;
extern unsigned long _etext ;
extern unsigned long _sdata ;
extern unsigned long _edata ;
extern unsigned long _sbss ;
extern unsigned long _ebss ;
extern unsigned long _estack ;
2014-08-15 17:42:12 +00:00
const uint8_t sys_reset_to_loader_magic [ 22 ] = " \xff \x00 \x7f RESET TO LOADER \x7f \x00 \xff " ;
2013-01-27 06:47:52 +00:00
2014-07-01 06:52:24 +00:00
// ----- Function Declarations -----
2014-07-19 16:21:35 +00:00
extern int main ( ) ;
2014-07-01 06:52:24 +00:00
void ResetHandler ( ) ;
// ----- Interrupts -----
// NVIC - Default ISR
void fault_isr ( )
2013-01-27 06:47:52 +00:00
{
2015-06-23 14:58:31 +00:00
print ( " Fault! " NL ) ;
2014-07-01 06:52:24 +00:00
while ( 1 )
{
2014-02-03 00:14:57 +00:00
// keep polling some communication while in fault
// mode, so we don't completely die.
2014-07-01 06:52:24 +00:00
if ( SIM_SCGC4 & SIM_SCGC4_USBOTG ) usb_isr ( ) ;
if ( SIM_SCGC4 & SIM_SCGC4_UART0 ) uart0_status_isr ( ) ;
if ( SIM_SCGC4 & SIM_SCGC4_UART1 ) uart1_status_isr ( ) ;
if ( SIM_SCGC4 & SIM_SCGC4_UART2 ) uart2_status_isr ( ) ;
2014-02-03 00:14:57 +00:00
}
2013-01-27 06:47:52 +00:00
}
2014-07-01 06:52:24 +00:00
void unused_isr ( )
2013-01-27 06:47:52 +00:00
{
2014-02-03 00:14:57 +00:00
fault_isr ( ) ;
2013-01-27 06:47:52 +00:00
}
2014-07-01 06:52:24 +00:00
// NVIC - SysTick ISR
2013-01-27 06:47:52 +00:00
extern volatile uint32_t systick_millis_count ;
2014-07-01 06:52:24 +00:00
void systick_default_isr ( )
2013-01-27 06:47:52 +00:00
{
systick_millis_count + + ;
}
2014-07-01 06:52:24 +00:00
2015-06-14 03:42:12 +00:00
// NVIC - Non-Maskable Interrupt ISR
void nmi_default_isr ( )
{
2015-06-23 14:58:31 +00:00
print ( " NMI! " NL ) ;
2015-06-14 03:42:12 +00:00
}
// NVIC - Hard Fault ISR
void hard_fault_default_isr ( )
{
2015-08-19 07:01:15 +00:00
print ( " Hard Fault! SCB_HFSR: " ) ;
printHex32 ( SCB_HFSR ) ;
print ( NL ) ;
SOFTWARE_RESET ( ) ;
2015-06-14 03:42:12 +00:00
}
// NVIC - Memory Manager Fault ISR
void memmanage_fault_default_isr ( )
{
2015-08-19 07:01:15 +00:00
print ( " Memory Manager Fault! SCB_CFSR: " ) ;
printHex32 ( SCB_CFSR ) ;
print ( " SCB_MMAR: " ) ;
printHex32 ( SCB_MMAR ) ;
print ( NL ) ;
2015-06-14 03:42:12 +00:00
}
// NVIC - Bus Fault ISR
void bus_fault_default_isr ( )
{
2015-08-19 07:01:15 +00:00
print ( " Bus Fault! SCB_CFSR: " ) ;
printHex32 ( SCB_CFSR ) ;
print ( " SCB_BFAR: " ) ;
printHex32 ( SCB_BFAR ) ;
print ( NL ) ;
2015-06-14 03:42:12 +00:00
}
// NVIC - Usage Fault ISR
void usage_fault_default_isr ( )
{
2015-08-19 07:01:15 +00:00
print ( " Usage Fault! SCB_CFSR: " ) ;
printHex32 ( SCB_CFSR ) ;
print ( NL ) ;
2015-06-14 03:42:12 +00:00
}
2014-07-01 06:52:24 +00:00
// NVIC - Default ISR/Vector Linking
2015-06-14 03:42:12 +00:00
void nmi_isr ( ) __attribute__ ( ( weak , alias ( " nmi_default_isr " ) ) ) ;
void hard_fault_isr ( ) __attribute__ ( ( weak , alias ( " hard_fault_default_isr " ) ) ) ;
void memmanage_fault_isr ( ) __attribute__ ( ( weak , alias ( " memmanage_fault_default_isr " ) ) ) ;
void bus_fault_isr ( ) __attribute__ ( ( weak , alias ( " bus_fault_default_isr " ) ) ) ;
void usage_fault_isr ( ) __attribute__ ( ( weak , alias ( " usage_fault_default_isr " ) ) ) ;
2014-07-01 06:52:24 +00:00
void svcall_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void debugmonitor_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pendablesrvreq_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void systick_isr ( ) __attribute__ ( ( weak , alias ( " systick_default_isr " ) ) ) ;
void dma_ch0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch3_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch4_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch5_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch6_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch7_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch8_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch9_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch10_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch11_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch12_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch13_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch14_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_ch15_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dma_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void mcm_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void flash_cmd_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void flash_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void low_voltage_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void wakeup_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void watchdog_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void i2c0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void i2c1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void i2c2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void spi0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void spi1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void spi2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void sdhc_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_message_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_bus_off_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_tx_warn_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_rx_warn_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void can0_wakeup_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void i2s0_tx_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void i2s0_rx_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart0_lon_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart0_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart0_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart1_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart1_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart2_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart2_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart3_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart3_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart4_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart4_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart5_status_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void uart5_error_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void adc0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void adc1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void cmp0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void cmp1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void cmp2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void ftm0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void ftm1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void ftm2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void ftm3_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void cmt_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void rtc_alarm_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void rtc_seconds_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pit0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pit1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pit2_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pit3_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void pdb_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void usb_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void usb_charge_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dac0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void dac1_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void tsi0_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void mcg_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void lptmr_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void porta_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void portb_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void portc_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void portd_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void porte_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
void software_isr ( ) __attribute__ ( ( weak , alias ( " unused_isr " ) ) ) ;
// NVIC - Interrupt Vector Table
2013-01-27 06:47:52 +00:00
__attribute__ ( ( section ( " .vectors " ) , used ) )
2014-07-01 06:52:24 +00:00
void ( * const gVectors [ ] ) ( ) =
2013-01-27 06:47:52 +00:00
{
2014-07-01 06:52:24 +00:00
( void ( * ) ( void ) ) ( ( unsigned long ) & _estack ) , // 0 ARM: Initial Stack Pointer
ResetHandler , // 1 ARM: Initial Program Counter
nmi_isr , // 2 ARM: Non-maskable Interrupt (NMI)
hard_fault_isr , // 3 ARM: Hard Fault
memmanage_fault_isr , // 4 ARM: MemManage Fault
bus_fault_isr , // 5 ARM: Bus Fault
usage_fault_isr , // 6 ARM: Usage Fault
fault_isr , // 7 --
fault_isr , // 8 --
fault_isr , // 9 --
fault_isr , // 10 --
svcall_isr , // 11 ARM: Supervisor call (SVCall)
debugmonitor_isr , // 12 ARM: Debug Monitor
fault_isr , // 13 --
pendablesrvreq_isr , // 14 ARM: Pendable req serv(PendableSrvReq)
systick_isr , // 15 ARM: System tick timer (SysTick)
2014-06-15 18:09:08 +00:00
# if defined(_mk20dx128_) || defined(_mk20dx128vlf5_)
2014-07-01 06:52:24 +00:00
dma_ch0_isr , // 16 DMA channel 0 transfer complete
dma_ch1_isr , // 17 DMA channel 1 transfer complete
dma_ch2_isr , // 18 DMA channel 2 transfer complete
dma_ch3_isr , // 19 DMA channel 3 transfer complete
dma_error_isr , // 20 DMA error interrupt channel
unused_isr , // 21 DMA --
flash_cmd_isr , // 22 Flash Memory Command complete
flash_error_isr , // 23 Flash Read collision
low_voltage_isr , // 24 Low-voltage detect/warning
wakeup_isr , // 25 Low Leakage Wakeup
watchdog_isr , // 26 Both EWM and WDOG interrupt
i2c0_isr , // 27 I2C0
spi0_isr , // 28 SPI0
i2s0_tx_isr , // 29 I2S0 Transmit
i2s0_rx_isr , // 30 I2S0 Receive
uart0_lon_isr , // 31 UART0 CEA709.1-B (LON) status
uart0_status_isr , // 32 UART0 status
uart0_error_isr , // 33 UART0 error
uart1_status_isr , // 34 UART1 status
uart1_error_isr , // 35 UART1 error
uart2_status_isr , // 36 UART2 status
uart2_error_isr , // 37 UART2 error
adc0_isr , // 38 ADC0
cmp0_isr , // 39 CMP0
cmp1_isr , // 40 CMP1
ftm0_isr , // 41 FTM0
ftm1_isr , // 42 FTM1
cmt_isr , // 43 CMT
rtc_alarm_isr , // 44 RTC Alarm interrupt
rtc_seconds_isr , // 45 RTC Seconds interrupt
pit0_isr , // 46 PIT Channel 0
pit1_isr , // 47 PIT Channel 1
pit2_isr , // 48 PIT Channel 2
pit3_isr , // 49 PIT Channel 3
pdb_isr , // 50 PDB Programmable Delay Block
usb_isr , // 51 USB OTG
usb_charge_isr , // 52 USB Charger Detect
tsi0_isr , // 53 TSI0
mcg_isr , // 54 MCG
lptmr_isr , // 55 Low Power Timer
porta_isr , // 56 Pin detect (Port A)
portb_isr , // 57 Pin detect (Port B)
portc_isr , // 58 Pin detect (Port C)
portd_isr , // 59 Pin detect (Port D)
porte_isr , // 60 Pin detect (Port E)
software_isr , // 61 Software interrupt
2015-01-11 03:53:46 +00:00
# elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
2014-07-01 06:52:24 +00:00
dma_ch0_isr , // 16 DMA channel 0 transfer complete
dma_ch1_isr , // 17 DMA channel 1 transfer complete
dma_ch2_isr , // 18 DMA channel 2 transfer complete
dma_ch3_isr , // 19 DMA channel 3 transfer complete
dma_ch4_isr , // 20 DMA channel 4 transfer complete
dma_ch5_isr , // 21 DMA channel 5 transfer complete
dma_ch6_isr , // 22 DMA channel 6 transfer complete
dma_ch7_isr , // 23 DMA channel 7 transfer complete
dma_ch8_isr , // 24 DMA channel 8 transfer complete
dma_ch9_isr , // 25 DMA channel 9 transfer complete
dma_ch10_isr , // 26 DMA channel 10 transfer complete
dma_ch11_isr , // 27 DMA channel 10 transfer complete
dma_ch12_isr , // 28 DMA channel 10 transfer complete
dma_ch13_isr , // 29 DMA channel 10 transfer complete
dma_ch14_isr , // 30 DMA channel 10 transfer complete
dma_ch15_isr , // 31 DMA channel 10 transfer complete
dma_error_isr , // 32 DMA error interrupt channel
unused_isr , // 33 --
flash_cmd_isr , // 34 Flash Memory Command complete
flash_error_isr , // 35 Flash Read collision
low_voltage_isr , // 36 Low-voltage detect/warning
wakeup_isr , // 37 Low Leakage Wakeup
watchdog_isr , // 38 Both EWM and WDOG interrupt
unused_isr , // 39 --
i2c0_isr , // 40 I2C0
i2c1_isr , // 41 I2C1
spi0_isr , // 42 SPI0
spi1_isr , // 43 SPI1
unused_isr , // 44 --
can0_message_isr , // 45 CAN OR'ed Message buffer (0-15)
can0_bus_off_isr , // 46 CAN Bus Off
can0_error_isr , // 47 CAN Error
can0_tx_warn_isr , // 48 CAN Transmit Warning
can0_rx_warn_isr , // 49 CAN Receive Warning
can0_wakeup_isr , // 50 CAN Wake Up
i2s0_tx_isr , // 51 I2S0 Transmit
i2s0_rx_isr , // 52 I2S0 Receive
unused_isr , // 53 --
unused_isr , // 54 --
unused_isr , // 55 --
unused_isr , // 56 --
unused_isr , // 57 --
unused_isr , // 58 --
unused_isr , // 59 --
uart0_lon_isr , // 60 UART0 CEA709.1-B (LON) status
uart0_status_isr , // 61 UART0 status
uart0_error_isr , // 62 UART0 error
uart1_status_isr , // 63 UART1 status
uart1_error_isr , // 64 UART1 error
uart2_status_isr , // 65 UART2 status
uart2_error_isr , // 66 UART2 error
unused_isr , // 67 --
unused_isr , // 68 --
unused_isr , // 69 --
unused_isr , // 70 --
unused_isr , // 71 --
unused_isr , // 72 --
adc0_isr , // 73 ADC0
adc1_isr , // 74 ADC1
cmp0_isr , // 75 CMP0
cmp1_isr , // 76 CMP1
cmp2_isr , // 77 CMP2
ftm0_isr , // 78 FTM0
ftm1_isr , // 79 FTM1
ftm2_isr , // 80 FTM2
cmt_isr , // 81 CMT
rtc_alarm_isr , // 82 RTC Alarm interrupt
rtc_seconds_isr , // 83 RTC Seconds interrupt
pit0_isr , // 84 PIT Channel 0
pit1_isr , // 85 PIT Channel 1
pit2_isr , // 86 PIT Channel 2
pit3_isr , // 87 PIT Channel 3
pdb_isr , // 88 PDB Programmable Delay Block
usb_isr , // 89 USB OTG
usb_charge_isr , // 90 USB Charger Detect
unused_isr , // 91 --
unused_isr , // 92 --
unused_isr , // 93 --
unused_isr , // 94 --
unused_isr , // 95 --
unused_isr , // 96 --
dac0_isr , // 97 DAC0
unused_isr , // 98 --
tsi0_isr , // 99 TSI0
mcg_isr , // 100 MCG
lptmr_isr , // 101 Low Power Timer
unused_isr , // 102 --
porta_isr , // 103 Pin detect (Port A)
portb_isr , // 104 Pin detect (Port B)
portc_isr , // 105 Pin detect (Port C)
portd_isr , // 106 Pin detect (Port D)
porte_isr , // 107 Pin detect (Port E)
unused_isr , // 108 --
unused_isr , // 109 --
software_isr , // 110 Software interrupt
2014-02-03 00:14:57 +00:00
# endif
2013-01-27 06:47:52 +00:00
} ;
2014-06-26 07:54:39 +00:00
2014-07-01 06:52:24 +00:00
// ----- Flash Configuration -----
2013-01-27 06:47:52 +00:00
2014-07-01 06:52:24 +00:00
// Only necessary for Teensy 3s, MCHCK uses the Bootloader to handle this
# if defined(_mk20dx128_) || defined(_mk20dx256_)
2013-01-27 06:47:52 +00:00
__attribute__ ( ( section ( " .flashconfig " ) , used ) )
const uint8_t flashconfigbytes [ 16 ] = {
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFE , 0xFF , 0xFF , 0xFF
} ;
2014-08-15 17:42:12 +00:00
# elif defined(_mk20dx128vlf5_) && defined(_bootloader_)
// XXX Byte labels may be in incorrect positions, double check before modifying
// FSEC is in correct location -Jacob
__attribute__ ( ( section ( " .flashconfig " ) , used ) )
const uint8_t flashconfigbytes [ 16 ] = {
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , // Backdoor Verif Key 28.3.1
2014-11-05 08:09:33 +00:00
//
// Protecting the first 4k of Flash memory from being over-written while running (bootloader protection)
// Still possible to overwrite the bootloader using an external flashing device
// For more details see:
// http://cache.freescale.com/files/training/doc/dwf/AMF_ENT_T1031_Boston.pdf (page 8)
// http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf
// http://cache.freescale.com/files/32bit/doc/ref_manual/K20P48M50SF0RM.pdf (28.34.6)
//
0xFF , 0xFF , 0xFF , 0xFE , // Program Flash Protection Bytes FPROT0-3
2014-08-15 17:42:12 +00:00
0xBE , // Flash security byte FSEC
0x03 , // Flash nonvolatile option byte FOPT
0xFF , // EEPROM Protection Byte FEPROT
0xFF , // Data Flash Protection Byte FDPROT
} ;
2015-01-01 01:13:44 +00:00
# elif defined(_mk20dx256vlh7_) && defined(_bootloader_)
// XXX Byte labels may be in incorrect positions, double check before modifying
// FSEC is in correct location -Jacob
__attribute__ ( ( section ( " .flashconfig " ) , used ) )
const uint8_t flashconfigbytes [ 16 ] = {
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , // Backdoor Verif Key 28.3.1
//
// Protecting the first 8k of Flash memory from being over-written while running (bootloader protection)
// Still possible to overwrite the bootloader using an external flashing device
// For more details see:
// http://cache.freescale.com/files/training/doc/dwf/AMF_ENT_T1031_Boston.pdf (page 8)
// http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf
// http://cache.freescale.com/files/32bit/doc/ref_manual/K20P64M72SF1RM.pdf (28.34.6)
//
2015-06-14 03:42:12 +00:00
0xFF , 0xFF , 0xFF , 0xFE , // Program Flash Protection Bytes FPROT0-3
2015-01-01 01:13:44 +00:00
0xBE , // Flash security byte FSEC
0x03 , // Flash nonvolatile option byte FOPT
0xFF , // EEPROM Protection Byte FEPROT
0xFF , // Data Flash Protection Byte FDPROT
2015-03-21 02:54:23 +00:00
} ;
2014-06-26 07:54:39 +00:00
# endif
2013-01-27 06:47:52 +00:00
2014-08-15 17:42:12 +00:00
// ----- Functions -----
2015-01-11 03:53:46 +00:00
# if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
2014-08-15 17:42:12 +00:00
__attribute__ ( ( noreturn ) )
static inline void jump_to_app ( uintptr_t addr )
{
2015-03-09 01:40:01 +00:00
// addr is in r0
__asm__ ( " ldr sp, [%[addr], #0] \n "
" ldr pc, [%[addr], #4] "
: : [ addr ] " r " ( addr ) ) ;
// NOTREACHED
__builtin_unreachable ( ) ;
2014-08-15 17:42:12 +00:00
}
2015-01-01 03:43:10 +00:00
# endif
2014-08-15 17:42:12 +00:00
void * memset ( void * addr , int val , unsigned int len )
{
char * buf = addr ;
for ( ; len > 0 ; - - len , + + buf )
* buf = val ;
return ( addr ) ;
}
int memcmp ( const void * a , const void * b , unsigned int len )
{
const uint8_t * ap = a , * bp = b ;
int val = 0 ;
for ( ; len > 0 & & ( val = * ap - * bp ) = = 0 ; - - len , + + ap , + + bp )
/* NOTHING */ ;
return ( val ) ;
}
void * memcpy ( void * dst , const void * src , unsigned int len )
{
char * dstbuf = dst ;
const char * srcbuf = src ;
for ( ; len > 0 ; - - len , + + dstbuf , + + srcbuf )
* dstbuf = * srcbuf ;
return ( dst ) ;
}
2014-07-01 06:52:24 +00:00
// ----- Chip Entry Point -----
2013-01-27 06:47:52 +00:00
__attribute__ ( ( section ( " .startup " ) ) )
2014-07-01 06:52:24 +00:00
void ResetHandler ( )
2013-01-27 06:47:52 +00:00
{
2015-01-11 03:53:46 +00:00
# if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
2014-08-15 17:42:12 +00:00
extern uint32_t _app_rom ;
// We treat _app_rom as pointer to directly read the stack
// pointer and check for valid app code. This is no fool
// proof method, but it should help for the first flash.
2015-01-11 03:53:46 +00:00
//
// Purposefully disabling the watchdog *after* the reset check this way
// if the chip goes into an odd state we'll reset to the bootloader (invalid firmware image)
// RCM_SRS0 & 0x20
//
// Also checking for ARM lock-up signal (invalid firmware image)
// RCM_SRS1 & 0x02
2015-04-05 06:21:11 +00:00
if ( // PIN (External Reset Pin/Switch)
RCM_SRS0 & 0x40
// WDOG (Watchdog timeout)
| | RCM_SRS0 & 0x20
// LOCKUP (ARM Core LOCKUP event)
| | RCM_SRS1 & 0x02
// Blank flash check
| | _app_rom = = 0xffffffff
// Software reset
| | memcmp ( ( uint8_t * ) & VBAT , sys_reset_to_loader_magic , sizeof ( sys_reset_to_loader_magic ) ) = = 0
)
2014-08-15 17:42:12 +00:00
{
memset ( ( uint8_t * ) & VBAT , 0 , sizeof ( VBAT ) ) ;
}
else
{
uint32_t addr = ( uintptr_t ) & _app_rom ;
SCB_VTOR = addr ; // relocate vector table
jump_to_app ( addr ) ;
}
# endif
2015-01-11 03:53:46 +00:00
// Disable Watchdog
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1 ;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2 ;
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE ;
2014-08-15 17:42:12 +00:00
2015-01-01 03:43:10 +00:00
uint32_t * src = ( uint32_t * ) & _etext ;
uint32_t * dest = ( uint32_t * ) & _sdata ;
2014-08-15 17:42:12 +00:00
2014-07-15 07:28:12 +00:00
// Enable clocks to always-used peripherals
SIM_SCGC5 = 0x00043F82 ; // Clocks active to all GPIO
SIM_SCGC6 = SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL ;
# if defined(_mk20dx128_)
SIM_SCGC6 | = SIM_SCGC6_RTC ;
2015-06-14 03:42:12 +00:00
# elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
2014-02-03 00:14:57 +00:00
SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2 ;
2014-07-15 07:28:12 +00:00
SIM_SCGC6 | = SIM_SCGC6_RTC ;
2014-02-03 00:14:57 +00:00
# endif
2014-07-01 06:52:24 +00:00
# if defined(_mk20dx128_) || defined(_mk20dx256_) // Teensy 3s
2013-01-27 06:47:52 +00:00
// if the RTC oscillator isn't enabled, get it started early
2014-07-01 06:52:24 +00:00
if ( ! ( RTC_CR & RTC_CR_OSCE ) )
{
2013-01-27 06:47:52 +00:00
RTC_SR = 0 ;
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE ;
}
2014-07-01 06:52:24 +00:00
# endif
2013-01-27 06:47:52 +00:00
2014-02-03 00:14:57 +00:00
// release I/O pins hold, if we woke up from VLLS mode
2014-07-15 07:28:12 +00:00
if ( PMC_REGSC & PMC_REGSC_ACKISO )
{
PMC_REGSC | = PMC_REGSC_ACKISO ;
}
2014-02-03 00:14:57 +00:00
2014-07-01 06:52:24 +00:00
// Prepare RAM
2015-01-01 03:43:10 +00:00
while ( dest < ( uint32_t * ) & _edata ) * dest + + = * src + + ;
dest = ( uint32_t * ) & _sbss ;
while ( dest < ( uint32_t * ) & _ebss ) * dest + + = 0 ;
2014-02-03 00:14:57 +00:00
2015-01-11 03:53:46 +00:00
// MCHCK / Kiibohd-dfu
2014-06-26 07:54:39 +00:00
# if defined(_mk20dx128vlf5_)
2014-07-15 07:28:12 +00:00
// Default all interrupts to medium priority level
for ( unsigned int i = 0 ; i < NVIC_NUM_INTERRUPTS ; i + + )
{
NVIC_SET_PRIORITY ( i , 128 ) ;
}
2015-03-09 01:40:01 +00:00
// FLL at 48MHz
2014-07-01 06:52:24 +00:00
MCG_C4 = MCG_C4_DMX32 | MCG_C4_DRST_DRS ( 1 ) ;
2014-06-26 07:54:39 +00:00
2014-07-15 07:28:12 +00:00
// USB Clock and FLL select
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL ;
2014-06-26 07:54:39 +00:00
2015-01-11 03:53:46 +00:00
// Teensy 3.0 and 3.1 and Kiibohd-dfu (mk20dx256vlh7)
2014-07-01 06:52:24 +00:00
# else
2015-06-14 03:42:12 +00:00
# if defined(_mk20dx128_) || defined(_mk20dx256_)
// use vector table in flash
SCB_VTOR = 0 ;
# endif
2014-06-26 07:54:39 +00:00
2014-07-01 06:52:24 +00:00
// default all interrupts to medium priority level
2015-01-11 03:53:46 +00:00
for ( unsigned int i = 0 ; i < NVIC_NUM_INTERRUPTS ; i + + )
2014-07-01 06:52:24 +00:00
{
NVIC_SET_PRIORITY ( i , 128 ) ;
}
2014-06-26 07:54:39 +00:00
2014-02-03 00:14:57 +00:00
// start in FEI mode
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P ;
2014-07-01 06:52:24 +00:00
2014-02-03 00:14:57 +00:00
// enable osc, 8-32 MHz range, low power mode
2014-07-01 06:52:24 +00:00
MCG_C2 = MCG_C2_RANGE0 ( 2 ) | MCG_C2_EREFS ;
2014-02-03 00:14:57 +00:00
// switch to crystal as clock source, FLL input = 16 MHz / 512
2014-07-01 06:52:24 +00:00
MCG_C1 = MCG_C1_CLKS ( 2 ) | MCG_C1_FRDIV ( 4 ) ;
2014-02-03 00:14:57 +00:00
// wait for crystal oscillator to begin
2014-07-01 06:52:24 +00:00
while ( ( MCG_S & MCG_S_OSCINIT0 ) = = 0 ) ;
2014-02-03 00:14:57 +00:00
// wait for FLL to use oscillator
2014-07-01 06:52:24 +00:00
while ( ( MCG_S & MCG_S_IREFST ) ! = 0 ) ;
2014-02-03 00:14:57 +00:00
// wait for MCGOUT to use oscillator
2014-07-01 06:52:24 +00:00
while ( ( MCG_S & MCG_S_CLKST_MASK ) ! = MCG_S_CLKST ( 2 ) ) ;
2014-02-03 00:14:57 +00:00
// now we're in FBE mode
2015-04-20 07:55:58 +00:00
# if F_CPU == 72000000
// config PLL input for 16 MHz Crystal / 8 = 2 MHz
MCG_C5 = MCG_C5_PRDIV0 ( 7 ) ;
# else
2014-02-03 00:14:57 +00:00
// config PLL input for 16 MHz Crystal / 4 = 4 MHz
2014-07-01 06:52:24 +00:00
MCG_C5 = MCG_C5_PRDIV0 ( 3 ) ;
2015-04-20 07:55:58 +00:00
# endif
2014-07-01 06:52:24 +00:00
2015-04-20 07:55:58 +00:00
# if F_CPU == 72000000
// config PLL for 72 MHz output (36 * 2 MHz Ext PLL)
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0 ( 12 ) ;
# else
2014-02-03 00:14:57 +00:00
// config PLL for 96 MHz output
2014-07-01 06:52:24 +00:00
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0 ( 0 ) ;
2015-04-20 07:55:58 +00:00
# endif
2014-07-01 06:52:24 +00:00
2014-02-03 00:14:57 +00:00
// wait for PLL to start using xtal as its input
2014-07-01 06:52:24 +00:00
while ( ! ( MCG_S & MCG_S_PLLST ) ) ;
2014-02-03 00:14:57 +00:00
// wait for PLL to lock
2014-07-01 06:52:24 +00:00
while ( ! ( MCG_S & MCG_S_LOCK0 ) ) ;
2014-02-03 00:14:57 +00:00
// now we're in PBE mode
2013-01-27 06:47:52 +00:00
# if F_CPU == 96000000
2014-02-03 00:14:57 +00:00
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash
2014-07-01 06:52:24 +00:00
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1 ( 0 ) | SIM_CLKDIV1_OUTDIV2 ( 1 ) | SIM_CLKDIV1_OUTDIV4 ( 3 ) ;
2015-04-20 07:55:58 +00:00
# elif F_CPU == 72000000
// config divisors: 72 MHz core, 36 MHz bus, 24 MHz flash
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1 ( 0 ) | SIM_CLKDIV1_OUTDIV2 ( 1 ) | SIM_CLKDIV1_OUTDIV4 ( 2 ) ;
2013-01-27 06:47:52 +00:00
# elif F_CPU == 48000000
2014-02-03 00:14:57 +00:00
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
2014-07-01 06:52:24 +00:00
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1 ( 1 ) | SIM_CLKDIV1_OUTDIV2 ( 1 ) | SIM_CLKDIV1_OUTDIV4 ( 3 ) ;
2013-01-27 06:47:52 +00:00
# elif F_CPU == 24000000
2014-02-03 00:14:57 +00:00
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash
2014-07-01 06:52:24 +00:00
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1 ( 3 ) | SIM_CLKDIV1_OUTDIV2 ( 3 ) | SIM_CLKDIV1_OUTDIV4 ( 3 ) ;
2013-01-27 06:47:52 +00:00
# else
2015-04-20 07:55:58 +00:00
# error "Error, F_CPU must be 96000000, 72000000, 48000000, or 24000000"
2013-01-27 06:47:52 +00:00
# endif
2014-02-03 00:14:57 +00:00
// switch to PLL as clock source, FLL input = 16 MHz / 512
2014-07-01 06:52:24 +00:00
MCG_C1 = MCG_C1_CLKS ( 0 ) | MCG_C1_FRDIV ( 4 ) ;
2014-02-03 00:14:57 +00:00
// wait for PLL clock to be used
2014-07-01 06:52:24 +00:00
while ( ( MCG_S & MCG_S_CLKST_MASK ) ! = MCG_S_CLKST ( 3 ) ) ;
2014-02-03 00:14:57 +00:00
// now we're in PEE mode
2015-04-20 07:55:58 +00:00
# if F_CPU == 72000000
// configure USB for 48 MHz clock
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV ( 2 ) | SIM_CLKDIV2_USBFRAC ; // USB = 72 MHz PLL / 1.5
# else
2014-02-03 00:14:57 +00:00
// configure USB for 48 MHz clock
2014-07-01 06:52:24 +00:00
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV ( 1 ) ; // USB = 96 MHz PLL / 2
2015-04-20 07:55:58 +00:00
# endif
2014-07-01 06:52:24 +00:00
2014-02-03 00:14:57 +00:00
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
2014-07-01 06:52:24 +00:00
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL ( 6 ) ;
2014-02-03 00:14:57 +00:00
2014-07-01 06:52:24 +00:00
# endif
2014-08-15 17:42:12 +00:00
# if !defined(_bootloader_)
2014-07-01 06:52:24 +00:00
// Initialize the SysTick counter
2014-02-03 00:14:57 +00:00
SYST_RVR = ( F_CPU / 1000 ) - 1 ;
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE ;
2013-01-27 06:47:52 +00:00
__enable_irq ( ) ;
2014-08-15 17:42:12 +00:00
# else
// Disable Watchdog for bootloader
WDOG_STCTRLH & = ~ WDOG_STCTRLH_WDOGEN ;
# endif
2013-01-27 06:47:52 +00:00
2014-02-03 00:14:57 +00:00
main ( ) ;
2014-07-01 06:52:24 +00:00
while ( 1 ) ; // Shouldn't get here...
2013-01-27 06:47:52 +00:00
}
2014-07-01 06:52:24 +00:00
// ----- RAM Setup -----
2014-02-03 00:14:57 +00:00
char * __brkval = ( char * ) & _ebss ;
2013-01-27 06:47:52 +00:00
2014-07-01 06:52:24 +00:00
void * _sbrk ( int incr )
2013-01-27 06:47:52 +00:00
{
2014-02-03 00:14:57 +00:00
char * prev = __brkval ;
__brkval + = incr ;
2013-01-27 06:47:52 +00:00
return prev ;
}
2014-07-01 06:52:24 +00:00
// ----- Interrupt Execution Priority -----
int nvic_execution_priority ( )
2014-02-03 00:14:57 +00:00
{
2014-07-01 06:52:24 +00:00
int priority = 256 ;
2014-02-03 00:14:57 +00:00
uint32_t primask , faultmask , basepri , ipsr ;
// full algorithm in ARM DDI0403D, page B1-639
// this isn't quite complete, but hopefully good enough
2014-07-01 06:52:24 +00:00
asm volatile ( " mrs %0, faultmask \n " : " =r " ( faultmask ) : : ) ;
if ( faultmask )
{
return - 1 ;
}
asm volatile ( " mrs %0, primask \n " : " =r " ( primask ) : : ) ;
if ( primask )
{
return 0 ;
}
asm volatile ( " mrs %0, ipsr \n " : " =r " ( ipsr ) : : ) ;
if ( ipsr )
{
if ( ipsr < 16 )
{
priority = 0 ; // could be non-zero
}
else
{
priority = NVIC_GET_PRIORITY ( ipsr - 16 ) ;
}
}
asm volatile ( " mrs %0, basepri \n " : " =r " ( basepri ) : : ) ;
if ( basepri > 0 & & basepri < priority )
{
priority = basepri ;
2014-02-03 00:14:57 +00:00
}
2014-07-01 06:52:24 +00:00
2014-02-03 00:14:57 +00:00
return priority ;
}
2013-01-27 06:47:52 +00:00