[KINETIS] Initial support for KL25 family
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7110 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
ef7990a192
commit
800bd88d35
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KL25Z128 memory setup.
|
||||||
|
*/
|
||||||
|
__main_stack_size__ = 0x0400;
|
||||||
|
__process_stack_size__ = 0x0400;
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
flash0 : org = 0x00000000, len = 0xc0
|
||||||
|
flashcfg : org = 0x00000400, len = 0x10
|
||||||
|
flash : org = 0x00000410, len = 128k - 0x410
|
||||||
|
ram : org = 0x1FFFF000, len = 16k
|
||||||
|
}
|
||||||
|
|
||||||
|
__ram_start__ = ORIGIN(ram);
|
||||||
|
__ram_size__ = LENGTH(ram);
|
||||||
|
__ram_end__ = __ram_start__ + __ram_size__;
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0;
|
||||||
|
|
||||||
|
.isr : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(vectors))
|
||||||
|
} > flash0
|
||||||
|
|
||||||
|
.cfmprotect : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.cfmconfig))
|
||||||
|
} > flashcfg
|
||||||
|
|
||||||
|
_text = .;
|
||||||
|
|
||||||
|
constructors : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
PROVIDE(__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE(__init_array_end = .);
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
destructors : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
PROVIDE(__fini_array_start = .);
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
PROVIDE(__fini_array_end = .);
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.text : ALIGN(4) SUBALIGN(4)
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.gcc*)
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.ARM.exidx : {
|
||||||
|
PROVIDE(__exidx_start = .);
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
PROVIDE(__exidx_end = .);
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.eh_frame_hdr :
|
||||||
|
{
|
||||||
|
*(.eh_frame_hdr)
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.eh_frame : ONLY_IF_RO
|
||||||
|
{
|
||||||
|
*(.eh_frame)
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
.textalign : ONLY_IF_RO
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
} > flash
|
||||||
|
|
||||||
|
_etext = .;
|
||||||
|
_textdata = _etext;
|
||||||
|
|
||||||
|
.stacks :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
__main_stack_base__ = .;
|
||||||
|
. += __main_stack_size__;
|
||||||
|
. = ALIGN(8);
|
||||||
|
__main_stack_end__ = .;
|
||||||
|
__process_stack_base__ = .;
|
||||||
|
__main_thread_stack_base__ = .;
|
||||||
|
. += __process_stack_size__;
|
||||||
|
. = ALIGN(8);
|
||||||
|
__process_stack_end__ = .;
|
||||||
|
__main_thread_stack_end__ = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
*(.data)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.ramtext)
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_edata = .);
|
||||||
|
} > ram AT > flash
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_bss_start = .);
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.bss.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_bss_end = .);
|
||||||
|
} > ram
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDE(end = .);
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
__heap_base__ = _end;
|
||||||
|
__heap_end__ = __ram_end__;
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file GCC/ARMCMx/KL2x/cmparams.h
|
||||||
|
* @brief ARM Cortex-M0+ parameters for the Kinetis KL2x.
|
||||||
|
*
|
||||||
|
* @defgroup ARMCMx_KL2x Kinetis KL2x Specific Parameters
|
||||||
|
* @ingroup ARMCMx_SPECIFIC
|
||||||
|
* @details This file contains the Cortex-M0+ specific parameters for the
|
||||||
|
* Kinetis KL2x platform.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CMPARAMS_H_
|
||||||
|
#define _CMPARAMS_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cortex core model.
|
||||||
|
*/
|
||||||
|
#define CORTEX_MODEL CORTEX_M0PLUS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Systick unit presence.
|
||||||
|
*/
|
||||||
|
#define CORTEX_HAS_ST TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Memory Protection unit presence.
|
||||||
|
*/
|
||||||
|
#define CORTEX_HAS_MPU FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Floating Point unit presence.
|
||||||
|
*/
|
||||||
|
#define CORTEX_HAS_FPU FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of bits in priority masks.
|
||||||
|
*/
|
||||||
|
#define CORTEX_PRIORITY_BITS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of interrupt vectors.
|
||||||
|
* @note This number does not include the 16 system vectors and must be
|
||||||
|
* rounded to a multiple of 8.
|
||||||
|
*/
|
||||||
|
#define CORTEX_NUM_VECTORS 32
|
||||||
|
|
||||||
|
/* The following code is not processed when the file is included from an
|
||||||
|
asm module.*/
|
||||||
|
#if !defined(_FROM_ASM_)
|
||||||
|
|
||||||
|
/* Including the device CMSIS header. Note, we are not using the definitions
|
||||||
|
from this header because we need this file to be usable also from
|
||||||
|
assembler source files. We verify that the info matches instead.*/
|
||||||
|
#include "kl25z.h"
|
||||||
|
|
||||||
|
#if !CORTEX_HAS_MPU != !__MPU_PRESENT
|
||||||
|
#error "CMSIS __MPU_PRESENT mismatch"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS
|
||||||
|
#error "CMSIS __NVIC_PRIO_BITS mismatch"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !defined(_FROM_ASM_) */
|
||||||
|
|
||||||
|
#endif /* _CMPARAMS_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief PAL setup.
|
||||||
|
* @details Digital I/O ports static configuration as defined in @p board.h.
|
||||||
|
* This variable is used by the HAL when initializing the PAL driver.
|
||||||
|
*/
|
||||||
|
const PALConfig pal_default_config =
|
||||||
|
{
|
||||||
|
.ports = {
|
||||||
|
{
|
||||||
|
.port = IOPORT1, // PORTA
|
||||||
|
.pads = {
|
||||||
|
/* PTA0*/ PAL_MODE_ALTERNATIVE_7, /* PTA1*/ PAL_MODE_ALTERNATIVE_2, /* PTA2*/ PAL_MODE_ALTERNATIVE_2,
|
||||||
|
/* PTA3*/ PAL_MODE_ALTERNATIVE_7, /* PTA4*/ PAL_MODE_INPUT_ANALOG, /* PTA5*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTA6*/ PAL_MODE_UNCONNECTED, /* PTA7*/ PAL_MODE_UNCONNECTED, /* PTA8*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/* PTA9*/ PAL_MODE_UNCONNECTED, /*PTA10*/ PAL_MODE_UNCONNECTED, /*PTA11*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTA12*/ PAL_MODE_INPUT_ANALOG, /*PTA13*/ PAL_MODE_INPUT_ANALOG, /*PTA14*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTA15*/ PAL_MODE_INPUT_ANALOG, /*PTA16*/ PAL_MODE_INPUT_ANALOG, /*PTA17*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTA18*/ PAL_MODE_INPUT_ANALOG, /*PTA19*/ PAL_MODE_INPUT_ANALOG, /*PTA20*/ PAL_MODE_ALTERNATIVE_7,
|
||||||
|
/*PTA21*/ PAL_MODE_UNCONNECTED, /*PTA22*/ PAL_MODE_UNCONNECTED, /*PTA23*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTA24*/ PAL_MODE_UNCONNECTED, /*PTA25*/ PAL_MODE_UNCONNECTED, /*PTA26*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTA27*/ PAL_MODE_UNCONNECTED, /*PTA28*/ PAL_MODE_UNCONNECTED, /*PTA29*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTA30*/ PAL_MODE_UNCONNECTED, /*PTA31*/ PAL_MODE_UNCONNECTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.port = IOPORT2, // PORTB
|
||||||
|
.pads = {
|
||||||
|
/* PTB0*/ PAL_MODE_INPUT_ANALOG, /* PTB1*/ PAL_MODE_INPUT_ANALOG, /* PTB2*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTB3*/ PAL_MODE_INPUT_ANALOG, /* PTB4*/ PAL_MODE_UNCONNECTED, /* PTB5*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/* PTB6*/ PAL_MODE_UNCONNECTED, /* PTB7*/ PAL_MODE_UNCONNECTED, /* PTB8*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTB9*/ PAL_MODE_INPUT_ANALOG, /*PTB10*/ PAL_MODE_INPUT_ANALOG, /*PTB11*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTB12*/ PAL_MODE_UNCONNECTED, /*PTB13*/ PAL_MODE_UNCONNECTED, /*PTB14*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTB15*/ PAL_MODE_UNCONNECTED, /*PTB16*/ PAL_MODE_INPUT_ANALOG, /*PTB17*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTB18*/ PAL_MODE_OUTPUT_PUSHPULL, /*PTB19*/ PAL_MODE_OUTPUT_PUSHPULL, /*PTB20*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTB21*/ PAL_MODE_UNCONNECTED, /*PTB22*/ PAL_MODE_UNCONNECTED, /*PTB23*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTB24*/ PAL_MODE_UNCONNECTED, /*PTB25*/ PAL_MODE_UNCONNECTED, /*PTB26*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTB27*/ PAL_MODE_UNCONNECTED, /*PTB28*/ PAL_MODE_UNCONNECTED, /*PTB29*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTB30*/ PAL_MODE_UNCONNECTED, /*PTB31*/ PAL_MODE_UNCONNECTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.port = IOPORT3, // PORTC
|
||||||
|
.pads = {
|
||||||
|
/* PTC0*/ PAL_MODE_INPUT_ANALOG, /* PTC1*/ PAL_MODE_INPUT_ANALOG, /* PTC2*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTC3*/ PAL_MODE_INPUT_ANALOG, /* PTC4*/ PAL_MODE_INPUT_ANALOG, /* PTC5*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTC6*/ PAL_MODE_INPUT_ANALOG, /* PTC7*/ PAL_MODE_INPUT_ANALOG, /* PTC8*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTC9*/ PAL_MODE_INPUT_ANALOG, /*PTC10*/ PAL_MODE_INPUT_ANALOG, /*PTC11*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTC12*/ PAL_MODE_INPUT_ANALOG, /*PTC13*/ PAL_MODE_INPUT_ANALOG, /*PTC14*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTC15*/ PAL_MODE_INPUT_ANALOG, /*PTC16*/ PAL_MODE_INPUT_ANALOG, /*PTC17*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTC18*/ PAL_MODE_UNCONNECTED, /*PTC19*/ PAL_MODE_UNCONNECTED, /*PTC20*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTC21*/ PAL_MODE_UNCONNECTED, /*PTC22*/ PAL_MODE_UNCONNECTED, /*PTC23*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTC24*/ PAL_MODE_UNCONNECTED, /*PTC25*/ PAL_MODE_UNCONNECTED, /*PTC26*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTC27*/ PAL_MODE_UNCONNECTED, /*PTC28*/ PAL_MODE_UNCONNECTED, /*PTC29*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTC30*/ PAL_MODE_UNCONNECTED, /*PTC31*/ PAL_MODE_UNCONNECTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.port = IOPORT4, // PORTD
|
||||||
|
.pads = {
|
||||||
|
/* PTD0*/ PAL_MODE_INPUT_ANALOG, /* PTD1*/ PAL_MODE_OUTPUT_PUSHPULL, /* PTD2*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTD3*/ PAL_MODE_INPUT_ANALOG, /* PTD4*/ PAL_MODE_INPUT_ANALOG, /* PTD5*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTD6*/ PAL_MODE_INPUT_ANALOG, /* PTD7*/ PAL_MODE_INPUT_ANALOG, /* PTD8*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTD9*/ PAL_MODE_UNCONNECTED, /*PTD10*/ PAL_MODE_UNCONNECTED, /*PTD11*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD12*/ PAL_MODE_UNCONNECTED, /*PTD13*/ PAL_MODE_UNCONNECTED, /*PTD14*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD15*/ PAL_MODE_UNCONNECTED, /*PTD16*/ PAL_MODE_UNCONNECTED, /*PTD17*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD18*/ PAL_MODE_UNCONNECTED, /*PTD19*/ PAL_MODE_UNCONNECTED, /*PTD20*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD21*/ PAL_MODE_UNCONNECTED, /*PTD22*/ PAL_MODE_UNCONNECTED, /*PTD23*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD24*/ PAL_MODE_UNCONNECTED, /*PTD25*/ PAL_MODE_UNCONNECTED, /*PTD26*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD27*/ PAL_MODE_UNCONNECTED, /*PTD28*/ PAL_MODE_UNCONNECTED, /*PTD29*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTD30*/ PAL_MODE_UNCONNECTED, /*PTD31*/ PAL_MODE_UNCONNECTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.port = IOPORT5, // PORTE
|
||||||
|
.pads = {
|
||||||
|
/* PTE0*/ PAL_MODE_INPUT_ANALOG, /* PTE1*/ PAL_MODE_INPUT_ANALOG, /* PTE2*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTE3*/ PAL_MODE_INPUT_ANALOG, /* PTE4*/ PAL_MODE_INPUT_ANALOG, /* PTE5*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/* PTE6*/ PAL_MODE_UNCONNECTED, /* PTE7*/ PAL_MODE_UNCONNECTED, /* PTE8*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/* PTE9*/ PAL_MODE_UNCONNECTED, /*PTE10*/ PAL_MODE_UNCONNECTED, /*PTE11*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTE12*/ PAL_MODE_UNCONNECTED, /*PTE13*/ PAL_MODE_UNCONNECTED, /*PTE14*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTE15*/ PAL_MODE_UNCONNECTED, /*PTE16*/ PAL_MODE_UNCONNECTED, /*PTE17*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTE18*/ PAL_MODE_UNCONNECTED, /*PTE19*/ PAL_MODE_UNCONNECTED, /*PTE20*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTE21*/ PAL_MODE_INPUT_ANALOG, /*PTE22*/ PAL_MODE_INPUT_ANALOG, /*PTE23*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTE24*/ PAL_MODE_ALTERNATIVE_5, /*PTE25*/ PAL_MODE_ALTERNATIVE_5, /*PTE26*/ PAL_MODE_UNCONNECTED,
|
||||||
|
/*PTE27*/ PAL_MODE_UNCONNECTED, /*PTE28*/ PAL_MODE_UNCONNECTED, /*PTE29*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
/*PTE30*/ PAL_MODE_INPUT_ANALOG, /*PTE31*/ PAL_MODE_INPUT_ANALOG,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Early initialization code.
|
||||||
|
* @details This initialization must be performed just after stack setup
|
||||||
|
* and before any other initialization.
|
||||||
|
*/
|
||||||
|
void __early_init(void) {
|
||||||
|
|
||||||
|
kl2x_clock_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Board-specific initialization code.
|
||||||
|
* @todo Add your board-specific code, if any.
|
||||||
|
*/
|
||||||
|
void boardInit(void) {
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BOARD_H_
|
||||||
|
#define _BOARD_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup for Freescale Freedom KL25Z board.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Board identifier.
|
||||||
|
*/
|
||||||
|
#define BOARD_FREESCALE_FREEDOM_KL25Z
|
||||||
|
#define BOARD_NAME "Freescale Freedom KL25Z"
|
||||||
|
|
||||||
|
/* External 8 MHz crystal with PLL for 48 MHz core/system clock. */
|
||||||
|
#define KINETIS_SYSCLK_FREQUENCY 48000000UL
|
||||||
|
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
|
||||||
|
|
||||||
|
#if !defined(_FROM_ASM_)
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void boardInit(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _FROM_ASM_ */
|
||||||
|
|
||||||
|
#endif /* _BOARD_H_ */
|
|
@ -0,0 +1,5 @@
|
||||||
|
# List of all the board related files.
|
||||||
|
BOARDSRC = ${CHIBIOS}/os/hal/boards/FREESCALE_FREEDOM_KL25Z/board.c
|
||||||
|
|
||||||
|
# Required include directories
|
||||||
|
BOARDINC = ${CHIBIOS}/os/hal/boards/FREESCALE_FREEDOM_KL25Z
|
|
@ -0,0 +1,282 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/hal_lld.c
|
||||||
|
* @brief Kinetis KL2x HAL Driver subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "osal.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level HAL driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void hal_lld_init(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief KL2x clocks and PLL initialization.
|
||||||
|
* @note All the involved constants come from the file @p board.h.
|
||||||
|
* @note This function should be invoked just after the system reset.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
void kl2x_clock_init(void) {
|
||||||
|
#if !KINETIS_NO_INIT
|
||||||
|
/* Disable COP watchdog */
|
||||||
|
SIM->COPC = 0;
|
||||||
|
|
||||||
|
/* Enable PORTA */
|
||||||
|
SIM->SCGC5 |= SIM_SCGC5_PORTA;
|
||||||
|
|
||||||
|
/* --- MCG mode: FEI (default out of reset) ---
|
||||||
|
f_MCGOUTCLK = f_int * F
|
||||||
|
F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32] bits.
|
||||||
|
Typical f_MCGOUTCLK = 21 MHz immediately after reset.
|
||||||
|
C4[DMX32]=0 and C4[DRST_DRS]=00 => FLL factor=640.
|
||||||
|
C3[SCTRIM] and C4[SCFTRIM] factory trim values apply to f_int. */
|
||||||
|
|
||||||
|
/* System oscillator drives 32 kHz clock (OSC32KSEL=0) */
|
||||||
|
SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;
|
||||||
|
|
||||||
|
#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
|
||||||
|
/* This is the default mode at reset. */
|
||||||
|
/* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
|
||||||
|
* OUTDIV1 (divider for core/system and bus/flash clock)
|
||||||
|
* OUTDIV4 (additional divider for bus/flash clock) */
|
||||||
|
SIM->CLKDIV1 =
|
||||||
|
SIM_CLKDIV1_OUTDIV1(1) | /* OUTDIV1 = divide-by-2 => 24 MHz */
|
||||||
|
SIM_CLKDIV1_OUTDIV4(0); /* OUTDIV4 = divide-by-1 => 24 MHz */
|
||||||
|
|
||||||
|
#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEE
|
||||||
|
/*
|
||||||
|
* FLL Enabled External (FEE) MCG Mode
|
||||||
|
* 24 MHz core, 12 MHz bus - using 32.768 kHz crystal with FLL.
|
||||||
|
* f_MCGOUTCLK = (f_ext / FLL_R) * F
|
||||||
|
* = (32.768 kHz ) *
|
||||||
|
* FLL_R is the reference divider selected by C1[FRDIV]
|
||||||
|
* F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32].
|
||||||
|
*
|
||||||
|
* Then the core/system and bus/flash clocks are divided:
|
||||||
|
* f_SYS = f_MCGOUTCLK / OUTDIV1 = 48 MHz / 1 = 48 MHz
|
||||||
|
* f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 = MHz / 4 = 24 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
SIM->SOPT2 =
|
||||||
|
SIM_SOPT2_TPMSRC(1); /* MCGFLLCLK clock or MCGPLLCLK/2 */
|
||||||
|
/* PLLFLLSEL=0 -> MCGFLLCLK */
|
||||||
|
|
||||||
|
/* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
|
||||||
|
* OUTDIV1 (divider for core/system and bus/flash clock)
|
||||||
|
* OUTDIV4 (additional divider for bus/flash clock) */
|
||||||
|
SIM->CLKDIV1 =
|
||||||
|
SIM_CLKDIV1_OUTDIV1(KINETIS_MCG_FLL_OUTDIV1 - 1) |
|
||||||
|
SIM_CLKDIV1_OUTDIV4(KINETIS_MCG_FLL_OUTDIV4 - 1);
|
||||||
|
|
||||||
|
/* EXTAL0 and XTAL0 */
|
||||||
|
PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */
|
||||||
|
PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */
|
||||||
|
|
||||||
|
OSC0->CR = 0;
|
||||||
|
|
||||||
|
/* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */
|
||||||
|
/* To change from FEI mode to FEE mode: */
|
||||||
|
/* (1) Select the external clock source in C2 register.
|
||||||
|
Use low-power OSC mode (HGO0=0) which enables internal feedback
|
||||||
|
resistor, for 32.768 kHz crystal configuration. */
|
||||||
|
MCG->C2 =
|
||||||
|
MCG_C2_RANGE0(0) | /* low frequency range (<= 40 kHz) */
|
||||||
|
MCG_C2_EREFS0; /* external reference (using a crystal) */
|
||||||
|
/* (2) Write to C1 to select the clock mode. */
|
||||||
|
MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */
|
||||||
|
MCG_C1_CLKS_FLLPLL | /* Use FLL for system clock, MCGCLKOUT. */
|
||||||
|
MCG_C1_FRDIV(0); /* Don't divide 32kHz ERCLK FLL reference. */
|
||||||
|
MCG->C6 = 0; /* PLLS=0: Select FLL as MCG source, not PLL */
|
||||||
|
|
||||||
|
/* Loop until S[OSCINIT0] is 1, indicating the
|
||||||
|
crystal selected by C2[EREFS0] has been initialized. */
|
||||||
|
while ((MCG->S & MCG_S_OSCINIT0) == 0)
|
||||||
|
;
|
||||||
|
/* Loop until S[IREFST] is 0, indicating the
|
||||||
|
external reference is the current reference clock source. */
|
||||||
|
while ((MCG->S & MCG_S_IREFST) != 0)
|
||||||
|
; /* Wait until external reference clock is FLL reference. */
|
||||||
|
/* (1)(e) Loop until S[CLKST] indicates FLL feeds MCGOUTCLK. */
|
||||||
|
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_FLL)
|
||||||
|
; /* Wait until FLL has been selected. */
|
||||||
|
|
||||||
|
/* --- MCG mode: FEE --- */
|
||||||
|
/* Set frequency range for DCO output (MCGFLLCLK). */
|
||||||
|
MCG->C4 = (KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0) |
|
||||||
|
MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS);
|
||||||
|
|
||||||
|
/* Wait for the FLL lock time; t[fll_acquire][max] = 1 ms */
|
||||||
|
/* TODO - not implemented - is it required? Freescale example code
|
||||||
|
seems to omit it. */
|
||||||
|
|
||||||
|
#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
|
||||||
|
/*
|
||||||
|
* PLL Enabled External (PEE) MCG Mode
|
||||||
|
* 48 MHz core, 24 MHz bus - using 8 MHz crystal with PLL.
|
||||||
|
* f_MCGOUTCLK = (OSCCLK / PLL_R) * M
|
||||||
|
* = 8 MHz / 2 * 24 = 96 MHz
|
||||||
|
* PLL_R is the reference divider selected by C5[PRDIV0]
|
||||||
|
* M is the multiplier selected by C6[VDIV0]
|
||||||
|
*
|
||||||
|
* Then the core/system and bus/flash clocks are divided:
|
||||||
|
* f_SYS = f_MCGOUTCLK / OUTDIV1 = 96 MHz / 2 = 48 MHz
|
||||||
|
* f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 = 96 MHz / 4 = 24 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
|
||||||
|
* OUTDIV1 (divider for core/system and bus/flash clock)
|
||||||
|
* OUTDIV4 (additional divider for bus/flash clock) */
|
||||||
|
SIM->CLKDIV1 =
|
||||||
|
SIM_CLKDIV1_OUTDIV1(1) | /* OUTDIV1 = divide-by-2 => 48 MHz */
|
||||||
|
SIM_CLKDIV1_OUTDIV4(1); /* OUTDIV4 = divide-by-2 => 24 MHz */
|
||||||
|
|
||||||
|
SIM->SOPT2 =
|
||||||
|
SIM_SOPT2_TPMSRC(1) | /* MCGFLLCLK clock or MCGPLLCLK/2 */
|
||||||
|
SIM_SOPT2_PLLFLLSEL; /* PLLFLLSEL=MCGPLLCLK/2 */
|
||||||
|
|
||||||
|
/* EXTAL0 and XTAL0 */
|
||||||
|
PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */
|
||||||
|
PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */
|
||||||
|
|
||||||
|
OSC0->CR = 0;
|
||||||
|
|
||||||
|
/* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */
|
||||||
|
/* To change from FEI mode to FBE mode: */
|
||||||
|
/* (1) Select the external clock source in C2 register.
|
||||||
|
Use low-power OSC mode (HGO0=0) which enables internal feedback
|
||||||
|
resistor since FRDM-KL25Z has feedback resistor R25 unpopulated.
|
||||||
|
Use high-gain mode by setting C2[HGO0] instead if external
|
||||||
|
feedback resistor Rf is installed. */
|
||||||
|
MCG->C2 =
|
||||||
|
MCG_C2_RANGE0(2) | /* very high frequency range */
|
||||||
|
MCG_C2_EREFS0; /* external reference (using a crystal) */
|
||||||
|
/* (2) Write to C1 to select the clock mode. */
|
||||||
|
MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */
|
||||||
|
MCG_C1_CLKS_ERCLK | /* Use ERCLK for system clock, MCGCLKOUT. */
|
||||||
|
MCG_C1_FRDIV(3); /* Divide ERCLK / 256 for FLL reference. */
|
||||||
|
/* Note: FLL reference frequency must be 31.25 kHz to 39.0625 kHz.
|
||||||
|
8 MHz / 256 = 31.25 kHz. */
|
||||||
|
MCG->C4 &= ~(MCG_C4_DMX32 | MCG_C4_DRST_DRS_MASK);
|
||||||
|
MCG->C6 = 0; /* PLLS=0: Select FLL as MCG source, not PLL */
|
||||||
|
|
||||||
|
/* (3) Once configuration is set, wait for MCG mode change. */
|
||||||
|
|
||||||
|
/* From KL25P80M48SF0RM section 24.5.31: */
|
||||||
|
/* (1)(c) Loop until S[OSCINIT0] is 1, indicating the
|
||||||
|
crystal selected by C2[EREFS0] has been initialized. */
|
||||||
|
while ((MCG->S & MCG_S_OSCINIT0) == 0)
|
||||||
|
;
|
||||||
|
/* (1)(d) Loop until S[IREFST] is 0, indicating the
|
||||||
|
external reference is the current reference clock source. */
|
||||||
|
while ((MCG->S & MCG_S_IREFST) != 0)
|
||||||
|
; /* Wait until external reference clock is FLL reference. */
|
||||||
|
/* (1)(e) Loop until S[CLKST] is 2'b10, indicating
|
||||||
|
the external reference clock is selected to feed MCGOUTCLK. */
|
||||||
|
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_ERCLK)
|
||||||
|
; /* Wait until external reference clock has been selected. */
|
||||||
|
|
||||||
|
/* --- MCG mode: FBE (FLL bypassed, external crystal) ---
|
||||||
|
Now the MCG is in FBE mode.
|
||||||
|
Although the FLL is bypassed, it is still on. */
|
||||||
|
|
||||||
|
/* (2) Then configure C5[PRDIV0] to generate the
|
||||||
|
correct PLL reference frequency. */
|
||||||
|
MCG->C5 = MCG_C5_PRDIV0(1); /* PLL External Reference Divide by 2 */
|
||||||
|
/* (3) Then from FBE transition to PBE mode. */
|
||||||
|
/* (3)(b) C6[PLLS]=1 to select PLL. */
|
||||||
|
/* (3)(b) C6[VDIV0]=5'b0000 (x24) 2 MHz * 24 = 48 MHz. */
|
||||||
|
MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
|
||||||
|
/* (3)(d) Loop until S[PLLST], indicating PLL
|
||||||
|
is the PLLS clock source. */
|
||||||
|
while ((MCG->S & MCG_S_PLLST) == 0)
|
||||||
|
; /* wait until PLL is the PLLS clock source. */
|
||||||
|
/* (3)(e) Loop until S[LOCK0] is set, indicating the PLL has acquired lock. */
|
||||||
|
/* PLL selected as MCG source. VDIV0=00000 (Multiply=24). */
|
||||||
|
while ((MCG->S & MCG_S_LOCK0) == 0)
|
||||||
|
; /* wait until PLL locked */
|
||||||
|
|
||||||
|
/* --- MCG mode: PBE (PLL bypassed, external crystal) --- */
|
||||||
|
|
||||||
|
/* (4) Transition from PBE mode to PEE mode. */
|
||||||
|
/* (4)(a) C1[CLKS] = 2'b00 to select PLL output as system clock source. */
|
||||||
|
// Switch to PEE mode
|
||||||
|
// Select PLL output (CLKS=0)
|
||||||
|
// FLL external reference divider (FRDIV=3)
|
||||||
|
// External reference clock for FLL (IREFS=0)
|
||||||
|
MCG->C1 = MCG_C1_CLKS(0) |
|
||||||
|
MCG_C1_FRDIV(3);
|
||||||
|
/* (4)(b) Loop until S[CLKST] are 2'b11, indicating the PLL output is selected for MCGOUTCLK. */
|
||||||
|
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL)
|
||||||
|
; /* wait until clock switched to PLL output */
|
||||||
|
|
||||||
|
/* --- MCG mode: PEE (PLL enabled, external crystal) --- */
|
||||||
|
|
||||||
|
#else /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */
|
||||||
|
#error Unimplemented KINETIS_MCG_MODE
|
||||||
|
#endif /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */
|
||||||
|
|
||||||
|
#endif /* !KINETIS_NO_INIT */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Platform early 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.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
void platform_early_init(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,268 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/hal_lld.h
|
||||||
|
* @brief Kinetis KL2x HAL subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HAL_LLD_H_
|
||||||
|
#define _HAL_LLD_H_
|
||||||
|
|
||||||
|
#include "kl25z.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the support for realtime counters in the HAL.
|
||||||
|
*/
|
||||||
|
#define HAL_IMPLEMENTS_COUNTERS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Platform identification
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define PLATFORM_NAME "Kinetis"
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum system and core clock (f_SYS) frequency.
|
||||||
|
*/
|
||||||
|
#define KINETIS_SYSCLK_MAX 48000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum bus clock (f_BUS) frequency.
|
||||||
|
*/
|
||||||
|
#define KINETIS_BUSCLK_MAX 24000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 Clock divider for core/system and bus/flash 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_MCG_FLL_OUTDIV1) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_MCG_FLL_OUTDIV1 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Additional clock divider bus/flash clocks (OUTDIV4).
|
||||||
|
* @note The allowed range is 1...8.
|
||||||
|
* @note This divider is on top of the OUTDIV1 divider.
|
||||||
|
* @note The default value is calculated for 24 MHz bus/flash clocks
|
||||||
|
* from a 96 MHz PLL output and 48 MHz core/system clock.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_MCG_FLL_OUTDIV4) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_MCG_FLL_OUTDIV4 2
|
||||||
|
#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 48000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCU bus/flash clock frequency.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_BUSCLK_FREQUENCY) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_BUSCLK_FREQUENCY (KINETIS_SYSCLK_FREQUENCY / KINETIS_MCG_FLL_OUTDIV4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART0 clock frequency.
|
||||||
|
* @note The default value is based on 96 MHz PLL/2 source.
|
||||||
|
* If you use a different source, such as the FLL,
|
||||||
|
* you must set this properly.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_UART0_CLOCK_FREQ) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_UART0_CLOCK_FREQ KINETIS_SYSCLK_FREQUENCY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART0 clock source.
|
||||||
|
* @note The default value is to use PLL/2 or FLL source.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_UART0_CLOCK_SRC) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_UART0_CLOCK_SRC 1
|
||||||
|
#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 !(defined(KINETIS_MCG_FLL_OUTDIV1) && \
|
||||||
|
KINETIS_MCG_FLL_OUTDIV1 >= 1 && KINETIS_MCG_FLL_OUTDIV1 <= 16)
|
||||||
|
#error KINETIS_MCG_FLL_OUTDIV1 must be 1 through 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined(KINETIS_MCG_FLL_OUTDIV4) && \
|
||||||
|
KINETIS_MCG_FLL_OUTDIV4 >= 1 && KINETIS_MCG_FLL_OUTDIV4 <= 8)
|
||||||
|
#error KINETIS_MCG_FLL_OUTDIV4 must be 1 through 8
|
||||||
|
#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. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type representing a system clock frequency.
|
||||||
|
*/
|
||||||
|
typedef uint32_t halclock_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of the realtime free counter value.
|
||||||
|
*/
|
||||||
|
typedef uint32_t halrtcnt_t;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current value of the system free running counter.
|
||||||
|
* @note This service is implemented by returning the content of the
|
||||||
|
* DWT_CYCCNT register.
|
||||||
|
*
|
||||||
|
* @return The value of the system free running counter of
|
||||||
|
* type halrtcnt_t.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define hal_lld_get_counter_value() 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Realtime counter frequency.
|
||||||
|
* @note The DWT_CYCCNT register is incremented directly by the system
|
||||||
|
* clock so this function returns STM32_HCLK.
|
||||||
|
*
|
||||||
|
* @return The realtime counter frequency of type halclock_t.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define hal_lld_get_counter_frequency() 0
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#include "nvic.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void hal_lld_init(void);
|
||||||
|
void kl2x_clock_init(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _HAL_LLD_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/pal_lld.c
|
||||||
|
* @brief Kinetis KL2x PAL subsystem low level driver.
|
||||||
|
*
|
||||||
|
* @addtogroup PAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "osal.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief STM32 I/O ports configuration.
|
||||||
|
* @details Ports A-D(E, F, G, H) clocks enabled.
|
||||||
|
*
|
||||||
|
* @param[in] config the STM32 ports configuration
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _pal_lld_init(const PALConfig *config) {
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
/* Enable clocking of all Ports */
|
||||||
|
SIM->SCGC5 |= SIM_SCGC5_PORTA |
|
||||||
|
SIM_SCGC5_PORTB |
|
||||||
|
SIM_SCGC5_PORTC |
|
||||||
|
SIM_SCGC5_PORTD |
|
||||||
|
SIM_SCGC5_PORTE;
|
||||||
|
|
||||||
|
for (i = 0; i < TOTAL_PORTS; i++) {
|
||||||
|
for (j = 0; j < PADS_PER_PORT; j++) {
|
||||||
|
pal_lld_setpadmode(config->ports[i].port,
|
||||||
|
j,
|
||||||
|
config->ports[i].pads[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pads mode setup.
|
||||||
|
* @details This function programs a pads group belonging to the same port
|
||||||
|
* with the specified mode.
|
||||||
|
*
|
||||||
|
* @param[in] port the port identifier
|
||||||
|
* @param[in] mask the group mask
|
||||||
|
* @param[in] mode the mode
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _pal_lld_setgroupmode(ioportid_t port,
|
||||||
|
ioportmask_t mask,
|
||||||
|
iomode_t mode) {
|
||||||
|
|
||||||
|
(void)port;
|
||||||
|
(void)mask;
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a logical state from an I/O pad.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
* @return The logical state.
|
||||||
|
* @retval PAL_LOW low logical state.
|
||||||
|
* @retval PAL_HIGH high logical state.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
uint8_t pal_lld_readpad(ioportid_t port, uint8_t pad)
|
||||||
|
{
|
||||||
|
return (port->PDIR & ((uint32_t) 1 << pad)) ? PAL_HIGH : PAL_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes a logical state on an output pad.
|
||||||
|
* @note This function is not meant to be invoked directly by the
|
||||||
|
* application code.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||||
|
* @p PAL_HIGH
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void pal_lld_writepad(ioportid_t port, uint8_t pad, uint8_t bit)
|
||||||
|
{
|
||||||
|
if (bit == PAL_HIGH)
|
||||||
|
port->PDOR |= ((uint32_t) 1 << pad);
|
||||||
|
else
|
||||||
|
port->PDOR &= ~((uint32_t) 1 << pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pad mode setup.
|
||||||
|
* @details This function programs a pad with the specified mode.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
* @param[in] mode pad mode
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void pal_lld_setpadmode(ioportid_t port, uint8_t pad, iomode_t mode)
|
||||||
|
{
|
||||||
|
PORT_TypeDef *portcfg = NULL;
|
||||||
|
|
||||||
|
osalDbgAssert(pad <= 31, "pal_lld_setpadmode() - invalid pad");
|
||||||
|
|
||||||
|
if (mode == PAL_MODE_OUTPUT_PUSHPULL)
|
||||||
|
port->PDDR |= ((uint32_t) 1 << pad);
|
||||||
|
else
|
||||||
|
port->PDDR &= ~((uint32_t) 1 << pad);
|
||||||
|
|
||||||
|
if (port == IOPORT1)
|
||||||
|
portcfg = PORTA;
|
||||||
|
else if (port == IOPORT2)
|
||||||
|
portcfg = PORTB;
|
||||||
|
else if (port == IOPORT3)
|
||||||
|
portcfg = PORTC;
|
||||||
|
else if (port == IOPORT4)
|
||||||
|
portcfg = PORTD;
|
||||||
|
else if (port == IOPORT5)
|
||||||
|
portcfg = PORTE;
|
||||||
|
|
||||||
|
osalDbgAssert(portcfg != NULL, "pal_lld_setpadmode() - invalid port");
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case PAL_MODE_RESET:
|
||||||
|
case PAL_MODE_INPUT:
|
||||||
|
case PAL_MODE_OUTPUT_PUSHPULL:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(1);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_INPUT_PULLUP:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(1) | PORTx_PCRn_PE | PORTx_PCRn_PS;
|
||||||
|
break;
|
||||||
|
case PAL_MODE_INPUT_PULLDOWN:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(1) | PORTx_PCRn_PE;
|
||||||
|
break;
|
||||||
|
case PAL_MODE_UNCONNECTED:
|
||||||
|
case PAL_MODE_INPUT_ANALOG:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(0);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_1:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(1);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_2:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(2);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_3:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(3);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_4:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(4);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_5:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(5);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_6:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(6);
|
||||||
|
break;
|
||||||
|
case PAL_MODE_ALTERNATIVE_7:
|
||||||
|
portcfg->PCR[pad] = PORTx_PCRn_MUX(7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_PAL */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/pal_lld.h
|
||||||
|
* @brief Kinetis KL2x PAL subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup PAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PAL_LLD_H_
|
||||||
|
#define _PAL_LLD_H_
|
||||||
|
|
||||||
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Unsupported modes and specific modes */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||||
|
|
||||||
|
#define PAL_MODE_ALTERNATIVE_1 0x10
|
||||||
|
#define PAL_MODE_ALTERNATIVE_2 0x11
|
||||||
|
#define PAL_MODE_ALTERNATIVE_3 0x12
|
||||||
|
#define PAL_MODE_ALTERNATIVE_4 0x13
|
||||||
|
#define PAL_MODE_ALTERNATIVE_5 0x14
|
||||||
|
#define PAL_MODE_ALTERNATIVE_6 0x15
|
||||||
|
#define PAL_MODE_ALTERNATIVE_7 0x16
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* I/O Ports Types and constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define TOTAL_PORTS 5
|
||||||
|
#define PADS_PER_PORT 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Digital I/O port sized unsigned type.
|
||||||
|
*/
|
||||||
|
typedef uint32_t ioportmask_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Digital I/O modes.
|
||||||
|
*/
|
||||||
|
typedef uint8_t iomode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port Identifier.
|
||||||
|
* @details This type can be a scalar or some kind of pointer, do not make
|
||||||
|
* any assumption about it, use the provided macros when populating
|
||||||
|
* variables of this type.
|
||||||
|
*/
|
||||||
|
typedef GPIO_TypeDef * ioportid_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ioportid_t port;
|
||||||
|
iomode_t pads[PADS_PER_PORT];
|
||||||
|
} PortConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic I/O ports static initializer.
|
||||||
|
* @details An instance of this structure must be passed to @p palInit() at
|
||||||
|
* system startup time in order to initialized the digital I/O
|
||||||
|
* subsystem. This represents only the initial setup, specific pads
|
||||||
|
* or whole ports can be reprogrammed at later time.
|
||||||
|
* @note Implementations may extend this structure to contain more,
|
||||||
|
* architecture dependent, fields.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PortConfig ports[TOTAL_PORTS];
|
||||||
|
} PALConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Width, in bits, of an I/O port.
|
||||||
|
*/
|
||||||
|
#define PAL_IOPORTS_WIDTH 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whole port mask.
|
||||||
|
* @brief This macro specifies all the valid bits into a port.
|
||||||
|
*/
|
||||||
|
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* I/O Ports Identifiers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief First I/O port identifier.
|
||||||
|
* @details Low level drivers can define multiple ports, it is suggested to
|
||||||
|
* use this naming convention.
|
||||||
|
*/
|
||||||
|
#define IOPORT1 GPIOA
|
||||||
|
#define IOPORT2 GPIOB
|
||||||
|
#define IOPORT3 GPIOC
|
||||||
|
#define IOPORT4 GPIOD
|
||||||
|
#define IOPORT5 GPIOE
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Implementation, some of the following macros could be implemented as */
|
||||||
|
/* functions, if so please put them in pal_lld.c. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level PAL subsystem initialization.
|
||||||
|
*
|
||||||
|
* @param[in] config architecture-dependent ports configuration
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_init(config) _pal_lld_init(config)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the physical I/O port states.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @return The port bits.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_readport(port) \
|
||||||
|
(port)->PDIR
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the output latch.
|
||||||
|
* @details The purpose of this function is to read back the latched output
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @return The latched logical states.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_readlatch(port) 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes a bits mask on a I/O port.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] bits bits to be written on the specified port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_writeport(port, bits)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a bits mask on a I/O port.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] bits bits to be ORed on the specified port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_setport(port, bits)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a bits mask on a I/O port.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] bits bits to be cleared on the specified port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_clearport(port, bits)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggles a bits mask on a I/O port.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] bits bits to be XORed on the specified port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_toggleport(port, bits)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a group of bits.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] mask group mask
|
||||||
|
* @param[in] offset group bit offset within the port
|
||||||
|
* @return The group logical states.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_readgroup(port, mask, offset) 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes a group of bits.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] mask group mask
|
||||||
|
* @param[in] offset group bit offset within the port
|
||||||
|
* @param[in] bits bits to be written. Values exceeding the group width
|
||||||
|
* are masked.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_writegroup(port, mask, offset, bits) (void)bits
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pads group mode setup.
|
||||||
|
* @details This function programs a pads group belonging to the same port
|
||||||
|
* with the specified mode.
|
||||||
|
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] mask group mask
|
||||||
|
* @param[in] offset group bit offset within the port
|
||||||
|
* @param[in] mode group mode
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||||
|
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a pad logical state to @p PAL_HIGH.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_setpad(port, pad) (port)->PSOR |= ((uint32_t) 1 << (pad))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a pad logical state to @p PAL_LOW.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_clearpad(port, pad) (port)->PCOR |= ((uint32_t) 1 << (pad))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggles a pad logical state.
|
||||||
|
* @note The @ref PAL provides a default software implementation of this
|
||||||
|
* functionality, implement this function if can optimize it by using
|
||||||
|
* special hardware functionalities or special coding.
|
||||||
|
*
|
||||||
|
* @param[in] port port identifier
|
||||||
|
* @param[in] pad pad number within the port
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define pal_lld_togglepad(port, pad) (port)->PTOR |= ((uint32_t) 1 << (pad))
|
||||||
|
|
||||||
|
#if !defined(__DOXYGEN__)
|
||||||
|
extern const PALConfig pal_default_config;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void _pal_lld_init(const PALConfig *config);
|
||||||
|
void _pal_lld_setgroupmode(ioportid_t port,
|
||||||
|
ioportmask_t mask,
|
||||||
|
iomode_t mode);
|
||||||
|
void pal_lld_setpadmode(ioportid_t port,
|
||||||
|
uint8_t pad,
|
||||||
|
iomode_t mode);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_PAL */
|
||||||
|
|
||||||
|
#endif /* _PAL_LLD_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,10 @@
|
||||||
|
# List of all platform files.
|
||||||
|
PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
|
||||||
|
${CHIBIOS}/os/hal/ports/KINETIS/KL2x/hal_lld.c \
|
||||||
|
${CHIBIOS}/os/hal/ports/KINETIS/KL2x/pal_lld.c \
|
||||||
|
${CHIBIOS}/os/hal/ports/KINETIS/KL2x/serial_lld.c \
|
||||||
|
${CHIBIOS}/os/hal/ports/KINETIS/KL2x/st_lld.c
|
||||||
|
|
||||||
|
# Required include directories
|
||||||
|
PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \
|
||||||
|
${CHIBIOS}/os/hal/ports/KINETIS/KL2x
|
|
@ -0,0 +1,353 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/serial_lld.c
|
||||||
|
* @brief Kinetis KL2x Serial Driver subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup SERIAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
#include "kl25z.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SD1 driver identifier.
|
||||||
|
*/
|
||||||
|
#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__)
|
||||||
|
SerialDriver SD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__)
|
||||||
|
SerialDriver SD2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__)
|
||||||
|
SerialDriver SD3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Driver default configuration.
|
||||||
|
*/
|
||||||
|
static const SerialConfig default_config = {
|
||||||
|
38400
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common IRQ handler.
|
||||||
|
* @note Tries hard to clear all the pending interrupt sources, we don't
|
||||||
|
* want to go through the whole ISR and have another interrupt soon
|
||||||
|
* after.
|
||||||
|
*
|
||||||
|
* @param[in] u pointer to an UART I/O block
|
||||||
|
* @param[in] sdp communication channel associated to the UART
|
||||||
|
*/
|
||||||
|
static void serve_interrupt(SerialDriver *sdp) {
|
||||||
|
UARTLP_TypeDef *u = sdp->uart;
|
||||||
|
|
||||||
|
if (u->S1 & UARTx_S1_RDRF) {
|
||||||
|
osalSysLockFromISR();
|
||||||
|
if (chIQIsEmptyI(&sdp->iqueue))
|
||||||
|
chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
|
||||||
|
if (chIQPutI(&sdp->iqueue, u->D) < Q_OK)
|
||||||
|
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->S1 & UARTx_S1_TDRE) {
|
||||||
|
msg_t b;
|
||||||
|
|
||||||
|
osalSysLockFromISR();
|
||||||
|
b = chOQGetI(&sdp->oqueue);
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
|
||||||
|
if (b < Q_OK) {
|
||||||
|
osalSysLockFromISR();
|
||||||
|
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
u->C2 &= ~UARTx_C2_TIE;
|
||||||
|
} else {
|
||||||
|
u->D = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->S1 & UARTx_S1_IDLE)
|
||||||
|
u->S1 = UARTx_S1_IDLE; // Clear IDLE (S1 bits are write-1-to-clear).
|
||||||
|
|
||||||
|
if (u->S1 & (UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF)) {
|
||||||
|
// FIXME: need to add set_error()
|
||||||
|
// Clear flags (S1 bits are write-1-to-clear).
|
||||||
|
u->S1 = UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attempts a TX preload
|
||||||
|
*/
|
||||||
|
static void preload(SerialDriver *sdp) {
|
||||||
|
UARTLP_TypeDef *u = sdp->uart;
|
||||||
|
|
||||||
|
if (u->S1 & UARTx_S1_TDRE) {
|
||||||
|
msg_t b = chOQGetI(&sdp->oqueue);
|
||||||
|
if (b < Q_OK) {
|
||||||
|
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u->D = b;
|
||||||
|
u->C2 |= UARTx_C2_TIE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Driver output notification.
|
||||||
|
*/
|
||||||
|
#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__)
|
||||||
|
static void notify1(GenericQueue *qp)
|
||||||
|
{
|
||||||
|
(void)qp;
|
||||||
|
preload(&SD1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__)
|
||||||
|
static void notify2(GenericQueue *qp)
|
||||||
|
{
|
||||||
|
(void)qp;
|
||||||
|
preload(&SD2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__)
|
||||||
|
static void notify3(GenericQueue *qp)
|
||||||
|
{
|
||||||
|
(void)qp;
|
||||||
|
preload(&SD3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common UART configuration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void configure_uart(UARTLP_TypeDef *uart, const SerialConfig *config)
|
||||||
|
{
|
||||||
|
uint32_t uart_clock;
|
||||||
|
|
||||||
|
uart->C1 = 0;
|
||||||
|
uart->C3 = UARTx_C3_ORIE | UARTx_C3_NEIE | UARTx_C3_FEIE | UARTx_C3_PEIE;
|
||||||
|
uart->S1 = UARTx_S1_IDLE | UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF;
|
||||||
|
while (uart->S1 & UARTx_S1_RDRF) {
|
||||||
|
(void)uart->D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0
|
||||||
|
if (uart == UART0) {
|
||||||
|
/* UART0 can be clocked from several sources. */
|
||||||
|
uart_clock = KINETIS_UART0_CLOCK_FREQ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if KINETIS_SERIAL_USE_UART1
|
||||||
|
if (uart == UART1) {
|
||||||
|
uart_clock = KINETIS_BUSCLK_FREQUENCY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if KINETIS_SERIAL_USE_UART2
|
||||||
|
if (uart == UART2) {
|
||||||
|
uart_clock = KINETIS_BUSCLK_FREQUENCY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: change fixed OSR = 16 to dynamic value based on baud */
|
||||||
|
uint16_t divisor = (uart_clock / 16) / config->sc_speed;
|
||||||
|
uart->C4 = UARTx_C4_OSR & (16 - 1);
|
||||||
|
uart->BDH = (divisor >> 8) & UARTx_BDH_SBR;
|
||||||
|
uart->BDL = (divisor & UARTx_BDL_SBR);
|
||||||
|
|
||||||
|
uart->C2 = UARTx_C2_RE | UARTx_C2_RIE | UARTx_C2_TE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__)
|
||||||
|
CH_IRQ_HANDLER(Vector70) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
serve_interrupt(&SD1);
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__)
|
||||||
|
CH_IRQ_HANDLER(Vector74) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
serve_interrupt(&SD2);
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__)
|
||||||
|
CH_IRQ_HANDLER(Vector78) {
|
||||||
|
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
serve_interrupt(&SD3);
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level serial driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void sd_lld_init(void) {
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0
|
||||||
|
/* Driver initialization.*/
|
||||||
|
sdObjectInit(&SD1, NULL, notify1);
|
||||||
|
SD1.uart = UART0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1
|
||||||
|
/* Driver initialization.*/
|
||||||
|
sdObjectInit(&SD2, NULL, notify2);
|
||||||
|
SD2.uart = UART1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2
|
||||||
|
/* Driver initialization.*/
|
||||||
|
sdObjectInit(&SD3, NULL, notify3);
|
||||||
|
SD3.uart = UART2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level serial driver configuration and (re)start.
|
||||||
|
*
|
||||||
|
* @param[in] sdp pointer to a @p SerialDriver object
|
||||||
|
* @param[in] config the architecture-dependent serial driver configuration.
|
||||||
|
* If this parameter is set to @p NULL then a default
|
||||||
|
* configuration is used.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||||
|
|
||||||
|
if (config == NULL)
|
||||||
|
config = &default_config;
|
||||||
|
|
||||||
|
if (sdp->state == SD_STOP) {
|
||||||
|
/* Enables the peripheral.*/
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0
|
||||||
|
if (sdp == &SD1) {
|
||||||
|
SIM->SCGC4 |= SIM_SCGC4_UART0;
|
||||||
|
SIM->SOPT2 =
|
||||||
|
(SIM->SOPT2 & ~SIM_SOPT2_UART0SRC_MASK) |
|
||||||
|
SIM_SOPT2_UART0SRC(KINETIS_UART0_CLOCK_SRC);
|
||||||
|
configure_uart(sdp->uart, config);
|
||||||
|
nvicEnableVector(UART0_IRQn, KINETIS_SERIAL_UART0_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif /* KINETIS_SERIAL_USE_UART0 */
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1
|
||||||
|
if (sdp == &SD2) {
|
||||||
|
SIM->SCGC4 |= SIM_SCGC4_UART1;
|
||||||
|
configure_uart(sdp->uart, config);
|
||||||
|
nvicEnableVector(UART1_IRQn, KINETIS_SERIAL_UART1_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif /* KINETIS_SERIAL_USE_UART1 */
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2
|
||||||
|
if (sdp == &SD3) {
|
||||||
|
SIM->SCGC4 |= SIM_SCGC4_UART2;
|
||||||
|
configure_uart(sdp->uart, config);
|
||||||
|
nvicEnableVector(UART2_IRQn, KINETIS_SERIAL_UART2_PRIORITY);
|
||||||
|
}
|
||||||
|
#endif /* KINETIS_SERIAL_USE_UART2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
/* Configures the peripheral.*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level serial driver stop.
|
||||||
|
* @details De-initializes the USART, stops the associated clock, resets the
|
||||||
|
* interrupt vector.
|
||||||
|
*
|
||||||
|
* @param[in] sdp pointer to a @p SerialDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void sd_lld_stop(SerialDriver *sdp) {
|
||||||
|
|
||||||
|
if (sdp->state == SD_READY) {
|
||||||
|
/* TODO: Resets the peripheral.*/
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0
|
||||||
|
if (sdp == &SD1) {
|
||||||
|
nvicDisableVector(UART0_IRQn);
|
||||||
|
SIM->SCGC4 &= ~SIM_SCGC4_UART0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1
|
||||||
|
if (sdp == &SD2) {
|
||||||
|
nvicDisableVector(UART1_IRQn);
|
||||||
|
SIM->SCGC4 &= ~SIM_SCGC4_UART1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2
|
||||||
|
if (sdp == &SD3) {
|
||||||
|
nvicDisableVector(UART2_IRQn);
|
||||||
|
SIM->SCGC4 &= ~SIM_SCGC4_UART2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_SERIAL */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KL2x/serial_lld.h
|
||||||
|
* @brief Kinetis KL2x Serial Driver subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup SERIAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SERIAL_LLD_H_
|
||||||
|
#define _SERIAL_LLD_H_
|
||||||
|
|
||||||
|
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief SD1 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for SD1 is included.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_USE_UART0) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_USE_UART0 FALSE
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief SD2 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for SD2 is included.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_USE_UART1) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_USE_UART1 FALSE
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief SD3 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for SD3 is included.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_USE_UART2) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_USE_UART2 FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART0 interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_UART0_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_UART0_PRIORITY 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART1 interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_UART1_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_UART1_PRIORITY 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART2 interrupt priority level setting.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_SERIAL_UART2_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_SERIAL_UART2_PRIORITY 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic Serial Driver configuration structure.
|
||||||
|
* @details An instance of this structure must be passed to @p sdStart()
|
||||||
|
* in order to configure and start a serial driver operations.
|
||||||
|
* @note Implementations may extend this structure to contain more,
|
||||||
|
* architecture dependent, fields.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Bit rate.
|
||||||
|
*/
|
||||||
|
uint32_t sc_speed;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
} SerialConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief @p SerialDriver specific data.
|
||||||
|
*/
|
||||||
|
#define _serial_driver_data \
|
||||||
|
_base_asynchronous_channel_data \
|
||||||
|
/* Driver state.*/ \
|
||||||
|
sdstate_t state; \
|
||||||
|
/* Input queue.*/ \
|
||||||
|
InputQueue iqueue; \
|
||||||
|
/* Output queue.*/ \
|
||||||
|
OutputQueue oqueue; \
|
||||||
|
/* Input circular buffer.*/ \
|
||||||
|
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||||
|
/* Output circular buffer.*/ \
|
||||||
|
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||||
|
/* End of the mandatory fields.*/ \
|
||||||
|
/* Pointer to the UART registers block.*/ \
|
||||||
|
UARTLP_TypeDef *uart;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART0 && !defined(__DOXYGEN__)
|
||||||
|
extern SerialDriver SD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART1 && !defined(__DOXYGEN__)
|
||||||
|
extern SerialDriver SD2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KINETIS_SERIAL_USE_UART2 && !defined(__DOXYGEN__)
|
||||||
|
extern SerialDriver SD3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void sd_lld_init(void);
|
||||||
|
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||||
|
void sd_lld_stop(SerialDriver *sdp);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_SERIAL */
|
||||||
|
|
||||||
|
#endif /* _SERIAL_LLD_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KINETIS/KL2x/st_lld.c
|
||||||
|
* @brief ST Driver subsystem low level driver code.
|
||||||
|
*
|
||||||
|
* @addtogroup ST
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief System Timer vector.
|
||||||
|
* @details This interrupt is used for system tick in periodic mode.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(SysTick_Handler) {
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
osalSysLockFromISR();
|
||||||
|
osalOsTimerHandlerI();
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level ST driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void st_lld_init(void) {
|
||||||
|
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
|
||||||
|
/* Periodic systick mode, the Cortex-Mx internal systick timer is used
|
||||||
|
in this mode.*/
|
||||||
|
SysTick->LOAD = (KINETIS_SYSCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1;
|
||||||
|
SysTick->VAL = 0;
|
||||||
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk;
|
||||||
|
|
||||||
|
/* IRQ enabled.*/
|
||||||
|
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, KINETIS_ST_IRQ_PRIORITY);
|
||||||
|
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file KINETIS/st_lld.h
|
||||||
|
* @brief ST Driver subsystem low level driver header.
|
||||||
|
* @details This header is designed to be include-able without having to
|
||||||
|
* include other files from the HAL.
|
||||||
|
*
|
||||||
|
* @addtogroup ST
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ST_LLD_H_
|
||||||
|
#define _ST_LLD_H_
|
||||||
|
|
||||||
|
#include "mcuconf.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief SysTick timer IRQ priority.
|
||||||
|
*/
|
||||||
|
#if !defined(KINETIS_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define KINETIS_ST_IRQ_PRIORITY 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void st_lld_init(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the time counter value.
|
||||||
|
*
|
||||||
|
* @return The counter value.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline systime_t st_lld_get_counter(void) {
|
||||||
|
|
||||||
|
return (systime_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the alarm.
|
||||||
|
* @note Makes sure that no spurious alarms are triggered after
|
||||||
|
* this call.
|
||||||
|
*
|
||||||
|
* @param[in] time the time to be set for the first alarm
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_start_alarm(systime_t time) {
|
||||||
|
|
||||||
|
(void)time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the alarm interrupt.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_stop_alarm(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the alarm time.
|
||||||
|
*
|
||||||
|
* @param[in] time the time to be set for the next alarm
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void st_lld_set_alarm(systime_t time) {
|
||||||
|
|
||||||
|
(void)time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current alarm time.
|
||||||
|
*
|
||||||
|
* @return The currently set alarm time.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline systime_t st_lld_get_alarm(void) {
|
||||||
|
|
||||||
|
return (systime_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines if the alarm is active.
|
||||||
|
*
|
||||||
|
* @return The alarm status.
|
||||||
|
* @retval false if the alarm is not active.
|
||||||
|
* @retval true is the alarm is active
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline bool st_lld_is_alarm_active(void) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ST_LLD_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
Loading…
Reference in New Issue