mirror of https://github.com/ARMmbed/mbed-os.git
commit
53edc82f73
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x40000 { ; load region size_region (256k)
|
||||||
|
ER_IROM1 0x00000000 0x40000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||||
|
; 0x8000 - 0xC0 = 0x7F40
|
||||||
|
RW_IRAM1 0x1FFFE0C0 0x7F40 {
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,332 @@
|
||||||
|
;/*****************************************************************************
|
||||||
|
; * @file: startup_MKL46Z4.s
|
||||||
|
; * @purpose: CMSIS Cortex-M0plus Core Device Startup File for the
|
||||||
|
; * MKL46Z4
|
||||||
|
; * @version: 2.0
|
||||||
|
; * @date: 2012-12-12
|
||||||
|
; *
|
||||||
|
; * Copyright: 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||||
|
;*
|
||||||
|
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||||
|
; *
|
||||||
|
; *****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
__initial_sp EQU 0x20006000 ; Top of RAM
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
|
||||||
|
; Vector Table Mapped to Address 0 at Reset
|
||||||
|
|
||||||
|
AREA RESET, DATA, READONLY
|
||||||
|
EXPORT __Vectors
|
||||||
|
EXPORT __Vectors_End
|
||||||
|
EXPORT __Vectors_Size
|
||||||
|
|
||||||
|
__Vectors DCD __initial_sp ; Top of Stack
|
||||||
|
DCD Reset_Handler ; Reset Handler
|
||||||
|
DCD NMI_Handler ; NMI Handler
|
||||||
|
DCD HardFault_Handler ; Hard Fault Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD SVC_Handler ; SVCall Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD PendSV_Handler ; PendSV Handler
|
||||||
|
DCD SysTick_Handler ; SysTick Handler
|
||||||
|
|
||||||
|
; External Interrupts
|
||||||
|
DCD DMA0_IRQHandler ; DMA channel 0 transfer complete/error interrupt
|
||||||
|
DCD DMA1_IRQHandler ; DMA channel 1 transfer complete/error interrupt
|
||||||
|
DCD DMA2_IRQHandler ; DMA channel 2 transfer complete/error interrupt
|
||||||
|
DCD DMA3_IRQHandler ; DMA channel 3 transfer complete/error interrupt
|
||||||
|
DCD Reserved20_IRQHandler ; Reserved interrupt 20
|
||||||
|
DCD FTFA_IRQHandler ; FTFA command complete/read collision interrupt
|
||||||
|
DCD LVD_LVW_IRQHandler ; Low Voltage Detect, Low Voltage Warning
|
||||||
|
DCD LLW_IRQHandler ; Low Leakage Wakeup
|
||||||
|
DCD I2C0_IRQHandler ; I2C0 interrupt
|
||||||
|
DCD I2C1_IRQHandler ; I2C0 interrupt 25
|
||||||
|
DCD SPI0_IRQHandler ; SPI0 interrupt
|
||||||
|
DCD SPI1_IRQHandler ; SPI1 interrupt
|
||||||
|
DCD UART0_IRQHandler ; UART0 status/error interrupt
|
||||||
|
DCD UART1_IRQHandler ; UART1 status/error interrupt
|
||||||
|
DCD UART2_IRQHandler ; UART2 status/error interrupt
|
||||||
|
DCD ADC0_IRQHandler ; ADC0 interrupt
|
||||||
|
DCD CMP0_IRQHandler ; CMP0 interrupt
|
||||||
|
DCD TPM0_IRQHandler ; TPM0 fault, overflow and channels interrupt
|
||||||
|
DCD TPM1_IRQHandler ; TPM1 fault, overflow and channels interrupt
|
||||||
|
DCD TPM2_IRQHandler ; TPM2 fault, overflow and channels interrupt
|
||||||
|
DCD RTC_IRQHandler ; RTC interrupt
|
||||||
|
DCD RTC_Seconds_IRQHandler ; RTC seconds interrupt
|
||||||
|
DCD PIT_IRQHandler ; PIT timer interrupt
|
||||||
|
DCD I2S0_IRQHandler ; I2S0 transmit interrupt
|
||||||
|
DCD USB0_IRQHandler ; USB0 interrupt
|
||||||
|
DCD DAC0_IRQHandler ; DAC0 interrupt
|
||||||
|
DCD TSI0_IRQHandler ; TSI0 interrupt
|
||||||
|
DCD MCG_IRQHandler ; MCG interrupt
|
||||||
|
DCD LPTimer_IRQHandler ; LPTimer interrupt
|
||||||
|
DCD LCD_IRQHandler ; Segment LCD Interrupt
|
||||||
|
DCD PORTA_IRQHandler ; Port A interrupt
|
||||||
|
DCD PORTD_IRQHandler ; Port D interrupt
|
||||||
|
__Vectors_End
|
||||||
|
|
||||||
|
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||||
|
|
||||||
|
; <h> Flash Configuration
|
||||||
|
; <i> 16-byte flash configuration field that stores default protection settings (loaded on reset)
|
||||||
|
; <i> and security information that allows the MCU to restrict acces to the FTFL module.
|
||||||
|
; <h> Backdoor Comparison Key
|
||||||
|
; <o0> Backdoor Key 0 <0x0-0xFF:2>
|
||||||
|
; <o1> Backdoor Key 1 <0x0-0xFF:2>
|
||||||
|
; <o2> Backdoor Key 2 <0x0-0xFF:2>
|
||||||
|
; <o3> Backdoor Key 3 <0x0-0xFF:2>
|
||||||
|
; <o4> Backdoor Key 4 <0x0-0xFF:2>
|
||||||
|
; <o5> Backdoor Key 5 <0x0-0xFF:2>
|
||||||
|
; <o6> Backdoor Key 6 <0x0-0xFF:2>
|
||||||
|
; <o7> Backdoor Key 7 <0x0-0xFF:2>
|
||||||
|
BackDoorK0 EQU 0xFF
|
||||||
|
BackDoorK1 EQU 0xFF
|
||||||
|
BackDoorK2 EQU 0xFF
|
||||||
|
BackDoorK3 EQU 0xFF
|
||||||
|
BackDoorK4 EQU 0xFF
|
||||||
|
BackDoorK5 EQU 0xFF
|
||||||
|
BackDoorK6 EQU 0xFF
|
||||||
|
BackDoorK7 EQU 0xFF
|
||||||
|
; </h>
|
||||||
|
; <h> Program flash protection bytes (FPROT)
|
||||||
|
; <i> Each program flash region can be protected from program and erase operation by setting the associated PROT bit.
|
||||||
|
; <i> Each bit protects a 1/32 region of the program flash memory.
|
||||||
|
; <h> FPROT0
|
||||||
|
; <i> Program flash protection bytes
|
||||||
|
; <i> 1/32 - 8/32 region
|
||||||
|
; <o.0> FPROT0.0
|
||||||
|
; <o.1> FPROT0.1
|
||||||
|
; <o.2> FPROT0.2
|
||||||
|
; <o.3> FPROT0.3
|
||||||
|
; <o.4> FPROT0.4
|
||||||
|
; <o.5> FPROT0.5
|
||||||
|
; <o.6> FPROT0.6
|
||||||
|
; <o.7> FPROT0.7
|
||||||
|
nFPROT0 EQU 0x00
|
||||||
|
FPROT0 EQU nFPROT0:EOR:0xFF
|
||||||
|
; </h>
|
||||||
|
; <h> FPROT1
|
||||||
|
; <i> Program Flash Region Protect Register 1
|
||||||
|
; <i> 9/32 - 16/32 region
|
||||||
|
; <o.0> FPROT1.0
|
||||||
|
; <o.1> FPROT1.1
|
||||||
|
; <o.2> FPROT1.2
|
||||||
|
; <o.3> FPROT1.3
|
||||||
|
; <o.4> FPROT1.4
|
||||||
|
; <o.5> FPROT1.5
|
||||||
|
; <o.6> FPROT1.6
|
||||||
|
; <o.7> FPROT1.7
|
||||||
|
nFPROT1 EQU 0x00
|
||||||
|
FPROT1 EQU nFPROT1:EOR:0xFF
|
||||||
|
; </h>
|
||||||
|
; <h> FPROT2
|
||||||
|
; <i> Program Flash Region Protect Register 2
|
||||||
|
; <i> 17/32 - 24/32 region
|
||||||
|
; <o.0> FPROT2.0
|
||||||
|
; <o.1> FPROT2.1
|
||||||
|
; <o.2> FPROT2.2
|
||||||
|
; <o.3> FPROT2.3
|
||||||
|
; <o.4> FPROT2.4
|
||||||
|
; <o.5> FPROT2.5
|
||||||
|
; <o.6> FPROT2.6
|
||||||
|
; <o.7> FPROT2.7
|
||||||
|
nFPROT2 EQU 0x00
|
||||||
|
FPROT2 EQU nFPROT2:EOR:0xFF
|
||||||
|
; </h>
|
||||||
|
; <h> FPROT3
|
||||||
|
; <i> Program Flash Region Protect Register 3
|
||||||
|
; <i> 25/32 - 32/32 region
|
||||||
|
; <o.0> FPROT3.0
|
||||||
|
; <o.1> FPROT3.1
|
||||||
|
; <o.2> FPROT3.2
|
||||||
|
; <o.3> FPROT3.3
|
||||||
|
; <o.4> FPROT3.4
|
||||||
|
; <o.5> FPROT3.5
|
||||||
|
; <o.6> FPROT3.6
|
||||||
|
; <o.7> FPROT3.7
|
||||||
|
nFPROT3 EQU 0x00
|
||||||
|
FPROT3 EQU nFPROT3:EOR:0xFF
|
||||||
|
; </h>
|
||||||
|
; </h>
|
||||||
|
; </h>
|
||||||
|
; <h> Flash nonvolatile option byte (FOPT)
|
||||||
|
; <i> Allows the user to customize the operation of the MCU at boot time.
|
||||||
|
; <o.0> LPBOOT0
|
||||||
|
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) or 0x3 (divide by 4)
|
||||||
|
; <1=> Core and system clock divider (OUTDIV1) is 0x1 (divide by 2) or 0x0 (divide by 1)
|
||||||
|
; <o.4> LPBOOT1
|
||||||
|
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) or 0x1 (divide by 2)
|
||||||
|
; <1=> Core and system clock divider (OUTDIV1) is 0x3 (divide by 4) or 0x0 (divide by 1)
|
||||||
|
; <o.2> NMI_DIS
|
||||||
|
; <0=> NMI interrupts are always blocked
|
||||||
|
; <1=> NMI pin/interrupts reset default to enabled
|
||||||
|
; <o.3> RESET_PIN_CFG
|
||||||
|
; <0=> RESET pin is disabled following a POR and cannot be enabled as RESET function
|
||||||
|
; <1=> RESET pin is dedicated
|
||||||
|
; <o.3> FAST_INIT
|
||||||
|
; <0=> Slower initialization
|
||||||
|
; <1=> Fast Initialization
|
||||||
|
FOPT EQU 0xFF
|
||||||
|
; </h>
|
||||||
|
; <h> Flash security byte (FSEC)
|
||||||
|
; <i> WARNING: If SEC field is configured as "MCU security status is secure" and MEEN field is configured as "Mass erase is disabled",
|
||||||
|
; <i> MCU's security status cannot be set back to unsecure state since Mass erase via the debugger is blocked !!!
|
||||||
|
; <o.0..1> SEC
|
||||||
|
; <2=> MCU security status is unsecure
|
||||||
|
; <3=> MCU security status is secure
|
||||||
|
; <i> Flash Security
|
||||||
|
; <i> This bits define the security state of the MCU.
|
||||||
|
; <o.2..3> FSLACC
|
||||||
|
; <2=> Freescale factory access denied
|
||||||
|
; <3=> Freescale factory access granted
|
||||||
|
; <i> Freescale Failure Analysis Access Code
|
||||||
|
; <i> This bits define the security state of the MCU.
|
||||||
|
; <o.4..5> MEEN
|
||||||
|
; <2=> Mass erase is disabled
|
||||||
|
; <3=> Mass erase is enabled
|
||||||
|
; <i> Mass Erase Enable Bits
|
||||||
|
; <i> Enables and disables mass erase capability of the FTFL module
|
||||||
|
; <o.6..7> KEYEN
|
||||||
|
; <2=> Backdoor key access enabled
|
||||||
|
; <3=> Backdoor key access disabled
|
||||||
|
; <i> Backdoor key Security Enable
|
||||||
|
; <i> These bits enable and disable backdoor key access to the FTFL module.
|
||||||
|
FSEC EQU 0xFE
|
||||||
|
; </h>
|
||||||
|
|
||||||
|
IF :LNOT::DEF:RAM_TARGET
|
||||||
|
AREA |.ARM.__at_0x400|, CODE, READONLY
|
||||||
|
DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3
|
||||||
|
DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7
|
||||||
|
DCB FPROT0, FPROT1, FPROT2, FPROT3
|
||||||
|
DCB FSEC, FOPT, 0xFF, 0xFF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Handler
|
||||||
|
|
||||||
|
Reset_Handler PROC
|
||||||
|
EXPORT Reset_Handler [WEAK]
|
||||||
|
IMPORT SystemInit
|
||||||
|
IMPORT __main
|
||||||
|
LDR R0, =SystemInit
|
||||||
|
BLX R0
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
|
||||||
|
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||||
|
|
||||||
|
NMI_Handler PROC
|
||||||
|
EXPORT NMI_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
HardFault_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT HardFault_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
SVC_Handler PROC
|
||||||
|
EXPORT SVC_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
PendSV_Handler PROC
|
||||||
|
EXPORT PendSV_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
SysTick_Handler PROC
|
||||||
|
EXPORT SysTick_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
Default_Handler PROC
|
||||||
|
EXPORT DMA0_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA3_IRQHandler [WEAK]
|
||||||
|
EXPORT Reserved20_IRQHandler [WEAK]
|
||||||
|
EXPORT FTFA_IRQHandler [WEAK]
|
||||||
|
EXPORT LVD_LVW_IRQHandler [WEAK]
|
||||||
|
EXPORT LLW_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C0_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C1_IRQHandler [WEAK]
|
||||||
|
EXPORT SPI0_IRQHandler [WEAK]
|
||||||
|
EXPORT SPI1_IRQHandler [WEAK]
|
||||||
|
EXPORT UART0_IRQHandler [WEAK]
|
||||||
|
EXPORT UART1_IRQHandler [WEAK]
|
||||||
|
EXPORT UART2_IRQHandler [WEAK]
|
||||||
|
EXPORT ADC0_IRQHandler [WEAK]
|
||||||
|
EXPORT CMP0_IRQHandler [WEAK]
|
||||||
|
EXPORT TPM0_IRQHandler [WEAK]
|
||||||
|
EXPORT TPM1_IRQHandler [WEAK]
|
||||||
|
EXPORT TPM2_IRQHandler [WEAK]
|
||||||
|
EXPORT RTC_IRQHandler [WEAK]
|
||||||
|
EXPORT RTC_Seconds_IRQHandler [WEAK]
|
||||||
|
EXPORT PIT_IRQHandler [WEAK]
|
||||||
|
EXPORT I2S0_IRQHandler [WEAK]
|
||||||
|
EXPORT USB0_IRQHandler [WEAK]
|
||||||
|
EXPORT DAC0_IRQHandler [WEAK]
|
||||||
|
EXPORT TSI0_IRQHandler [WEAK]
|
||||||
|
EXPORT MCG_IRQHandler [WEAK]
|
||||||
|
EXPORT LPTimer_IRQHandler [WEAK]
|
||||||
|
EXPORT LCD_IRQHandler [WEAK]
|
||||||
|
EXPORT PORTA_IRQHandler [WEAK]
|
||||||
|
EXPORT PORTD_IRQHandler [WEAK]
|
||||||
|
EXPORT DefaultISR [WEAK]
|
||||||
|
|
||||||
|
DMA0_IRQHandler
|
||||||
|
DMA1_IRQHandler
|
||||||
|
DMA2_IRQHandler
|
||||||
|
DMA3_IRQHandler
|
||||||
|
Reserved20_IRQHandler
|
||||||
|
FTFA_IRQHandler
|
||||||
|
LVD_LVW_IRQHandler
|
||||||
|
LLW_IRQHandler
|
||||||
|
I2C0_IRQHandler
|
||||||
|
I2C1_IRQHandler
|
||||||
|
SPI0_IRQHandler
|
||||||
|
SPI1_IRQHandler
|
||||||
|
UART0_IRQHandler
|
||||||
|
UART1_IRQHandler
|
||||||
|
UART2_IRQHandler
|
||||||
|
ADC0_IRQHandler
|
||||||
|
CMP0_IRQHandler
|
||||||
|
TPM0_IRQHandler
|
||||||
|
TPM1_IRQHandler
|
||||||
|
TPM2_IRQHandler
|
||||||
|
RTC_IRQHandler
|
||||||
|
RTC_Seconds_IRQHandler
|
||||||
|
PIT_IRQHandler
|
||||||
|
I2S0_IRQHandler
|
||||||
|
USB0_IRQHandler
|
||||||
|
DAC0_IRQHandler
|
||||||
|
TSI0_IRQHandler
|
||||||
|
MCG_IRQHandler
|
||||||
|
LPTimer_IRQHandler
|
||||||
|
LCD_IRQHandler
|
||||||
|
PORTA_IRQHandler
|
||||||
|
PORTD_IRQHandler
|
||||||
|
DefaultISR
|
||||||
|
|
||||||
|
B .
|
||||||
|
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
|
||||||
|
ALIGN
|
||||||
|
END
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* mbed Microcontroller Library - stackheap
|
||||||
|
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* Setup a fixed single stack/heap memory model,
|
||||||
|
* between the top of the RW/ZI region and the stackpointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <rt_misc.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern char Image$$RW_IRAM1$$ZI$$Limit[];
|
||||||
|
|
||||||
|
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
||||||
|
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
|
||||||
|
uint32_t sp_limit = __current_sp();
|
||||||
|
|
||||||
|
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
|
||||||
|
|
||||||
|
struct __initial_stackheap r;
|
||||||
|
r.heap_base = zi_limit;
|
||||||
|
r.heap_limit = sp_limit;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,13 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* KL25Z ARM GCC linker script file
|
* KL46Z ARM GCC linker script file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
|
VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
|
||||||
FLASH_PROTECTION (rx) : ORIGIN = 0x00000400, LENGTH = 0x00000010
|
FLASH_PROTECTION (rx) : ORIGIN = 0x00000400, LENGTH = 0x00000010
|
||||||
FLASH (rx) : ORIGIN = 0x00000410, LENGTH = 256K - 0x00000410
|
FLASH (rx) : ORIGIN = 0x00000410, LENGTH = 256K - 0x00000410
|
||||||
RAM (rwx) : ORIGIN = 0x1FFFE000, LENGTH = 32K
|
RAM (rwx) : ORIGIN = 0x1FFFE0C0, LENGTH = 32K - 0xC0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linker script to place sections and symbol values. Should be used together
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* CMSIS-style functionality to support dynamic vectors
|
* CMSIS-style functionality to support dynamic vectors
|
||||||
*/
|
*/
|
||||||
#include "cmsis_nvic.h"
|
#include "cmsis_nvic.h"
|
||||||
|
|
||||||
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFF000) // Vectors positioned at start of RAM
|
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000) // Vectors positioned at start of RAM
|
||||||
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
|
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
|
||||||
|
|
||||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
|
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
#define DISABLE_WDOG 1
|
#define DISABLE_WDOG 1
|
||||||
|
|
||||||
#define CLOCK_SETUP 0
|
#define CLOCK_SETUP 1
|
||||||
/* Predefined clock setups
|
/* Predefined clock setups
|
||||||
0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode
|
0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode
|
||||||
Reference clock source for MCG module is the slow internal clock source 32.768kHz
|
Reference clock source for MCG module is the slow internal clock source 32.768kHz
|
||||||
|
|
|
@ -193,13 +193,10 @@ typedef enum {
|
||||||
|
|
||||||
LED_RED = PTE29,
|
LED_RED = PTE29,
|
||||||
LED_GREEN = PTD5,
|
LED_GREEN = PTD5,
|
||||||
LED_BLUE = PTD5,
|
|
||||||
|
|
||||||
// mbed original LED naming
|
// mbed original LED naming
|
||||||
LED1 = LED_GREEN,
|
LED1 = LED_GREEN,
|
||||||
LED2 = LED_RED,
|
LED2 = LED_RED,
|
||||||
LED3 = LED_GREEN,
|
|
||||||
LED4 = LED_RED,
|
|
||||||
|
|
||||||
// USB Pins
|
// USB Pins
|
||||||
USBTX = PTA2,
|
USBTX = PTA2,
|
||||||
|
@ -223,18 +220,18 @@ typedef enum {
|
||||||
D14 = PTE0,
|
D14 = PTE0,
|
||||||
D15 = PTE1,
|
D15 = PTE1,
|
||||||
|
|
||||||
A0 = PTC1,
|
A0 = PTB0,
|
||||||
A1 = PTC2,
|
A1 = PTB1,
|
||||||
A2 = PTB3,
|
A2 = PTB2,
|
||||||
A3 = PTB2,
|
A3 = PTB3,
|
||||||
A4 = PTB1,
|
A4 = PTC2,
|
||||||
A5 = PTB0,
|
A5 = PTC1,
|
||||||
|
|
||||||
// Not connected
|
// Not connected
|
||||||
NC = (int)0xFFFFFFFF
|
NC = (int)0xFFFFFFFF
|
||||||
} PinName;
|
} PinName;
|
||||||
|
|
||||||
/* PullDown not available for KL25 */
|
/* PullDown not available for KL46 */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PullNone = 0,
|
PullNone = 0,
|
||||||
PullUp = 2,
|
PullUp = 2,
|
||||||
|
|
|
@ -20,29 +20,29 @@
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
static const PinMap PinMap_PWM[] = {
|
static const PinMap PinMap_PWM[] = {
|
||||||
// LEDs
|
// LEDs - only RED pin is PWM capable
|
||||||
{LED_RED , PWM_9 , 3}, // PTB18, TPM2 CH0
|
{LED_RED, PWM_3, 3}, // PTE29, TPM0 CH2
|
||||||
{LED_GREEN, PWM_10, 3}, // PTB19, TPM2 CH1
|
|
||||||
{LED_BLUE , PWM_2 , 4}, // PTD1 , TPM0 CH1
|
|
||||||
|
|
||||||
// Arduino digital pinout
|
// Arduino digital pinout
|
||||||
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
|
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
|
||||||
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
|
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
|
||||||
{D2, PWM_5 , 4}, // PTD4 , TPM0 CH4
|
{D2, PWM_4 , 4}, // PTD3 , TPM0 CH3
|
||||||
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
|
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
|
||||||
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
|
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
|
||||||
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
|
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
|
||||||
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
|
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
|
||||||
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
|
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
|
||||||
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
|
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
|
||||||
{D9, PWM_6 , 4}, // PTD5 , TPM0 CH5
|
{D9, PWM_3 , 4}, // PTD2 , TPM0 CH2
|
||||||
{D10, PWM_1 , 4}, // PTD0 , TPM0 CH0
|
{D10, PWM_5 , 4}, // PTD4 , TPM0 CH4
|
||||||
{D11, PWM_3 , 4}, // PTD2 , TPM0 CH2
|
//PWM on D11 not available
|
||||||
{D12, PWM_4 , 4}, // PTD3 , TPM0 CH3
|
//PWM on D12 not available
|
||||||
{D13, PWM_2 , 4}, // PTD1 , TPM0 CH1,
|
{D13, PWM_2 , 4}, // PTD5 , TPM0 CH1,
|
||||||
|
|
||||||
{PTA0, PWM_6, 3},
|
{PTA0, PWM_6, 3},
|
||||||
{PTA3, PWM_1, 3},
|
{PTA3, PWM_1, 3},
|
||||||
|
{PTA6, PWM_4, 3},
|
||||||
|
{PTA7, PWM_5, 3},
|
||||||
{PTB0, PWM_7, 3},
|
{PTB0, PWM_7, 3},
|
||||||
{PTB1, PWM_8, 3},
|
{PTB1, PWM_8, 3},
|
||||||
{PTB2, PWM_9, 3},
|
{PTB2, PWM_9, 3},
|
||||||
|
@ -57,6 +57,7 @@ static const PinMap PinMap_PWM[] = {
|
||||||
{PTE23, PWM_10, 3},
|
{PTE23, PWM_10, 3},
|
||||||
{PTE24, PWM_1, 3},
|
{PTE24, PWM_1, 3},
|
||||||
{PTE25, PWM_2, 3},
|
{PTE25, PWM_2, 3},
|
||||||
|
{PTE26, PWM_6, 3},
|
||||||
{PTE29, PWM_3, 3},
|
{PTE29, PWM_3, 3},
|
||||||
{PTE30, PWM_4, 3},
|
{PTE30, PWM_4, 3},
|
||||||
{PTE31, PWM_5, 3},
|
{PTE31, PWM_5, 3},
|
||||||
|
|
|
@ -24,7 +24,7 @@ static void init(void) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* configure PTC1 with alternate function 1: RTC_CLKIN
|
* configure PTC1 with alternate function 1: RTC_CLKIN
|
||||||
* As the kl25z board does not have a 32kHz osc,
|
* As the KL46Z board does not have a 32kHz osc,
|
||||||
* we use an external clock generated by the
|
* we use an external clock generated by the
|
||||||
* interface chip
|
* interface chip
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,26 +28,30 @@
|
||||||
* INITIALIZATION
|
* INITIALIZATION
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static const PinMap PinMap_UART_TX[] = {
|
static const PinMap PinMap_UART_TX[] = {
|
||||||
{PTC4, UART_1, 3},
|
|
||||||
{PTA2, UART_0, 2},
|
{PTA2, UART_0, 2},
|
||||||
{PTD5, UART_2, 3},
|
{PTA14, UART_0, 3},
|
||||||
|
{PTC4, UART_1, 3},
|
||||||
{PTD3, UART_2, 3},
|
{PTD3, UART_2, 3},
|
||||||
|
{PTD5, UART_2, 3},
|
||||||
{PTD7, UART_0, 3},
|
{PTD7, UART_0, 3},
|
||||||
|
{PTE0, UART_1, 3},
|
||||||
|
{PTE16, UART_2, 3},
|
||||||
{PTE20, UART_0, 4},
|
{PTE20, UART_0, 4},
|
||||||
{PTE22, UART_2, 4},
|
{PTE22, UART_2, 4},
|
||||||
{PTE0, UART_1, 3},
|
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const PinMap PinMap_UART_RX[] = {
|
static const PinMap PinMap_UART_RX[] = {
|
||||||
{PTC3, UART_1, 3},
|
|
||||||
{PTA1, UART_0, 2},
|
{PTA1, UART_0, 2},
|
||||||
{PTD4, UART_2, 3},
|
{PTA15, UART_0, 3},
|
||||||
|
{PTC3, UART_1, 3},
|
||||||
{PTD2, UART_2, 3},
|
{PTD2, UART_2, 3},
|
||||||
|
{PTD4, UART_2, 3},
|
||||||
{PTD6, UART_0, 3},
|
{PTD6, UART_0, 3},
|
||||||
{PTE23, UART_2, 4},
|
|
||||||
{PTE21, UART_0, 4},
|
|
||||||
{PTE1, UART_1, 3},
|
{PTE1, UART_1, 3},
|
||||||
|
{PTE17, UART_2, 3},
|
||||||
|
{PTE21, UART_0, 4},
|
||||||
|
{PTE23, UART_2, 4},
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +81,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||||
}
|
}
|
||||||
// Disable UART before changing registers
|
// Disable UART before changing registers
|
||||||
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
||||||
|
|
||||||
switch (uart) {
|
switch (uart) {
|
||||||
case UART_0: obj->index = 0; break;
|
case UART_0: obj->index = 0; break;
|
||||||
case UART_1: obj->index = 1; break;
|
case UART_1: obj->index = 1; break;
|
||||||
|
@ -122,13 +126,13 @@ void serial_free(serial_t *obj) {
|
||||||
// DivAddVal < MulVal
|
// DivAddVal < MulVal
|
||||||
//
|
//
|
||||||
void serial_baud(serial_t *obj, int baudrate) {
|
void serial_baud(serial_t *obj, int baudrate) {
|
||||||
|
|
||||||
// save C2 state
|
// save C2 state
|
||||||
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
|
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
|
||||||
|
|
||||||
// Disable UART before changing registers
|
// Disable UART before changing registers
|
||||||
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
||||||
|
|
||||||
// [TODO] not hardcode this value
|
// [TODO] not hardcode this value
|
||||||
uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u;
|
uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u;
|
||||||
|
|
||||||
|
@ -143,20 +147,20 @@ void serial_baud(serial_t *obj, int baudrate) {
|
||||||
// set BDH and BDL
|
// set BDH and BDL
|
||||||
obj->uart->BDH = (obj->uart->BDH & ~(0x1f)) | ((DL >> 8) & 0x1f);
|
obj->uart->BDH = (obj->uart->BDH & ~(0x1f)) | ((DL >> 8) & 0x1f);
|
||||||
obj->uart->BDL = (obj->uart->BDL & ~(0xff)) | ((DL >> 0) & 0xff);
|
obj->uart->BDL = (obj->uart->BDL & ~(0xff)) | ((DL >> 0) & 0xff);
|
||||||
|
|
||||||
// restore C2 state
|
// restore C2 state
|
||||||
obj->uart->C2 |= c2_state;
|
obj->uart->C2 |= c2_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||||
uint8_t m10 = 0;
|
uint8_t m10 = 0;
|
||||||
|
|
||||||
// save C2 state
|
// save C2 state
|
||||||
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
|
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
|
||||||
|
|
||||||
// Disable UART before changing registers
|
// Disable UART before changing registers
|
||||||
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
|
||||||
|
|
||||||
// 8 data bits = 0 ... 9 data bits = 1
|
// 8 data bits = 0 ... 9 data bits = 1
|
||||||
if ((data_bits < 8) || (data_bits > 9)) {
|
if ((data_bits < 8) || (data_bits > 9)) {
|
||||||
error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
|
error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
|
||||||
|
@ -178,7 +182,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
||||||
error("Invalid stop bits specified\r\n");
|
error("Invalid stop bits specified\r\n");
|
||||||
}
|
}
|
||||||
stop_bits -= 1;
|
stop_bits -= 1;
|
||||||
|
|
||||||
// 9 data bits + parity
|
// 9 data bits + parity
|
||||||
if (data_bits == 2) {
|
if (data_bits == 2) {
|
||||||
// only uart0 supports 10 bit communication
|
// only uart0 supports 10 bit communication
|
||||||
|
@ -193,17 +197,17 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
||||||
obj->uart->C1 = ((data_bits << 4)
|
obj->uart->C1 = ((data_bits << 4)
|
||||||
| (parity_enable << 1)
|
| (parity_enable << 1)
|
||||||
| (parity_select << 0));
|
| (parity_select << 0));
|
||||||
|
|
||||||
// enable 10bit mode if needed
|
// enable 10bit mode if needed
|
||||||
if (obj->index == 0) {
|
if (obj->index == 0) {
|
||||||
obj->uart->C4 &= ~UARTLP_C4_M10_MASK;
|
obj->uart->C4 &= ~UARTLP_C4_M10_MASK;
|
||||||
obj->uart->C4 |= (m10 << UARTLP_C4_M10_SHIFT);
|
obj->uart->C4 |= (m10 << UARTLP_C4_M10_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop bits
|
// stop bits
|
||||||
obj->uart->BDH &= ~UART_BDH_SBNS_MASK;
|
obj->uart->BDH &= ~UART_BDH_SBNS_MASK;
|
||||||
obj->uart->BDH |= (stop_bits << UART_BDH_SBNS_SHIFT);
|
obj->uart->BDH |= (stop_bits << UART_BDH_SBNS_SHIFT);
|
||||||
|
|
||||||
// restore C2 state
|
// restore C2 state
|
||||||
obj->uart->C2 |= c2_state;
|
obj->uart->C2 |= c2_state;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +308,7 @@ void serial_pinout_tx(PinName tx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_break_set(serial_t *obj) {
|
void serial_break_set(serial_t *obj) {
|
||||||
obj->uart->C2 |= UART_C2_SBK_MASK;
|
obj->uart->C2 |= UART_C2_SBK_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_break_clear(serial_t *obj) {
|
void serial_break_clear(serial_t *obj) {
|
||||||
|
|
|
@ -23,11 +23,13 @@
|
||||||
|
|
||||||
static const PinMap PinMap_SPI_SCLK[] = {
|
static const PinMap PinMap_SPI_SCLK[] = {
|
||||||
{PTA15, SPI_0, 2},
|
{PTA15, SPI_0, 2},
|
||||||
|
{PTB9, SPI_1, 2},
|
||||||
{PTB11, SPI_1, 2},
|
{PTB11, SPI_1, 2},
|
||||||
{PTC5, SPI_0, 2},
|
{PTC5, SPI_0, 2},
|
||||||
{PTD1, SPI_0, 2},
|
{PTD1, SPI_0, 2},
|
||||||
{PTD5, SPI_1, 2},
|
{PTD5, SPI_1, 2},
|
||||||
{PTE2, SPI_1, 2},
|
{PTE2, SPI_1, 2},
|
||||||
|
{PTE17, SPI_0, 2},
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,6 +46,8 @@ static const PinMap PinMap_SPI_MOSI[] = {
|
||||||
{PTD7, SPI_1, 5},
|
{PTD7, SPI_1, 5},
|
||||||
{PTE1, SPI_1, 2},
|
{PTE1, SPI_1, 2},
|
||||||
{PTE3, SPI_1, 5},
|
{PTE3, SPI_1, 5},
|
||||||
|
{PTE18, SPI_0, 2},
|
||||||
|
{PTE19, SPI_0, 5},
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,6 +64,8 @@ static const PinMap PinMap_SPI_MISO[] = {
|
||||||
{PTD7, SPI_1, 2},
|
{PTD7, SPI_1, 2},
|
||||||
{PTE1, SPI_1, 5},
|
{PTE1, SPI_1, 5},
|
||||||
{PTE3, SPI_1, 2},
|
{PTE3, SPI_1, 2},
|
||||||
|
{PTE18, SPI_0, 5},
|
||||||
|
{PTE19, SPI_0, 2},
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +76,7 @@ static const PinMap PinMap_SPI_SSEL[] = {
|
||||||
{PTD0, SPI_0, 2},
|
{PTD0, SPI_0, 2},
|
||||||
{PTD4, SPI_1, 2},
|
{PTD4, SPI_1, 2},
|
||||||
{PTE4, SPI_1, 2},
|
{PTE4, SPI_1, 2},
|
||||||
|
{PTE16, SPI_0, 2},
|
||||||
{NC , NC , 0}
|
{NC , NC , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ AnalogOut out(PTE30);
|
||||||
AnalogIn in(PTB11); // D9
|
AnalogIn in(PTB11); // D9
|
||||||
AnalogOut out(PTB1); // D1
|
AnalogOut out(PTB1); // D1
|
||||||
|
|
||||||
|
#elif defined(TARGET_KL46Z)
|
||||||
|
AnalogIn in(PTB0);
|
||||||
|
AnalogOut out(PTE30);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
AnalogIn in(p17);
|
AnalogIn in(p17);
|
||||||
AnalogOut out(p18);
|
AnalogOut out(p18);
|
||||||
|
|
|
@ -7,6 +7,9 @@ DigitalOut cs(PTA13);
|
||||||
#elif defined(TARGET_KL05Z)
|
#elif defined(TARGET_KL05Z)
|
||||||
SPI spi(PTA7, PTA6, PTB0); // mosi, miso, sclk
|
SPI spi(PTA7, PTA6, PTB0); // mosi, miso, sclk
|
||||||
DigitalOut cs(PTB1);
|
DigitalOut cs(PTB1);
|
||||||
|
#elif defined(TARGET_KL46Z)
|
||||||
|
SPI spi(PTD2, PTD3, PTD1); // mosi, miso, sclk
|
||||||
|
DigitalOut cs(PTA13);
|
||||||
#else
|
#else
|
||||||
SPI spi(p5, p6, p7); // mosi, miso, sclk
|
SPI spi(p5, p6, p7); // mosi, miso, sclk
|
||||||
DigitalOut cs(p8);
|
DigitalOut cs(p8);
|
||||||
|
|
|
@ -17,6 +17,8 @@ Ticker flipper_2;
|
||||||
# define LED_NAME LED2
|
# define LED_NAME LED2
|
||||||
#elif defined(TARGET_KL05Z)
|
#elif defined(TARGET_KL05Z)
|
||||||
# define LED_NAME LED2
|
# define LED_NAME LED2
|
||||||
|
#elif defined(TARGET_KL46Z)
|
||||||
|
# define LED_NAME LED2
|
||||||
#else
|
#else
|
||||||
# define LED_NAME PTE31
|
# define LED_NAME PTE31
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,10 @@ DigitalOut out(D10);
|
||||||
#elif TARGET_KL05Z
|
#elif TARGET_KL05Z
|
||||||
DigitalOut out(PTB1);
|
DigitalOut out(PTB1);
|
||||||
|
|
||||||
|
#elif TARGET_KL46Z
|
||||||
|
DigitalOut out(PTA1);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
DigitalOut out(p5);
|
DigitalOut out(p5);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,9 @@ DigitalOut out(PTD4);
|
||||||
#elif TARGET_KL05Z
|
#elif TARGET_KL05Z
|
||||||
DigitalOut out(PTB1);
|
DigitalOut out(PTB1);
|
||||||
|
|
||||||
|
#elif TARGET_KL46Z
|
||||||
|
DigitalOut out(PTA1);
|
||||||
|
|
||||||
#elif TARGET_LPC812
|
#elif TARGET_LPC812
|
||||||
DigitalOut out(D10);
|
DigitalOut out(D10);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ DigitalOut out(PTA1);
|
||||||
#elif TARGET_KL05Z
|
#elif TARGET_KL05Z
|
||||||
DigitalOut out(PTB1);
|
DigitalOut out(PTB1);
|
||||||
|
|
||||||
|
#elif TARGET_KL46Z
|
||||||
|
DigitalOut out(PTA1);
|
||||||
|
|
||||||
#elif defined(TARGET_LPC812)
|
#elif defined(TARGET_LPC812)
|
||||||
DigitalOut out(P0_12);
|
DigitalOut out(P0_12);
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,9 @@ class KL46Z(Target):
|
||||||
self.core = "Cortex-M0+"
|
self.core = "Cortex-M0+"
|
||||||
|
|
||||||
self.extra_labels = ['Freescale']
|
self.extra_labels = ['Freescale']
|
||||||
|
|
||||||
self.supported_toolchains = ["GCC_ARM"]
|
self.supported_toolchains = ["GCC_ARM", "ARM"]
|
||||||
|
|
||||||
self.is_disk_virtual = True
|
self.is_disk_virtual = True
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue