Merge pull request #158 from walkerstop/mike

Kinetis MK66F18 and PJRC Teensy 3.6 support
This commit is contained in:
Fabien Poussin 2018-05-07 16:58:30 +02:00 committed by GitHub
commit 6cc0927c06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 24761 additions and 3 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
/*
** ###################################################################
** Processors: MK66FN2M0VLQ18
** MK66FN2M0VMD18
** MK66FX1M0VLQ18
** MK66FX1M0VMD18
**
** Compilers: Keil ARM C/C++ Compiler
** Freescale C/C++ for Embedded ARM
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** MCUXpresso Compiler
**
** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015
** Version: rev. 3.0, 2015-03-25
** Build: b171226
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** The Clear BSD License
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2017 NXP
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted (subject to the limitations in the
** disclaimer below) provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** * Neither the name of the copyright holder nor the names of its
** contributors may be used to endorse or promote products derived from
** this software without specific prior written permission.
**
** NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
** GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
** HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2013-09-02)
** Initial version.
** - rev. 2.0 (2014-02-17)
** Register accessor macros added to the memory map.
** Symbols for Processor Expert memory map compatibility added to the memory map.
** Startup file for gcc has been updated according to CMSIS 3.2.
** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled.
** Update according to reference manual rev. 2
** - rev. 2.1 (2014-04-16)
** Update of SystemInit() and SystemCoreClockUpdate() functions.
** - rev. 2.2 (2014-10-14)
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.3 (2014-11-20)
** Update according to reverence manual K65P169M180SF5RMV2_NDA, Rev. 0 Draft A, October 2014.
** Update of SystemInit() to use 16MHz external crystal.
** - rev. 2.4 (2015-02-19)
** Renamed interrupt vector LLW to LLWU.
** - rev. 3.0 (2015-03-25)
** Registers updated according to the reference manual revision 1, March 2015
**
** ###################################################################
*/
/*!
* @file MK66F18
* @version 3.0
* @date 2015-03-25
* @brief Device specific configuration file for MK66F18 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef _SYSTEM_MK66F18_H_
#define _SYSTEM_MK66F18_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#ifndef DISABLE_WDOG
#define DISABLE_WDOG 1
#endif
/* Define clock source values */
#define CPU_XTAL_CLK_HZ 16000000U /* Value of the external crystal or oscillator clock frequency of the system oscillator (OSC) in Hz */
#define CPU_XTAL32k_CLK_HZ 32768U /* Value of the external 32k crystal or oscillator clock frequency of the RTC in Hz */
#define CPU_INT_SLOW_CLK_HZ 32768U /* Value of the slow internal oscillator clock frequency in Hz */
#define CPU_INT_FAST_CLK_HZ 4000000U /* Value of the fast internal oscillator clock frequency in Hz */
#define CPU_INT_IRC_CLK_HZ 48000000U /* Value of the 48M internal oscillator clock frequency in Hz */
/* RTC oscillator setting */
/* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0,CLKO=1,OSCE=1,WPS=0,UM=0,SUP=0,WPE=0,SWR=0 */
#define SYSTEM_RTC_CR_VALUE 0x0300U /* RTC_CR */
/* Low power mode enable */
/* SMC_PMPROT: AHSRUN=1,AVLP=1,ALLS=1,AVLLS=1 */
#define SYSTEM_SMC_PMPROT_VALUE 0xAAU /* SMC_PMPROT */
#define DEFAULT_SYSTEM_CLOCK 20971520u
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit (void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void);
/**
* @brief SystemInit function hook.
*
* This weak function allows to call specific initialization code during the
* SystemInit() execution.This can be used when an application specific code needs
* to be called as close to the reset entry as possible (for example the Multicore
* Manager MCMGR_EarlyInit() function call).
* NOTE: No global r/w variables can be used in this hook function because the
* initialization of these variables happens after this function.
*/
void SystemInitHook (void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MK66F18_H_ */

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2013-2016 Fabio Utzig, http://fabioutzig.com
* (C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* MK66FX1M0 memory setup.
*/
MEMORY
{
flash0 : org = 0x00000000, len = 0x400
flash1 : org = 0x00000400, len = 0x10
flash2 : org = 0x00000410, len = 1024k - 0x410
flash3 : org = 0x10000000, len = 128k /* FlexNVM */
ram0 : org = 0x1FFF0000, len = 64k /* SRAM_L (code RAM) */
ram1 : org = 0x20000000, len = 192k /* SRAM_U (data RAM) */
ram2 : org = 0x14000000, len = 4k /* FlexRAM */
ram3 : org = 0x00000000, len = 0
ram4 : org = 0x00000000, len = 0
ram5 : org = 0x00000000, len = 0
ram6 : org = 0x00000000, len = 0
ram7 : org = 0x00000000, len = 0
}
/* Flash region for the configuration bytes.*/
SECTIONS
{
.cfmprotect : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.cfmconfig))
} > flash1
}
/* For each data/text section two region are defined, a virtual region
and a load region (_LMA suffix).*/
/* Flash region to be used for exception vectors.*/
REGION_ALIAS("VECTORS_FLASH", flash0);
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash2);
REGION_ALIAS("XTORS_FLASH_LMA", flash2);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash2);
REGION_ALIAS("TEXT_FLASH_LMA", flash2);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash2);
REGION_ALIAS("RODATA_FLASH_LMA", flash2);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash2);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash2);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("MAIN_STACK_RAM", ram1);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("PROCESS_STACK_RAM", ram1);
/* RAM region to be used for data segment.*/
REGION_ALIAS("DATA_RAM", ram1);
REGION_ALIAS("DATA_RAM_LMA", flash2);
/* RAM region to be used for BSS segment.*/
REGION_ALIAS("BSS_RAM", ram1);
/* RAM region to be used for the default heap.*/
REGION_ALIAS("HEAP_RAM", ram1);
/* Generic rules inclusion.*/
INCLUDE rules.ld

View File

@ -0,0 +1,13 @@
# List of the ChibiOS generic MK66F18 startup and CMSIS files.
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.S
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
$(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/MK66F18 \
$(CHIBIOS)/os/common/ext/CMSIS/include \
$(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \
$(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/KINETIS
STARTUPLD = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld

View File

@ -0,0 +1,80 @@
/*
ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio.
(C) 2015 RedoX https://github.com/RedoXyde
(C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
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/MK66F18/cmparams.h
* @brief ARM Cortex-M4 parameters for the Kinetis MK66F18.
*
* @defgroup ARMCMx_MK66F18 Kinetis MK66F18 Specific Parameters
* @ingroup ARMCMx_SPECIFIC
* @details This file contains the Cortex-M4 specific parameters for the
* Kinetis MK66F18 platform.
* @{
*/
#ifndef _CMPARAMS_H_
#define _CMPARAMS_H_
/**
* @brief Cortex core model.
*/
#define CORTEX_MODEL 4
/**
* @brief Systick unit presence.
*/
#define CORTEX_HAS_ST TRUE
/**
* @brief Floating Point unit presence.
*/
#define CORTEX_HAS_FPU TRUE
/**
* @brief Number of bits in priority masks.
*/
#define CORTEX_PRIORITY_BITS 4
/**
* @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 104
/* 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 "MK66F18.h"
#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS
#error "CMSIS __NVIC_PRIO_BITS mismatch"
#endif
#endif /* !defined(_FROM_ASM_) */
#endif /* _CMPARAMS_H_ */
/** @} */

View File

@ -0,0 +1,216 @@
/*
ChibiOS - Copyright (C) 2015 RedoX https://github.com/RedoXyde
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 "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 = {
{
/*
* PORTA setup.
*
* PTA0 - SWD
* PTA3 - SWD
* PTA5 - PIN25
* PTA12 - PIN3
* PTA13 - PIN4
* PTA14 - PIN26
* PTA15 - PIN27
* PTA16 - PIN28
* PTA17 - PIN39
* PTA18 - Crystal
* PTA19 - Crystal
* PTA26 - PIN42
* PTA28 - PIN40
* PTA29 - PIN41
*
*/
.port = IOPORT1,
.pads = {
PAL_MODE_ALTERNATIVE_7, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_ALTERNATIVE_7, PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_INPUT_ANALOG, PAL_MODE_INPUT_ANALOG, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
},
},
{
/*
* PORTB setup.
*
* PTB0 - PIN16
* PTB1 - PIN17
* PTB2 - PIN19
* PTB3 - PIN18
* PTB4 - PIN49
* PTB5 - PIN50
* PTB10 - PIN31
* PTB11 - PIN32
* PTB16 - PIN0 - UART0_RX
* PTB17 - PIN1 - UART0_TX
* PTB18 - PIN29
* PTB19 - PIN30
* PTB20 - PIN43
* PTB21 - PIN46
* PTB22 - PIN44
* PTB23 - PIN45
*/
.port = IOPORT2,
.pads = {
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_ALTERNATIVE_3, PAL_MODE_ALTERNATIVE_3,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
},
},
{
/*
* PORTC setup.
* PTC0 - PIN15
* PTC1 - PIN22
* PTC2 - PIN23
* PTC3 - PIN9
* PTC4 - PIN10
* PTC5 - PIN13
* PTC6 - PIN11
* PTC7 - PIN12
* PTC8 - PIN35
* PTC9 - PIN36
* PTC10 - PIN37
* PTC11 - PIN38
*
*/
.port = IOPORT3,
.pads = {
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
},
},
{
/*
* PORTD setup.
*
* PTD0 - PIN2
* PTD1 - PIN14
* PTD2 - PIN7
* PTD3 - PIN8
* PTD4 - PIN6
* PTD5 - PIN20
* PTD6 - PIN21
* PTD7 - PIN5
* PTD8 - PIN47
* PTD9 - PIN48
* PTD11 - PIN55
* PTD12 - PIN53
* PTD13 - PIN52
* PTD14 - PIN51
* PTD15 - PIN54
*/
.port = IOPORT4,
.pads = {
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
},
},
{
/*
* PORTE setup.
*
* PTE0 - SDHC
* PTE1 - SDHC
* PTE2 - SDHC
* PTE3 - SDHC
* PTE4 - SDHC
* PTE5 - SDHC
* PTE6 - USB OTG power switch
* PTE10 - PIN56
* PTE11 - PIN57
* PTE24 - PIN33
* PTE25 - PIN34
* PTE26 - PIN24
*/
.port = IOPORT5,
.pads = {
PAL_MODE_ALTERNATIVE_4, PAL_MODE_ALTERNATIVE_4, PAL_MODE_ALTERNATIVE_4,
PAL_MODE_ALTERNATIVE_4, PAL_MODE_ALTERNATIVE_4, PAL_MODE_ALTERNATIVE_4,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED,
},
},
},
};
#endif
/**
* @brief Early initialization code.
* @details This initialization must be performed just after stack setup
* and before any other initialization.
*/
void __early_init(void) {
MK66F18_clock_init();
}
/**
* @brief Board-specific initialization code.
* @todo Add your board-specific code, if any.
*/
void boardInit(void) {
}

View File

@ -0,0 +1,345 @@
/*
ChibiOS - Copyright (C) 2015 RedoX https://github.com/RedoXyde
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 the PJRC Teensy 3.6 board.
*/
/*
* Board identifier.
*/
#define BOARD_PJRC_TEENSY_3_6
#define BOARD_NAME "PJRC Teensy 3.6"
/* External 16 MHz crystal */
#define KINETIS_XTAL_FREQUENCY 16000000UL
/* Use internal capacitors for the crystal */
#define KINETIS_BOARD_OSCILLATOR_SETTING OSC_CR_SC8P|OSC_CR_SC2P
/*
* MCU type
*/
#define MK66F18
/*
* IO pins assignments.
*/
#define PORTA_PIN0 0
#define PORTA_PIN1 1
#define PORTA_PIN2 2
#define PORTA_PIN3 3
#define PORTA_PIN4 4
#define TEENSY_PIN25 5
#define PORTA_PIN6 6
#define PORTA_PIN7 7
#define PORTA_PIN8 8
#define PORTA_PIN9 9
#define PORTA_PIN10 10
#define PORTA_PIN11 11
#define TEENSY_PIN3 12
#define TEENSY_PIN4 13
#define TEENSY_PIN26 14
#define TEENSY_PIN27 15
#define TEENSY_PIN28 16
#define TEENSY_PIN39 17
#define PORTA_PIN18 18
#define PORTA_PIN19 19
#define PORTA_PIN20 20
#define PORTA_PIN21 21
#define PORTA_PIN22 22
#define PORTA_PIN23 23
#define PORTA_PIN24 24
#define PORTA_PIN25 25
#define TEENSY_PIN42 26
#define PORTA_PIN27 27
#define TEENSY_PIN40 28
#define TEENSY_PIN41 29
#define PORTA_PIN30 30
#define PORTA_PIN31 31
#define TEENSY_PIN40_IOPORT IOPORT1
#define TEENSY_PIN41_IOPORT IOPORT1
#define TEENSY_PIN42_IOPORT IOPORT1
#define TEENSY_PIN3_IOPORT IOPORT1
#define TEENSY_PIN4_IOPORT IOPORT1
#define TEENSY_PIN25_IOPORT IOPORT1
#define TEENSY_PIN26_IOPORT IOPORT1
#define TEENSY_PIN27_IOPORT IOPORT1
#define TEENSY_PIN28_IOPORT IOPORT1
#define TEENSY_PIN39_IOPORT IOPORT1
#define TEENSY_PIN16 0
#define TEENSY_PIN17 1
#define TEENSY_PIN19 2
#define TEENSY_PIN18 3
#define TEENSY_PIN49 4
#define TEENSY_PIN50 5
#define PORTB_PIN6 6
#define PORTB_PIN7 7
#define PORTB_PIN8 8
#define PORTB_PIN9 9
#define TEENSY_PIN31 10
#define TEENSY_PIN32 11
#define PORTB_PIN12 12
#define PORTB_PIN13 13
#define PORTB_PIN14 14
#define PORTB_PIN15 15
#define TEENSY_PIN0 16
#define TEENSY_PIN1 17
#define TEENSY_PIN29 18
#define TEENSY_PIN30 19
#define TEENSY_PIN43 20
#define TEENSY_PIN46 21
#define TEENSY_PIN44 22
#define TEENSY_PIN45 23
#define PORTB_PIN24 24
#define PORTB_PIN25 25
#define PORTB_PIN26 26
#define PORTB_PIN27 27
#define PORTB_PIN28 28
#define PORTB_PIN29 29
#define PORTB_PIN30 30
#define PORTB_PIN31 31
#define TEENSY_PIN49_IOPORT IOPORT2
#define TEENSY_PIN50_IOPORT IOPORT2
#define TEENSY_PIN43_IOPORT IOPORT2
#define TEENSY_PIN44_IOPORT IOPORT2
#define TEENSY_PIN45_IOPORT IOPORT2
#define TEENSY_PIN46_IOPORT IOPORT2
#define TEENSY_PIN0_IOPORT IOPORT2
#define TEENSY_PIN1_IOPORT IOPORT2
#define TEENSY_PIN29_IOPORT IOPORT2
#define TEENSY_PIN30_IOPORT IOPORT2
#define TEENSY_PIN31_IOPORT IOPORT2
#define TEENSY_PIN32_IOPORT IOPORT2
#define TEENSY_PIN16_IOPORT IOPORT2
#define TEENSY_PIN17_IOPORT IOPORT2
#define TEENSY_PIN19_IOPORT IOPORT2
#define TEENSY_PIN18_IOPORT IOPORT2
#define TEENSY_PIN15 0
#define TEENSY_PIN22 1
#define TEENSY_PIN23 2
#define TEENSY_PIN9 3
#define TEENSY_PIN10 4
#define TEENSY_PIN13 5
#define TEENSY_PIN11 6
#define TEENSY_PIN12 7
#define TEENSY_PIN35 8
#define TEENSY_PIN36 9
#define TEENSY_PIN37 10
#define TEENSY_PIN38 11
#define PORTC_PIN12 12
#define PORTC_PIN13 13
#define PORTC_PIN14 14
#define PORTC_PIN15 15
#define PORTC_PIN16 16
#define PORTC_PIN17 17
#define PORTC_PIN18 18
#define PORTC_PIN19 19
#define PORTC_PIN20 20
#define PORTC_PIN21 21
#define PORTC_PIN22 22
#define PORTC_PIN23 23
#define PORTC_PIN24 24
#define PORTC_PIN25 25
#define PORTC_PIN26 26
#define PORTC_PIN27 27
#define PORTC_PIN28 28
#define PORTC_PIN29 29
#define PORTC_PIN30 30
#define PORTC_PIN31 31
#define TEENSY_PIN9_IOPORT IOPORT3
#define TEENSY_PIN10_IOPORT IOPORT3
#define TEENSY_PIN11_IOPORT IOPORT3
#define TEENSY_PIN12_IOPORT IOPORT3
#define TEENSY_PIN35_IOPORT IOPORT3
#define TEENSY_PIN36_IOPORT IOPORT3
#define TEENSY_PIN37_IOPORT IOPORT3
#define TEENSY_PIN38_IOPORT IOPORT3
#define TEENSY_PIN13_IOPORT IOPORT3
#define TEENSY_PIN15_IOPORT IOPORT3
#define TEENSY_PIN22_IOPORT IOPORT3
#define TEENSY_PIN23_IOPORT IOPORT3
#define TEENSY_PIN2 0
#define TEENSY_PIN14 1
#define TEENSY_PIN7 2
#define TEENSY_PIN8 3
#define TEENSY_PIN6 4
#define TEENSY_PIN20 5
#define TEENSY_PIN21 6
#define TEENSY_PIN5 7
#define TEENSY_PIN47 8
#define TEENSY_PIN48 9
#define PORTD_PIN10 10
#define TEENSY_PIN55 11
#define TEENSY_PIN53 12
#define TEENSY_PIN52 13
#define TEENSY_PIN51 14
#define TEENSY_PIN54 15
#define PORTD_PIN16 16
#define PORTD_PIN17 17
#define PORTD_PIN18 18
#define PORTD_PIN19 19
#define PORTD_PIN20 20
#define PORTD_PIN21 21
#define PORTD_PIN22 22
#define PORTD_PIN23 23
#define PORTD_PIN24 24
#define PORTD_PIN25 25
#define PORTD_PIN26 26
#define PORTD_PIN27 27
#define PORTD_PIN28 28
#define PORTD_PIN29 29
#define PORTD_PIN30 30
#define PORTD_PIN31 31
#define TEENSY_PIN51_IOPORT IOPORT4
#define TEENSY_PIN52_IOPORT IOPORT4
#define TEENSY_PIN53_IOPORT IOPORT4
#define TEENSY_PIN54_IOPORT IOPORT4
#define TEENSY_PIN55_IOPORT IOPORT4
#define TEENSY_PIN47_IOPORT IOPORT4
#define TEENSY_PIN48_IOPORT IOPORT4
#define TEENSY_PIN2_IOPORT IOPORT4
#define TEENSY_PIN5_IOPORT IOPORT4
#define TEENSY_PIN6_IOPORT IOPORT4
#define TEENSY_PIN7_IOPORT IOPORT4
#define TEENSY_PIN8_IOPORT IOPORT4
#define TEENSY_PIN14_IOPORT IOPORT4
#define TEENSY_PIN20_IOPORT IOPORT4
#define TEENSY_PIN21_IOPORT IOPORT4
#define PORTE_PIN0 0
#define PORTE_PIN1 1
#define PORTE_PIN2 2
#define PORTE_PIN3 3
#define PORTE_PIN4 4
#define PORTE_PIN5 5
#define PORTE_PIN6 6
#define PORTE_PIN7 7
#define PORTE_PIN8 8
#define PORTE_PIN9 9
#define TEENSY_PIN56 10
#define TEENSY_PIN57 11
#define PORTE_PIN12 12
#define PORTE_PIN13 13
#define PORTE_PIN14 14
#define PORTE_PIN15 15
#define PORTE_PIN16 16
#define PORTE_PIN17 17
#define PORTE_PIN18 18
#define PORTE_PIN19 19
#define PORTE_PIN20 20
#define PORTE_PIN21 21
#define PORTE_PIN22 22
#define PORTE_PIN23 23
#define TEENSY_PIN33 24
#define TEENSY_PIN34 25
#define TEENSY_PIN24 26
#define PORTE_PIN27 27
#define PORTE_PIN28 28
#define PORTE_PIN29 29
#define PORTE_PIN30 30
#define PORTE_PIN31 31
#define TEENSY_PIN56_IOPORT IOPORT5
#define TEENSY_PIN57_IOPORT IOPORT5
#define TEENSY_PIN24_IOPORT IOPORT5
#define TEENSY_PIN33_IOPORT IOPORT5
#define TEENSY_PIN34_IOPORT IOPORT5
#define LINE_PIN0 PAL_LINE(TEENSY_PIN0_IOPORT, TEENSY_PIN0)
#define LINE_PIN1 PAL_LINE(TEENSY_PIN1_IOPORT, TEENSY_PIN1)
#define LINE_PIN2 PAL_LINE(TEENSY_PIN2_IOPORT, TEENSY_PIN2)
#define LINE_PIN3 PAL_LINE(TEENSY_PIN3_IOPORT, TEENSY_PIN3)
#define LINE_PIN4 PAL_LINE(TEENSY_PIN4_IOPORT, TEENSY_PIN4)
#define LINE_PIN5 PAL_LINE(TEENSY_PIN5_IOPORT, TEENSY_PIN5)
#define LINE_PIN6 PAL_LINE(TEENSY_PIN6_IOPORT, TEENSY_PIN6)
#define LINE_PIN7 PAL_LINE(TEENSY_PIN7_IOPORT, TEENSY_PIN7)
#define LINE_PIN8 PAL_LINE(TEENSY_PIN8_IOPORT, TEENSY_PIN8)
#define LINE_PIN9 PAL_LINE(TEENSY_PIN9_IOPORT, TEENSY_PIN9)
#define LINE_PIN10 PAL_LINE(TEENSY_PIN10_IOPORT, TEENSY_PIN10)
#define LINE_PIN11 PAL_LINE(TEENSY_PIN11_IOPORT, TEENSY_PIN11)
#define LINE_PIN12 PAL_LINE(TEENSY_PIN12_IOPORT, TEENSY_PIN12)
#define LINE_PIN13 PAL_LINE(TEENSY_PIN13_IOPORT, TEENSY_PIN13)
#define LINE_PIN14 PAL_LINE(TEENSY_PIN14_IOPORT, TEENSY_PIN14)
#define LINE_PIN15 PAL_LINE(TEENSY_PIN15_IOPORT, TEENSY_PIN15)
#define LINE_PIN16 PAL_LINE(TEENSY_PIN16_IOPORT, TEENSY_PIN16)
#define LINE_PIN17 PAL_LINE(TEENSY_PIN17_IOPORT, TEENSY_PIN17)
#define LINE_PIN18 PAL_LINE(TEENSY_PIN18_IOPORT, TEENSY_PIN18)
#define LINE_PIN19 PAL_LINE(TEENSY_PIN19_IOPORT, TEENSY_PIN19)
#define LINE_PIN20 PAL_LINE(TEENSY_PIN20_IOPORT, TEENSY_PIN20)
#define LINE_PIN21 PAL_LINE(TEENSY_PIN21_IOPORT, TEENSY_PIN21)
#define LINE_PIN22 PAL_LINE(TEENSY_PIN22_IOPORT, TEENSY_PIN22)
#define LINE_PIN23 PAL_LINE(TEENSY_PIN23_IOPORT, TEENSY_PIN23)
#define LINE_PIN24 PAL_LINE(TEENSY_PIN24_IOPORT, TEENSY_PIN24)
#define LINE_PIN25 PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25)
#define LINE_PIN25 PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25)
#define LINE_PIN26 PAL_LINE(TEENSY_PIN26_IOPORT, TEENSY_PIN26)
#define LINE_PIN27 PAL_LINE(TEENSY_PIN27_IOPORT, TEENSY_PIN27)
#define LINE_PIN28 PAL_LINE(TEENSY_PIN28_IOPORT, TEENSY_PIN28)
#define LINE_PIN29 PAL_LINE(TEENSY_PIN29_IOPORT, TEENSY_PIN29)
#define LINE_PIN30 PAL_LINE(TEENSY_PIN30_IOPORT, TEENSY_PIN30)
#define LINE_PIN31 PAL_LINE(TEENSY_PIN31_IOPORT, TEENSY_PIN31)
#define LINE_PIN32 PAL_LINE(TEENSY_PIN32_IOPORT, TEENSY_PIN32)
#define LINE_PIN33 PAL_LINE(TEENSY_PIN33_IOPORT, TEENSY_PIN33)
#define LINE_PIN34 PAL_LINE(TEENSY_PIN34_IOPORT, TEENSY_PIN34)
#define LINE_PIN35 PAL_LINE(TEENSY_PIN35_IOPORT, TEENSY_PIN35)
#define LINE_PIN36 PAL_LINE(TEENSY_PIN36_IOPORT, TEENSY_PIN36)
#define LINE_PIN37 PAL_LINE(TEENSY_PIN37_IOPORT, TEENSY_PIN37)
#define LINE_PIN38 PAL_LINE(TEENSY_PIN38_IOPORT, TEENSY_PIN38)
#define LINE_PIN39 PAL_LINE(TEENSY_PIN39_IOPORT, TEENSY_PIN39)
#define LINE_PIN40 PAL_LINE(TEENSY_PIN40_IOPORT, TEENSY_PIN40)
#define LINE_PIN41 PAL_LINE(TEENSY_PIN41_IOPORT, TEENSY_PIN41)
#define LINE_PIN42 PAL_LINE(TEENSY_PIN42_IOPORT, TEENSY_PIN42)
#define LINE_PIN43 PAL_LINE(TEENSY_PIN43_IOPORT, TEENSY_PIN43)
#define LINE_PIN44 PAL_LINE(TEENSY_PIN44_IOPORT, TEENSY_PIN44)
#define LINE_PIN45 PAL_LINE(TEENSY_PIN45_IOPORT, TEENSY_PIN45)
#define LINE_PIN46 PAL_LINE(TEENSY_PIN46_IOPORT, TEENSY_PIN46)
#define LINE_PIN47 PAL_LINE(TEENSY_PIN47_IOPORT, TEENSY_PIN47)
#define LINE_PIN48 PAL_LINE(TEENSY_PIN48_IOPORT, TEENSY_PIN48)
#define LINE_PIN49 PAL_LINE(TEENSY_PIN49_IOPORT, TEENSY_PIN49)
#define LINE_PIN50 PAL_LINE(TEENSY_PIN50_IOPORT, TEENSY_PIN50)
#define LINE_PIN51 PAL_LINE(TEENSY_PIN51_IOPORT, TEENSY_PIN50)
#define LINE_PIN52 PAL_LINE(TEENSY_PIN52_IOPORT, TEENSY_PIN52)
#define LINE_PIN53 PAL_LINE(TEENSY_PIN53_IOPORT, TEENSY_PIN53)
#define LINE_PIN54 PAL_LINE(TEENSY_PIN54_IOPORT, TEENSY_PIN54)
#define LINE_PIN55 PAL_LINE(TEENSY_PIN55_IOPORT, TEENSY_PIN55)
#define LINE_PIN56 PAL_LINE(TEENSY_PIN56_IOPORT, TEENSY_PIN56)
#define LINE_PIN57 PAL_LINE(TEENSY_PIN57_IOPORT, TEENSY_PIN57)
#define LINE_LED LINE_PIN13
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */
#endif /* _BOARD_H_ */

View File

@ -0,0 +1,5 @@
# List of all the board related files.
BOARDSRC = ${CHIBIOS_CONTRIB}/os/hal/boards/PJRC_TEENSY_3_6/board.c
# Required include directories
BOARDINC = ${CHIBIOS_CONTRIB}/os/hal/boards/PJRC_TEENSY_3_6

View File

@ -442,7 +442,13 @@ static inline msg_t _i2c_txrx_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* wait until the bus is released */
/* Calculating the time window for the timeout on the busy bus condition.*/
start = osalOsGetSystemTimeX();
#if defined(OSAL_TIME_MS2I)
end = start + OSAL_TIME_MS2I(KINETIS_I2C_BUSY_TIMEOUT);
#elif defined(OSAL_TIME_MS2ST)
end = start + OSAL_TIME_MS2ST(KINETIS_I2C_BUSY_TIMEOUT);
#else
end = start + OSAL_MS2ST(KINETIS_I2C_BUSY_TIMEOUT);
#endif
while(true) {
osalSysLock();

View File

@ -29,7 +29,7 @@
* or write).
*
* The SDHC signals must be routed to the desired pins, and pullups/pulldowns
* configured.
* configured.
*
* @addtogroup SDC
* @{
@ -45,8 +45,13 @@
/* Driver local definitions. */
/*===========================================================================*/
#if defined(MK66F18)
/* Configure SDHC block to use the IRC48M clock */
#define KINETIS_SDHC_PERIPHERAL_FREQUENCY 48000000UL
#else
/* We configure the SDHC block to use the system clock */
#define KINETIS_SDHC_PERIPHERAL_FREQUENCY KINETIS_SYSCLK_FREQUENCY
#endif
#ifndef KINETIS_SDHC_PRIORITY
#define KINETIS_SDHC_PRIORITY 12 /* TODO? Default IRQ priority for SDHC */
@ -189,6 +194,11 @@ static void enable_clock_when_stable(uint32_t new_sysctl)
/* Restart the clock */
SDHC->SYSCTL = new_sysctl | SDHC_SYSCTL_SDCLKEN;
/* Wait for clock to stabilize again */
while(!(SDHC->PRSSTAT & SDHC_PRSSTAT_SDSTB)) {
osalThreadSleepMilliseconds(1);
}
}
/**
@ -589,9 +599,15 @@ void sdc_lld_init(void) {
void sdc_lld_start(SDCDriver *sdcp) {
if (sdcp->state == BLK_STOP) {
#if defined(MK66F18)
/* Use IRC48M clock for SDHC */
SIM->SOPT2 |= SIM_SOPT2_SDHCSRC(1);
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_SET(3);
#else
SIM->SOPT2 =
(SIM->SOPT2 & ~SIM_SOPT2_SDHCSRC_MASK) |
SIM_SOPT2_SDHCSRC(0); /* SDHC clock source 0: Core/system clock. */
#endif
SIM->SCGC3 |= SIM_SCGC3_SDHC; /* Enable clock to SDHC peripheral */
/* Reset the SDHC block */

View File

@ -262,7 +262,7 @@ static void configure_uart(SerialDriver *sdp, const SerialConfig *config) {
}
#endif /* KINETIS_SERIAL_USE_UART0 */
#elif defined(K20x) || defined(K60x) /* KL2x */
#elif defined(K20x) || defined(K60x) || defined(MK66F18) /* KL2x */
/* UARTs 0 and 1 are clocked from SYSCLK, others from BUSCLK on K20x and K60x. */
#if KINETIS_SERIAL_USE_UART0

View File

@ -395,9 +395,10 @@ void usb_lld_init(void) {
#if KINETIS_USB_USE_USB0
/* Set USB clock source to MCGPLLCLK, MCGFLLCLK, USB1 PFD, or IRC48M */
SIM->SOPT2 |= SIM_SOPT2_USBSRC;
#if defined(K20x5) || defined(K20x7)
#if defined(K20x5) || defined(K20x7) || defined(MK66F18)
#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
@ -406,6 +407,8 @@ void usb_lld_init(void) {
#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
#if !defined(MK66F18)
/* Note: We don't need this for MK66F18, we can use IRC48M clock for USB */
#define KINETIS_USBCLK_FREQUENCY 48000000UL
uint32_t i,j;
for(i=0; i < 2; i++) {
@ -418,11 +421,18 @@ void usb_lld_init(void) {
}
usbfrac_match_found:
osalDbgAssert(i<2 && j <8,"USB Init error");
#endif
#else /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */
#error USB clock setting not implemented for this KINETIS_MCG_MODE
#endif /* KINETIS_MCG_MODE == ... */
#if defined(MK66F18)
/* Switch from default MCGPLLCLK to IRC48M for USB */
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0);
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_SET(3);
#endif
#elif defined(KL25) || defined (KL26) || defined(KL27)
/* No extra clock dividers for USB clock */
@ -452,9 +462,15 @@ void usb_lld_start(USBDriver *usbp) {
_bdt[i].addr=0;
}
#if defined(MK66F18)
/* Disable the USB current limiter */
SIM->USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM;
#endif
/* Enable Clock */
#if KINETIS_USB0_IS_USBOTG
SIM->SCGC4 |= SIM_SCGC4_USBOTG;
#else /* KINETIS_USB0_IS_USBOTG */
SIM->SCGC4 |= SIM_SCGC4_USBFS;
#endif /* KINETIS_USB0_IS_USBOTG */

View File

@ -0,0 +1,243 @@
/*
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MK66F18/hal_lld.c
* @brief Kinetis MK66F18 HAL Driver subsystem low level driver source template.
*
* @addtogroup HAL
* @{
*/
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
#ifdef __CC_ARM
__attribute__ ((section(".ARM.__at_0x400")))
#else
__attribute__ ((used,section(".cfmconfig")))
#endif
const uint8_t _cfm[0x10] = {
0xFF, /* NV_BACKKEY3: KEY=0xFF */
0xFF, /* NV_BACKKEY2: KEY=0xFF */
0xFF, /* NV_BACKKEY1: KEY=0xFF */
0xFF, /* NV_BACKKEY0: KEY=0xFF */
0xFF, /* NV_BACKKEY7: KEY=0xFF */
0xFF, /* NV_BACKKEY6: KEY=0xFF */
0xFF, /* NV_BACKKEY5: KEY=0xFF */
0xFF, /* NV_BACKKEY4: KEY=0xFF */
0xFF, /* NV_FPROT3: PROT=0xFF */
0xFF, /* NV_FPROT2: PROT=0xFF */
0xFF, /* NV_FPROT1: PROT=0xFF */
0xFF, /* NV_FPROT0: PROT=0xFF */
0x7E, /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */
0xFF, /* NV_FOPT: ??=1,??=1,FAST_INIT=1,LPBOOT1=1,RESET_PIN_CFG=1,
NMI_DIS=1,EZPORT_DIS=1,LPBOOT0=1 */
0xFF,
0xFF
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
* @todo Use a macro to define the system clock frequency.
*
* @notapi
*/
void hal_lld_init(void) {
#if defined(MK66F18)
/* Disable the MPU by default */
SYSMPU->CESR &= ~SYSMPU_CESR_VLD_MASK;
#endif
}
/**
* @brief MK66F18 clock initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function is meant to be invoked early during the system
* initialization, it is usually invoked from the file
* @p board.c.
* @todo This function needs to be more generic.
*
* @special
*/
void MK66F18_clock_init(void) {
#if !KINETIS_NO_INIT
/* Disable the watchdog */
WDOG->UNLOCK = 0xC520;
WDOG->UNLOCK = 0xD928;
WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN;
SIM->SCGC5 |= SIM_SCGC5_PORTA |
SIM_SCGC5_PORTB |
SIM_SCGC5_PORTC |
SIM_SCGC5_PORTD |
SIM_SCGC5_PORTE;
#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
/* This is the default mode at reset. */
/* Configure FEI mode */
MCG->C4 = MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS) |
(KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0);
/* Set clock dividers */
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
#if defined(MK66F18)
SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3-1) |
#endif
SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0); /* not strictly necessary since usb_lld will set this */
#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
uint32_t ratio, frdiv;
uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 };
uint8_t ratio_quantity = sizeof(ratios) / sizeof(ratios[0]);
uint8_t i;
/* EXTAL0 and XTAL0 */
PORTA->PCR[18] = 0;
PORTA->PCR[19] = 0;
/*
* Start in FEI mode
*/
/* Internal capacitors for crystal */
#if defined(KINETIS_BOARD_OSCILLATOR_SETTING)
OSC0->CR = KINETIS_BOARD_OSCILLATOR_SETTING;
#else /* KINETIS_BOARD_OSCILLATOR_SETTING */
/* Disable the internal capacitors */
OSC0->CR = 0;
#endif /* KINETIS_BOARD_OSCILLATOR_SETTING */
/* TODO: need to add more flexible calculation, specially regarding
* divisors which may not be available depending on the XTAL
* frequency, which would required other registers to be modified.
*/
/* Enable OSC, low power mode */
if (KINETIS_XTAL_FREQUENCY > 8000000UL)
MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(2);
else
MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(1);
frdiv = 7;
ratio = KINETIS_XTAL_FREQUENCY / 31250UL;
for (i = 0; i < ratio_quantity; ++i) {
if (ratio == ratios[i]) {
frdiv = i;
break;
}
}
/* Switch to crystal as clock source, FLL input of 31.25 KHz */
MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv);
/* Wait for crystal oscillator to begin */
while (!(MCG->S & MCG_S_OSCINIT0));
/* Wait for the FLL to use the oscillator */
while (MCG->S & MCG_S_IREFST);
/* Wait for the MCGOUTCLK to use the oscillator */
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2));
/*
* Now in FBE mode
*/
#define KINETIS_PLLIN_FREQUENCY 2000000UL
/*
* Config PLL input for 2 MHz
* TODO: Make sure KINETIS_XTAL_FREQUENCY >= 2Mhz && <= 50Mhz
*/
MCG->C5 = MCG_C5_PRDIV0((KINETIS_XTAL_FREQUENCY/KINETIS_PLLIN_FREQUENCY) - 1);
/*
* Config PLL output to match KINETIS_SYSCLK_FREQUENCY
* TODO: make sure KINETIS_SYSCLK_FREQUENCY is a match
*/
for(i = 24; i < 56; i++)
{
if(i == (KINETIS_PLLCLK_FREQUENCY/KINETIS_PLLIN_FREQUENCY))
{
/* Config PLL to match KINETIS_PLLCLK_FREQUENCY */
MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(i-24);
break;
}
}
if(i>=56) /* Config PLL for 96 MHz output as default setting */
MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
/* Wait for PLL to start using crystal as its input, and to lock */
while ((MCG->S & (MCG_S_PLLST|MCG_S_LOCK0))!=(MCG_S_PLLST|MCG_S_LOCK0));
/*
* Now in PBE mode
*/
/* Set the PLL dividers for the different clocks */
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0);
/* Configure peripherals to use MCGPLLCLK */
SIM->SOPT2 = SIM_SOPT2_PLLFLLSEL;
/* Switch to PLL as clock source */
MCG->C1 = MCG_C1_CLKS(0);
/* Wait for PLL clock to be used */
while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL);
/*
* Now in PEE mode
*/
#else /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */
#error Unimplemented KINETIS_MCG_MODE
#endif /* KINETIS_MCG_MODE == ... */
#endif /* !KINETIS_NO_INIT */
}
/** @} */

View File

@ -0,0 +1,322 @@
/*
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MK66F18/hal_lld.h
* @brief Kinetis MK66F18 HAL subsystem low level driver header.
*
* @addtogroup HAL
* @{
*/
#ifndef HAL_LLD_H_
#define HAL_LLD_H_
#include "kinetis_registry.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"
/** @} */
/**
* @name Internal clock sources
* @{
*/
#define KINETIS_IRCLK_F 4000000 /**< Fast internal reference clock, factory trimmed. */
#define KINETIS_IRCLK_S 32768 /**< Slow internal reference clock, factory trimmed. */
/** @} */
#define KINETIS_MCG_MODE_FEI 1 /**< FLL Engaged Internal. */
#define KINETIS_MCG_MODE_FEE 2 /**< FLL Engaged External. */
#define KINETIS_MCG_MODE_FBI 3 /**< FLL Bypassed Internal. */
#define KINETIS_MCG_MODE_FBE 4 /**< FLL Bypassed External. */
#define KINETIS_MCG_MODE_PEE 5 /**< PLL Engaged External. */
#define KINETIS_MCG_MODE_PBE 6 /**< PLL Bypassed External. */
#define KINETIS_MCG_MODE_BLPI 7 /**< Bypassed Low Power Internal. */
#define KINETIS_MCG_MODE_BLPE 8 /**< Bypassed Low Power External. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief Disables the MCG/system clock initialization in the HAL.
*/
#if !defined(KINETIS_NO_INIT) || defined(__DOXYGEN__)
#define KINETIS_NO_INIT FALSE
#endif
/**
* @brief MCG mode selection.
*/
#if !defined(KINETIS_MCG_MODE) || defined(__DOXYGEN__)
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
#endif
/**
* @brief MCU PLL clock frequency.
*/
#if !defined(KINETIS_PLLCLK_FREQUENCY) || defined(__DOXYGEN__)
#define KINETIS_PLLCLK_FREQUENCY 96000000UL
#endif
/**
* @brief Clock divider for core/system clocks (OUTDIV1).
* @note The allowed range is 1..16
* @note The default value is calculated for a 48 MHz system clock
* from a 96 MHz PLL output.
*/
#if !defined(KINETIS_CLKDIV1_OUTDIV1) || defined(__DOXYGEN__)
#if defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV1 (KINETIS_PLLCLK_FREQUENCY/KINETIS_SYSCLK_FREQUENCY)
#else
#define KINETIS_CLKDIV1_OUTDIV1 2
#endif
#endif
/**
* @brief Clock divider for bus clock (OUTDIV2).
* @note The allowed range is 1..16
* @note The default value is calculated for a 48 MHz bus clock
* from a 96 MHz PLL output.
*/
#if !defined(KINETIS_CLKDIV1_OUTDIV2) || defined(__DOXYGEN__)
#if defined(KINETIS_BUSCLK_FREQUENCY) && KINETIS_BUSCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV2 (KINETIS_PLLCLK_FREQUENCY/KINETIS_BUSCLK_FREQUENCY)
#elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV2 KINETIS_CLKDIV1_OUTDIV1
#else
#define KINETIS_CLKDIV1_OUTDIV2 2
#endif
#endif
/**
* @brief Clock divider for FlexBus clock (OUTDIV3).
* @note The allowed range is 1..16
* @note The default value is calculated for a 48 MHz clock
* from a 96 MHz PLL output.
*/
#if !defined(KINETIS_CLKDIV1_OUTDIV3) || defined(__DOXYGEN__)
#if defined(KINETIS_FLEXBUSCLK_FREQUENCY) && KINETIS_FLEXBUSCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV3 (KINETIS_PLLCLK_FREQUENCY/KINETIS_FLEXBUSCLK_FREQUENCY)
#else
/* If no FlexBus frequency provided, use bus speed divider */
#define KINETIS_CLKDIV1_OUTDIV3 KINETIS_CLKDIV1_OUTDIV2
#endif
#endif
/**
* @brief Clock divider for flash clock (OUTDIV4).
* @note The allowed range is 1..16
* @note The default value is calculated for a 24 MHz flash clock
* from a 96 MHz PLL output
*/
#if !defined(KINETIS_CLKDIV1_OUTDIV4) || defined(__DOXYGEN__)
#if defined(KINETIS_FLASHCLK_FREQUENCY) && KINETIS_FLASHCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_PLLCLK_FREQUENCY/KINETIS_FLASHCLK_FREQUENCY)
#elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
#define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_CLKDIV1_OUTDIV1*2)
#else
#define KINETIS_CLKDIV1_OUTDIV4 4
#endif
#endif
/**
* @brief FLL DCO tuning enable for 32.768 kHz reference.
* @note Set to 1 for fine-tuning DCO for maximum frequency with
* a 32.768 kHz reference.
* @note The default value is for a 32.768 kHz external crystal.
*/
#if !defined(KINETIS_MCG_FLL_DMX32) || defined(__DOXYGEN__)
#define KINETIS_MCG_FLL_DMX32 1
#endif
/**
* @brief FLL DCO range selection.
* @note The allowed range is 0...3.
* @note The default value is calculated for 48 MHz FLL output
* from a 32.768 kHz external crystal.
* (DMX32 && DRST_DRS=1 => F=1464; 32.768 kHz * F ~= 48 MHz.)
*
*/
#if !defined(KINETIS_MCG_FLL_DRS) || defined(__DOXYGEN__)
#define KINETIS_MCG_FLL_DRS 2
#endif
/**
* @brief MCU system/core clock frequency.
*/
#if !defined(KINETIS_SYSCLK_FREQUENCY) || defined(__DOXYGEN__)
#define KINETIS_SYSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV1)
#endif
/**
* @brief MCU bus clock frequency.
*/
#if !defined(KINETIS_BUSCLK_FREQUENCY) || defined(__DOXYGEN__)
#define KINETIS_BUSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV2)
#endif
/**
* @brief MCU flash clock frequency.
*/
#if !defined(KINETIS_FLASHCLK_FREQUENCY) || defined(__DOXYGEN__)
#define KINETIS_FLASHCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV4)
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !defined(KINETIS_SYSCLK_FREQUENCY)
#error KINETIS_SYSCLK_FREQUENCY must be defined
#endif
#if KINETIS_SYSCLK_FREQUENCY <= 0 || KINETIS_SYSCLK_FREQUENCY > KINETIS_SYSCLK_MAX
#error KINETIS_SYSCLK_FREQUENCY out of range
#endif
#if !defined(KINETIS_BUSCLK_FREQUENCY)
#error KINETIS_BUSCLK_FREQUENCY must be defined
#endif
#if KINETIS_BUSCLK_FREQUENCY <= 0 || KINETIS_BUSCLK_FREQUENCY > KINETIS_BUSCLK_MAX
#error KINETIS_BUSCLK_FREQUENCY out of range
#endif
#if KINETIS_BUSCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
#error KINETIS_BUSCLK_FREQUENCY must be an integer divide of\
KINETIS_SYSCLK_FREQUENCY
#endif
#if !defined(KINETIS_FLASHCLK_FREQUENCY)
#error KINETIS_FLASHCLK_FREQUENCY must be defined
#endif
#if KINETIS_FLASHCLK_FREQUENCY <= 0 || KINETIS_FLASHCLK_FREQUENCY > KINETIS_FLASHCLK_MAX
#error KINETIS_FLASHCLK_FREQUENCY out of range
#endif
#if KINETIS_FLASHCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
#error KINETIS_FLASHCLK_FREQUENCY must be an integer divide of\
KINETIS_SYSCLK_FREQUENCY
#endif
#if !(defined(KINETIS_CLKDIV1_OUTDIV1) && \
KINETIS_CLKDIV1_OUTDIV1 >= 1 && KINETIS_CLKDIV1_OUTDIV1 <= 16)
#error KINETIS_CLKDIV1_OUTDIV1 must be 1 through 16
#endif
#if !(defined(KINETIS_CLKDIV1_OUTDIV2) && \
KINETIS_CLKDIV1_OUTDIV2 >= 1 && KINETIS_CLKDIV1_OUTDIV2 <= 16)
#error KINETIS_CLKDIV1_OUTDIV2 must be 1 through 16
#endif
#if !(defined(KINETIS_CLKDIV1_OUTDIV3) && \
KINETIS_CLKDIV1_OUTDIV3 >= 1 && KINETIS_CLKDIV1_OUTDIV3 <= 16)
#error KINETIS_CLKDIV1_OUTDIV3 must be 1 through 16
#endif
#if !(defined(KINETIS_CLKDIV1_OUTDIV4) && \
KINETIS_CLKDIV1_OUTDIV4 >= 1 && KINETIS_CLKDIV1_OUTDIV4 <= 16)
#error KINETIS_CLKDIV1_OUTDIV4 must be 1 through 16
#endif
#if !(KINETIS_MCG_FLL_DMX32 == 0 || KINETIS_MCG_FLL_DMX32 == 1)
#error Invalid KINETIS_MCG_FLL_DMX32 value, must be 0 or 1
#endif
#if !(0 <= KINETIS_MCG_FLL_DRS && KINETIS_MCG_FLL_DRS <= 3)
#error Invalid KINETIS_MCG_FLL_DRS value, must be 0...3
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @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 MK66F18_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,390 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Adam J. Porter
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 MK66F18/pwm_lld.c
* @brief KINETIS PWM subsystem low level driver source.
*
* @addtogroup PWM
* @{
*/
#include "hal.h"
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief PWMD1 driver identifier.
* @note The driver PWMD1 allocates the timer FTM0 when enabled.
*/
#if KINETIS_PWM_USE_FTM0 || defined(__DOXYGEN__)
PWMDriver PWMD1;
#endif
/**
* @brief PWMD2 driver identifier.
* @note The driver PWMD2 allocates the timer FTM1 when enabled.
*/
#if KINETIS_PWM_USE_FTM1 || defined(__DOXYGEN__)
PWMDriver PWMD2;
#endif
/**
* @brief PWMD3 driver identifier.
* @note The driver PWMD3 allocates the timer FTM2 when enabled.
*/
#if KINETIS_PWM_USE_FTM2 || defined(__DOXYGEN__)
PWMDriver PWMD3;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
uint32_t sr;
sr = pwmp->ftm->SC;
pwmp->ftm->SC = sr&(~FTM_SC_TOF);
if (((sr & FTM_SC_TOF) != 0) && /* Timer Overflow */
((sr & FTM_SC_TOIE) != 0) &&
(pwmp->config->callback != NULL)) {
pwmp->config->callback(pwmp);
}
uint8_t n=0;
for(n=0;n<pwmp->channels;n++) {
sr = pwmp->ftm->CHANNEL[n].CnSC;
pwmp->ftm->CHANNEL[n].CnSC = sr&(~FTM_CnSC_CHF);
if (((sr & FTM_CnSC_CHF) != 0) &&
((sr & FTM_CnSC_CHIE) != 0) &&
(pwmp->config->channels[n].callback != NULL)) {
pwmp->config->channels[n].callback(pwmp);
}
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if KINETIS_PWM_USE_FTM0
/**
* @brief FTM0 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(KINETIS_FTM0_IRQ_VECTOR) {
OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD1);
OSAL_IRQ_EPILOGUE();
}
#endif /* KINETIS_PWM_USE_FTM0 */
#if KINETIS_PWM_USE_FTM1
/**
* @brief FTM1 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(KINETIS_FTM1_IRQ_VECTOR) {
OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD2);
OSAL_IRQ_EPILOGUE();
}
#endif /* KINETIS_PWM_USE_FTM1 */
#if KINETIS_PWM_USE_FTM2
/**
* @brief FTM2 interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(KINETIS_FTM2_IRQ_VECTOR) {
OSAL_IRQ_PROLOGUE();
pwm_lld_serve_interrupt(&PWMD3);
OSAL_IRQ_EPILOGUE();
}
#endif /* KINETIS_PWM_USE_FTM2 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level PWM driver initialization.
*
* @notapi
*/
void pwm_lld_init(void) {
#if KINETIS_PWM_USE_FTM0
pwmObjectInit(&PWMD1);
PWMD1.channels = KINETIS_FTM0_CHANNELS;
PWMD1.ftm = FTM0;
#endif
#if KINETIS_PWM_USE_FTM1
pwmObjectInit(&PWMD2);
PWMD2.channels = KINETIS_FTM1_CHANNELS;
PWMD2.ftm = FTM1;
#endif
#if KINETIS_PWM_USE_FTM2
pwmObjectInit(&PWMD3);
PWMD3.channels = KINETIS_FTM2_CHANNELS;
PWMD3.ftm = FTM2;
#endif
}
/**
* @brief Configures and activates the PWM peripheral.
* @note Starting a driver that is already in the @p PWM_READY state
* disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_start(PWMDriver *pwmp) {
uint16_t psc;
uint8_t i=0;
if (pwmp->state == PWM_STOP) {
/* Clock activation and timer reset.*/
#if KINETIS_PWM_USE_FTM0
if (&PWMD1 == pwmp) {
SIM->SCGC6 |= SIM_SCGC6_FTM0;
nvicEnableVector(FTM0_IRQn, KINETIS_PWM_FTM0_PRIORITY);
}
#endif
#if KINETIS_PWM_USE_FTM1
if (&PWMD2 == pwmp) {
SIM->SCGC6 |= SIM_SCGC6_FTM1;
nvicEnableVector(FTM1_IRQn, KINETIS_PWM_FTM1_PRIORITY);
}
#endif
#if KINETIS_PWM_USE_FTM2
if (&PWMD3 == pwmp) {
SIM->SCGC3 |= SIM_SCGC3_FTM2;
nvicEnableVector(FTM2_IRQn, KINETIS_PWM_FTM2_PRIORITY);
}
#endif
}
pwmp->ftm->MODE = FTM_MODE_FTMEN_MASK|FTM_MODE_PWMSYNC_MASK;
pwmp->ftm->SYNC = FTM_SYNC_CNTMIN_MASK|FTM_SYNC_CNTMAX_MASK
|FTM_SYNC_SWSYNC_MASK;
pwmp->ftm->COMBINE = FTM_COMBINE_SYNCEN3_MASK | FTM_COMBINE_SYNCEN2_MASK
| FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN0_MASK;
pwmp->ftm->SYNCONF = FTM_SYNCONF_SYNCMODE_MASK;
pwmp->ftm->CNTIN = 0x0000;
//~ pwmp->ftm->SC = 0; /* Disable FTM counter.*/
pwmp->ftm->CNT = 0x0000; /* Clear count register.*/
/* Prescaler value calculation.*/
psc = (KINETIS_SYSCLK_FREQUENCY / pwmp->config->frequency);
//~ /* Prescaler must be power of two between 1 and 128.*/
osalDbgAssert(psc <= 128 && !(psc & (psc - 1)), "invalid frequency");
//~ /* Prescaler register value determination.
//~ Prescaler register value conveniently corresponds to bit position,
//~ i.e., register value for prescaler CLK/64 is 6 ((1 << 6) == 64).*/
for (i = 0; i < 8; i++) {
if (psc == (unsigned)(1 << i)) {
break;
}
}
/* Set prescaler and clock mode.
This also sets the following:
CPWMS up-counting mode
Timer overflow interrupt disabled
DMA disabled.*/
pwmp->ftm->SC = FTM_SC_CLKS(1) | FTM_SC_PS(i);
/* Configure period */
pwmp->ftm->MOD = pwmp->period-1;
pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;
}
/**
* @brief Deactivates the PWM peripheral.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_stop(PWMDriver *pwmp) {
/* If in ready state then disables the PWM clock.*/
if (pwmp->state == PWM_READY) {
#if KINETIS_PWM_USE_FTM0
if (&PWMD1 == pwmp) {
SIM->SCGC6 &= ~SIM_SCGC6_FTM0;
nvicDisableVector(FTM0_IRQn);
}
#endif
#if KINETIS_PWM_USE_FTM1
if (&PWMD2 == pwmp) {
SIM->SCGC6 &= ~SIM_SCGC6_FTM1;
nvicDisableVector(FTM1_IRQn);
}
#endif
#if KINETIS_PWM_USE_FTM2
if (&PWMD3 == pwmp) {
SIM->SCGC3 &= ~SIM_SCGC3_FTM2;
nvicDisableVector(FTM2_IRQn);
}
#endif
/* Disable FTM counter.*/
pwmp->ftm->SC = 0;
pwmp->ftm->MOD = 0;
}
}
/**
* @brief Enables a PWM channel.
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The channel is active using the specified configuration.
* @note The function has effect at the next cycle start.
* @note Channel notification is not enabled.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...channels-1)
* @param[in] width PWM pulse width as clock pulses number
*
* @notapi
*/
void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width) {
uint32_t mode = FTM_CnSC_MSB; /* Edge-aligned PWM mode.*/
switch (pwmp->config->channels[channel].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_HIGH:
mode |= FTM_CnSC_ELSB;
break;
case PWM_OUTPUT_ACTIVE_LOW:
mode |= FTM_CnSC_ELSA;
break;
}
if (pwmp->ftm->CHANNEL[channel].CnSC & FTM_CnSC_CHIE)
mode |= FTM_CnSC_CHIE;
pwmp->ftm->CHANNEL[channel].CnSC = mode;
pwmp->ftm->CHANNEL[channel].CnV = width;
pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;
}
/**
* @brief Disables a PWM channel and its notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The channel is disabled and its output line returned to the
* idle state.
* @note The function has effect at the next cycle start.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...channels-1)
*
* @notapi
*/
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
pwmp->ftm->CHANNEL[channel].CnSC = 0;
pwmp->ftm->CHANNEL[channel].CnV = 0;
}
/**
* @brief Enables the periodic activation edge notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @note If the notification is already enabled then the call has no effect.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
pwmp->ftm->SC |= FTM_SC_TOIE;
}
/**
* @brief Disables the periodic activation edge notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @note If the notification is already disabled then the call has no effect.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
pwmp->ftm->SC &= ~FTM_SC_TOIE;
}
/**
* @brief Enables a channel de-activation edge notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @pre The channel must have been activated using @p pwmEnableChannel().
* @note If the notification is already enabled then the call has no effect.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...channels-1)
*
* @notapi
*/
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
pwmchannel_t channel) {
pwmp->ftm->CHANNEL[channel].CnSC |= FTM_CnSC_CHIE;
}
/**
* @brief Disables a channel de-activation edge notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @pre The channel must have been activated using @p pwmEnableChannel().
* @note If the notification is already disabled then the call has no effect.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...channels-1)
*
* @notapi
*/
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
pwmchannel_t channel) {
pwmp->ftm->CHANNEL[channel].CnSC &= ~FTM_CnSC_CHIE;
}
#endif /* HAL_USE_PWM */
/** @} */

View File

@ -0,0 +1,270 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Adam J. Porter
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 MK66F18/pwm_lld.h
* @brief KINETIS PWM subsystem low level driver header.
*
* @addtogroup PWM
* @{
*/
#ifndef HAL_PWM_LLD_H_
#define HAL_PWM_LLD_H_
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Number of PWM channels per PWM driver.
*/
#define PWM_CHANNELS 8
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
#if !defined(KINETIS_PWM_USE_FTM0)
#define KINETIS_PWM_USE_FTM0 FALSE
#endif
#if !defined(KINETIS_PWM_USE_FTM1)
#define KINETIS_PWM_USE_FTM1 FALSE
#endif
#if !defined(KINETIS_PWM_USE_FTM2)
#define KINETIS_PWM_USE_FTM2 FALSE
#endif
/**
* @brief FTM0 interrupt priority level setting.
*/
#if !defined(KINETIS_PWM_FTM0_PRIORITY) || defined(__DOXYGEN__)
#define KINETIS_PWM_FTM0_PRIORITY 12
#endif
/**
* @brief FTM1 interrupt priority level setting.
*/
#if !defined(KINETIS_PWM_FTM1_PRIORITY) || defined(__DOXYGEN__)
#define KINETIS_PWM_FTM1_PRIORITY 12
#endif
/**
* @brief FTM2 interrupt priority level setting.
*/
#if !defined(KINETIS_PWM_FTM2_PRIORITY) || defined(__DOXYGEN__)
#define KINETIS_PWM_FTM2_PRIORITY 12
#endif
/** @} */
/**
* @name Configuration options
* @{
*/
/**
* @brief If advanced timer features switch.
* @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
* enabled.
* @note The default is @p TRUE.
*/
#if !defined(KINETIS_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
#define KINETIS_PWM_USE_ADVANCED FALSE
#endif
/** @} */
/*===========================================================================*/
/* Configuration checks. */
/*===========================================================================*/
#if !KINETIS_PWM_USE_FTM0 && !KINETIS_PWM_USE_FTM1 && !KINETIS_PWM_USE_FTM2
#error "PWM driver activated but no FTM peripheral assigned"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a PWM mode.
*/
typedef uint32_t pwmmode_t;
/**
* @brief Type of a PWM channel.
*/
typedef uint8_t pwmchannel_t;
/**
* @brief Type of a channels mask.
*/
typedef uint32_t pwmchnmsk_t;
/**
* @brief Type of a PWM counter.
*/
typedef uint16_t pwmcnt_t;
/**
* @brief Type of a PWM driver channel configuration structure.
*/
typedef struct {
/**
* @brief Channel active logic level.
*/
pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
/**
* @brief Type of a PWM driver configuration structure.
*/
typedef struct {
/**
* @brief Timer clock in Hz.
* @note The low level can use assertions in order to catch invalid
* frequency specifications.
*/
uint32_t frequency;
/**
* @brief PWM period in ticks.
* @note The low level can use assertions in order to catch invalid
* period specifications.
*/
pwmcnt_t period;
/**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
} PWMConfig;
/**
* @brief Structure representing a PWM driver.
*/
struct PWMDriver {
/**
* @brief Driver state.
*/
pwmstate_t state;
/**
* @brief Current driver configuration data.
*/
const PWMConfig *config;
/**
* @brief Current PWM period in ticks.
*/
pwmcnt_t period;
/**
* @brief Mask of the enabled channels.
*/
pwmchnmsk_t enabled;
/**
* @brief Number of channels in this instance.
*/
pwmchannel_t channels;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Pointer to the FTM registers block.
*/
FTM_TypeDef *ftm;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Changes the period the PWM peripheral.
* @details This function changes the period of a PWM unit that has already
* been activated using @p pwmStart().
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The PWM unit period is changed to the new value.
* @note The function has effect at the next cycle start.
* @note If a period is specified that is shorter than the pulse width
* programmed in one of the channels then the behavior is not
* guaranteed.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] period new cycle time in ticks
*
* @notapi
*/
#define pwm_lld_change_period(pwmp, period) \
do { \
(pwmp)->ftm->MOD = ((period) - 1); \
pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;\
} while(0)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if KINETIS_PWM_USE_FTM0 || defined(__DOXYGEN__)
extern PWMDriver PWMD1;
#endif
#if KINETIS_PWM_USE_FTM1 || defined(__DOXYGEN__)
extern PWMDriver PWMD2;
#endif
#if KINETIS_PWM_USE_FTM2 || defined(__DOXYGEN__)
extern PWMDriver PWMD3;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void pwm_lld_init(void);
void pwm_lld_start(PWMDriver *pwmp);
void pwm_lld_stop(PWMDriver *pwmp);
void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
pwmchannel_t channel);
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
pwmchannel_t channel);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PWM */
#endif /* HAL_PWM_LLD_H_ */
/** @} */

View File

@ -0,0 +1,539 @@
/*
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file KINETIS/spi_lld.c
* @brief KINETIS SPI subsystem low level driver source.
*
* @addtogroup SPI
* @{
*/
#include "hal.h"
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#if !defined(KINETIS_SPI0_RX_DMA_IRQ_PRIORITY)
#define KINETIS_SPI0_RX_DMA_IRQ_PRIORITY 8
#endif
#if !defined(KINETIS_SPI0_RX_DMAMUX_CHANNEL)
#define KINETIS_SPI0_RX_DMAMUX_CHANNEL 0
#endif
#if !defined(KINETIS_SPI0_RX_DMA_CHANNEL)
#define KINETIS_SPI0_RX_DMA_CHANNEL 0
#endif
#if !defined(KINETIS_SPI0_TX_DMAMUX_CHANNEL)
#define KINETIS_SPI0_TX_DMAMUX_CHANNEL 1
#endif
#if !defined(KINETIS_SPI0_TX_DMA_CHANNEL)
#define KINETIS_SPI0_TX_DMA_CHANNEL 1
#endif
#if !defined(KINETIS_SPI1_RX_DMA_IRQ_PRIORITY)
#define KINETIS_SPI1_RX_DMA_IRQ_PRIORITY 8
#endif
#if !defined(KINETIS_SPI1_RX_DMAMUX_CHANNEL)
#define KINETIS_SPI1_RX_DMAMUX_CHANNEL 0
#endif
#if !defined(KINETIS_SPI1_RX_DMA_CHANNEL)
#define KINETIS_SPI1_RX_DMA_CHANNEL 0
#endif
#if !defined(KINETIS_SPI1_TX_DMAMUX_CHANNEL)
#define KINETIS_SPI1_TX_DMAMUX_CHANNEL 1
#endif
#if !defined(KINETIS_SPI1_TX_DMA_CHANNEL)
#define KINETIS_SPI1_TX_DMA_CHANNEL 1
#endif
#if KINETIS_SPI_USE_SPI0
#define DMAMUX_SPI_RX_SOURCE 16
#define DMAMUX_SPI_TX_SOURCE 17
#endif
#if KINETIS_SPI_USE_SPI1
#define DMAMUX_SPI_RX_SOURCE 18
#define DMAMUX_SPI_TX_SOURCE 19
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief SPI0 driver identifier.*/
#if KINETIS_SPI_USE_SPI0 || defined(__DOXYGEN__)
SPIDriver SPID1;
#endif
/** @brief SPI1 driver identifier.*/
#if KINETIS_SPI_USE_SPI1 || defined(__DOXYGEN__)
SPIDriver SPID2;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/* Use a dummy byte as the source/destination when a buffer is not provided */
/* Note: The MMC driver relies on 0xFF being sent for dummy bytes. */
static volatile uint16_t dmaRxDummy;
static uint16_t dmaTxDummy = 0xFFFF;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void spi_start_xfer(SPIDriver *spip, bool polling)
{
/*
* Enable the DSPI peripheral in master mode.
* Clear the TX and RX FIFOs.
* */
spip->spi->MCR = SPIx_MCR_MSTR | SPIx_MCR_CLR_TXF | SPIx_MCR_CLR_RXF;
/* If we are not polling then enable DMA */
if (!polling) {
/* Enable receive dma and transmit dma */
spip->spi->RSER = SPIx_RSER_RFDF_DIRS | SPIx_RSER_RFDF_RE |
SPIx_RSER_TFFF_RE | SPIx_RSER_TFFF_DIRS;
/* Configure RX DMA */
if (spip->rxbuf) {
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].DADDR = (uint32_t)spip->rxbuf;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].DOFF = spip->word_size;
} else {
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].DADDR = (uint32_t)&dmaRxDummy;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].DOFF = 0;
}
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].BITER_ELINKNO = spip->count;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].CITER_ELINKNO = spip->count;
/* Enable Request Register (ERQ) for RX by writing 0 to SERQ */
DMA->SERQ = KINETIS_SPI0_RX_DMA_CHANNEL;
/* Configure TX DMA */
if (spip->txbuf) {
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].SADDR = (uint32_t)spip->txbuf;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].SOFF = spip->word_size;
} else {
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].SADDR = (uint32_t)&dmaTxDummy;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].SOFF = 0;
}
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].BITER_ELINKNO = spip->count;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].CITER_ELINKNO = spip->count;
/* Enable Request Register (ERQ) for TX by writing 1 to SERQ */
DMA->SERQ = KINETIS_SPI0_TX_DMA_CHANNEL;
}
}
static void spi_stop_xfer(SPIDriver *spip)
{
/* Halt the DSPI peripheral */
spip->spi->MCR = SPIx_MCR_MSTR | SPIx_MCR_HALT;
/* Clear all the flags which are currently set. */
spip->spi->SR |= spip->spi->SR;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if KINETIS_SPI_USE_SPI0 || defined(__DOXYGEN__)
OSAL_IRQ_HANDLER(KINETIS_DMA0_IRQ_VECTOR) {
OSAL_IRQ_PROLOGUE();
/* Clear bit 0 in Interrupt Request Register (INT) by writing 0 to CINT */
DMA->CINT = KINETIS_SPI0_RX_DMA_CHANNEL;
spi_stop_xfer(&SPID1);
_spi_isr_code(&SPID1);
OSAL_IRQ_EPILOGUE();
}
#endif
#if KINETIS_SPI_USE_SPI1 || defined(__DOXYGEN__)
OSAL_IRQ_HANDLER(KINETIS_DMA0_IRQ_VECTOR) {
OSAL_IRQ_PROLOGUE();
/* Clear bit 0 in Interrupt Request Register (INT) by writing 0 to CINT */
DMA->CINT = KINETIS_SPI1_RX_DMA_CHANNEL;
spi_stop_xfer(&SPID2);
_spi_isr_code(&SPID2);
OSAL_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level SPI driver initialization.
*
* @notapi
*/
void spi_lld_init(void) {
#if KINETIS_SPI_USE_SPI0
spiObjectInit(&SPID1);
#endif
#if KINETIS_SPI_USE_SPI1
spiObjectInit(&SPID2);
#endif
}
/**
* @brief Configures and activates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_start(SPIDriver *spip) {
/* If in stopped state then enables the SPI and DMA clocks.*/
if (spip->state == SPI_STOP) {
#if KINETIS_SPI_USE_SPI0
if (&SPID1 == spip) {
/* Enable the clock for SPI0 */
SIM->SCGC6 |= SIM_SCGC6_SPI0;
SPID1.spi = SPI0;
if (spip->config->tar0) {
spip->spi->CTAR[0] = spip->config->tar0;
} else {
spip->spi->CTAR[0] = KINETIS_SPI_TAR0_DEFAULT;
}
}
#endif
#if KINETIS_SPI_USE_SPI1
if (&SPID2 == spip) {
/* Enable the clock for SPI0 */
SIM->SCGC6 |= SIM_SCGC6_SPI1;
SPID2.spi = SPI1;
if (spip->config->tar0) {
spip->spi->CTAR[0] = spip->config->tar0;
} else {
spip->spi->CTAR[0] = KINETIS_SPI_TAR0_DEFAULT;
}
}
#endif
nvicEnableVector(DMA0_IRQn, KINETIS_SPI0_RX_DMA_IRQ_PRIORITY);
SIM->SCGC6 |= SIM_SCGC6_DMAMUX;
SIM->SCGC7 |= SIM_SCGC7_DMA;
/* Clear DMA error flags */
DMA->ERR = 0x0F;
#if KINETIS_SPI_USE_SPI0
/* Rx, select SPI Rx FIFO */
DMAMUX->CHCFG[KINETIS_SPI0_RX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL |
DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_RX_SOURCE);
/* Tx, select SPI Tx FIFO */
DMAMUX->CHCFG[KINETIS_SPI0_TX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL |
DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_TX_SOURCE);
/* Extract the frame size from the TAR */
uint16_t frame_size = ((spip->spi->CTAR[0] >> SPIx_CTARn_FMSZ_SHIFT) &
SPIx_CTARn_FMSZ_MASK) + 1;
/* DMA transfer size is 16 bits for a frame size > 8 bits */
uint16_t dma_size = frame_size > 8 ? 1 : 0;
/* DMA word size is 2 for a 16 bit frame size */
spip->word_size = frame_size > 8 ? 2 : 1;
/* configure DMA RX fixed values */
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].SADDR = (uint32_t)&SPI0->POPR;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].SOFF = 0;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].SLAST = 0;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].DLASTSGA = 0;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) |
DMA_ATTR_DSIZE(dma_size);
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size;
DMA->TCD[KINETIS_SPI0_RX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK |
DMA_CSR_INTMAJOR_MASK;
/* configure DMA TX fixed values */
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].SLAST = 0;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].DADDR = (uint32_t)&SPI0->PUSHR;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].DOFF = 0;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].DLASTSGA = 0;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) |
DMA_ATTR_DSIZE(dma_size);
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size;
DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK;
#endif
#if KINETIS_SPI_USE_SPI1
/* Rx, select SPI Rx FIFO */
DMAMUX->CHCFG[KINETIS_SPI1_RX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL |
DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_RX_SOURCE);
/* Tx, select SPI Tx FIFO */
DMAMUX->CHCFG[KINETIS_SPI1_TX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL |
DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_TX_SOURCE);
/* Extract the frame size from the TAR */
uint16_t frame_size = ((spip->spi->CTAR[0] >> SPIx_CTARn_FMSZ_SHIFT) &
SPIx_CTARn_FMSZ_MASK) + 1;
/* DMA transfer size is 16 bits for a frame size > 8 bits */
uint16_t dma_size = frame_size > 8 ? 1 : 0;
/* DMA word size is 2 for a 16 bit frame size */
spip->word_size = frame_size > 8 ? 2 : 1;
/* configure DMA RX fixed values */
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SADDR = (uint32_t)&SPI1->POPR;
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SOFF = 0;
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SLAST = 0;
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].DLASTSGA = 0;
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) |
DMA_ATTR_DSIZE(dma_size);
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size;
DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK |
DMA_CSR_INTMAJOR_MASK;
/* configure DMA TX fixed values */
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].SLAST = 0;
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DADDR = (uint32_t)&SPI1->PUSHR;
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DOFF = 0;
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DLASTSGA = 0;
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) |
DMA_ATTR_DSIZE(dma_size);
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size;
DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK;
#endif
}
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_stop(SPIDriver *spip) {
/* If in ready state then disables the SPI clock.*/
if (spip->state == SPI_READY) {
nvicDisableVector(DMA0_IRQn);
SIM->SCGC7 &= ~SIM_SCGC7_DMA;
SIM->SCGC6 &= ~SIM_SCGC6_DMAMUX;
#if KINETIS_SPI_USE_SPI0
if (&SPID1 == spip) {
/* SPI halt.*/
spip->spi->MCR |= SPIx_MCR_HALT;
}
/* Disable the clock for SPI0 */
SIM->SCGC6 &= ~SIM_SCGC6_SPI0;
#endif
#if KINETIS_SPI_USE_SPI1
if (&SPID2 == spip) {
/* SPI halt.*/
spip->spi->MCR |= SPIx_MCR_HALT;
}
/* Disable the clock for SPI1 */
SIM->SCGC6 &= ~SIM_SCGC6_SPI1;
#endif
}
}
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_select(SPIDriver *spip) {
palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
* @brief Deasserts the slave select signal.
* @details The previously selected peripheral is unselected.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
* @brief Ignores data on the SPI bus.
* @details This asynchronous function starts the transmission of a series of
* idle words on the SPI bus and ignores the received data.
* @post At the end of the operation the configured callback is invoked.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
*
* @notapi
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
spip->count = n;
spip->rxbuf = NULL;
spip->txbuf = NULL;
spi_start_xfer(spip, false);
}
/**
* @brief Exchanges data on the SPI bus.
* @details This asynchronous function starts a simultaneous transmit/receive
* operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
*
* @notapi
*/
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
spip->count = n;
spip->rxbuf = rxbuf;
spip->txbuf = txbuf;
spi_start_xfer(spip, false);
}
/**
* @brief Sends data over the SPI bus.
* @details This asynchronous function starts a transmit operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer
*
* @notapi
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
spip->count = n;
spip->rxbuf = NULL;
spip->txbuf = (void *)txbuf;
spi_start_xfer(spip, false);
}
/**
* @brief Receives data from the SPI bus.
* @details This asynchronous function starts a receive operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer
*
* @notapi
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
spip->count = n;
spip->rxbuf = rxbuf;
spip->txbuf = NULL;
spi_start_xfer(spip, false);
}
/**
* @brief Exchanges one frame using a polled wait.
* @details This synchronous function exchanges one frame using a polled
* synchronization method. This function is useful when exchanging
* small amount of data on high speed channels, usually in this
* situation is much more efficient just wait for completion using
* polling than suspending the thread waiting for an interrupt.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] frame the data frame to send over the SPI bus
* @return The received data frame from the SPI bus.
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
spi_start_xfer(spip, true);
spip->spi->PUSHR = SPIx_PUSHR_TXDATA(frame);
while ((spip->spi->SR & SPIx_SR_RFDF) == 0)
;
frame = spip->spi->POPR;
spi_stop_xfer(spip);
return frame;
}
#endif /* HAL_USE_SPI */
/** @} */

View File

@ -0,0 +1,261 @@
/*
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file KINETIS/spi_lld.h
* @brief KINETIS SPI subsystem low level driver header.
*
* @addtogroup SPI
* @{
*/
#ifndef HAL_SPI_LLD_H_
#define HAL_SPI_LLD_H_
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief SPI0 driver enable switch.
* @details If set to @p TRUE the support for SPI0 is included.
* @note The default is @p FALSE.
*/
#if !defined(KINETIS_SPI_USE_SPI0) || defined(__DOXYGEN__)
#define KINETIS_SPI_USE_SPI0 FALSE
#endif
/**
* @brief SPI0 interrupt priority level setting.
*/
#if !defined(KINETIS_SPI_SPI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define KINETIS_SPI_SPI0_IRQ_PRIORITY 10
#endif
/**
* @brief SPI1 driver enable switch.
* @details If set to @p TRUE the support for SPI0 is included.
* @note The default is @p FALSE.
*/
#if !defined(KINETIS_SPI_USE_SPI1) || defined(__DOXYGEN__)
#define KINETIS_SPI_USE_SPI1 FALSE
#endif
/**
* @brief SPI1 interrupt priority level setting.
*/
#if !defined(KINETIS_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define KINETIS_SPI_SPI1_IRQ_PRIORITY 10
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if KINETIS_SPI_USE_SPI0 && !KINETIS_HAS_SPI0
#error "SPI0 not present in the selected device"
#endif
#if KINETIS_SPI_USE_SPI1 && !KINETIS_HAS_SPI1
#error "SPI1 not present in the selected device"
#endif
#if KINETIS_SPI_USE_SPI0 && KINETIS_SPI_USE_SPI1
#error "Only one SPI peripheral can be enabled"
#endif
#if !(KINETIS_SPI_USE_SPI0 || KINETIS_SPI_USE_SPI1)
#error "SPI driver activated but no SPI peripheral assigned"
#endif
#if KINETIS_SPI_USE_SPI0 && \
!OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_SPI_SPI0_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SPI0"
#endif
#if KINETIS_SPI_USE_SPI1 && \
!OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_SPI_SPI1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SPI1"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a structure representing an SPI driver.
*/
typedef struct SPIDriver SPIDriver;
/**
* @brief SPI notification callback type.
*
* @param[in] spip pointer to the @p SPIDriver object triggering the
* callback
*/
typedef void (*spicallback_t)(SPIDriver *spip);
/**
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port - when not using pcs.
*/
ioportid_t ssport;
/**
* @brief The chip select line pad number - when not using pcs.
*/
uint16_t sspad;
/**
* @brief SPI initialization data.
*/
uint32_t tar0;
} SPIConfig;
/**
* @brief Structure representing a SPI driver.
*/
struct SPIDriver {
/**
* @brief Driver state.
*/
spistate_t state;
/**
* @brief Current configuration data.
*/
const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
thread_reference_t thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
mutex_t mutex;
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
SPI_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Pointer to the SPIx registers block.
*/
SPI_TypeDef *spi;
/**
* @brief Number of bytes/words of data to transfer.
*/
size_t count;
/**
* @brief Word size in bytes.
*/
size_t word_size;
/**
* @brief Pointer to the buffer with data to send.
*/
const uint8_t *txbuf;
/**
* @brief Pointer to the buffer to put received data.
*/
uint8_t *rxbuf;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/* TAR settings for n bits at SYSCLK / 2 */
#define KINETIS_SPI_TAR_SYSCLK_DIV_2(n)\
SPIx_CTARn_FMSZ((n) - 1) | \
SPIx_CTARn_CPOL | \
SPIx_CTARn_CPHA | \
SPIx_CTARn_DBR | \
SPIx_CTARn_PBR(0) | \
SPIx_CTARn_BR(0) | \
SPIx_CTARn_CSSCK(0) | \
SPIx_CTARn_ASC(0) | \
SPIx_CTARn_DT(0)
/* TAR settings for n bits at SYSCLK / 4096 for debugging */
#define KINETIS_SPI_TAR_SYSCLK_DIV_4096(n) \
SPIx_CTARn_FMSZ(((n) - 1)) | \
SPIx_CTARn_CPOL | \
SPIx_CTARn_CPHA | \
SPIx_CTARn_PBR(0) | \
SPIx_CTARn_BR(0xB) | \
SPIx_CTARn_CSSCK(0xB) | \
SPIx_CTARn_ASC(0x7) | \
SPIx_CTARn_DT(0xB)
#define KINETIS_SPI_TAR_8BIT_FAST KINETIS_SPI_TAR_SYSCLK_DIV_2(8)
#define KINETIS_SPI_TAR_8BIT_SLOW KINETIS_SPI_TAR_SYSCLK_DIV_4096(8)
#define KINETIS_SPI_TAR0_DEFAULT KINETIS_SPI_TAR_SYSCLK_DIV_2(8)
#define KINETIS_SPI_TAR1_DEFAULT KINETIS_SPI_TAR_SYSCLK_DIV_2(8)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if KINETIS_SPI_USE_SPI0 && !defined(__DOXYGEN__)
extern SPIDriver SPID1;
#endif
#if KINETIS_SPI_USE_SPI1 && !defined(__DOXYGEN__)
extern SPIDriver SPID2;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
void spi_lld_ignore(SPIDriver *spip, size_t n);
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf);
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SPI */
#endif /* HAL_SPI_LLD_H_ */
/** @} */

View File

@ -0,0 +1,168 @@
/*
ChibiOS - Copyright (C) 2014 Derek Mulcahy
(C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
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 MK66F18/kinetis_registry.h
* @brief MK66F18 capabilities registry.
*
* @addtogroup HAL
* @{
*/
#ifndef KINETIS_REGISTRY_H_
#define KINETIS_REGISTRY_H_
#if !defined(MK66F18) || defined(__DOXYGEN__)
#define MK66F18
#endif
/*===========================================================================*/
/* Platform capabilities. */
/*===========================================================================*/
/**
* @brief Maximum system and core clock (f_SYS) frequency.
*/
#define KINETIS_SYSCLK_MAX 180000000L
/**
* @brief Maximum bus clock (f_BUS) frequency.
*/
#define KINETIS_BUSCLK_MAX 60000000L
/**
* @brief Maximum flash clock (f_FLASH) frequency.
*/
#define KINETIS_FLASHCLK_MAX 28000000L
/* ADC attributes.*/
#define KINETIS_HAS_ADC0 TRUE
#define KINETIS_ADC0_IRQ_VECTOR VectorDC
#define KINETIS_HAS_ADC1 TRUE
#define KINETIS_ADC1_IRQ_VECTOR Vector164
/* DAC attributes.*/
#define KINETIS_HAS_DAC0 TRUE
#define KINETIS_DAC0_IRQ_VECTOR Vector120
#define KINETIS_HAS_DAC1 TRUE
#define KINETIS_DAC1_IRQ_VECTOR Vector160
/* DMA attributes.*/
#define KINETIS_DMA0_IRQ_VECTOR Vector40
#define KINETIS_DMA1_IRQ_VECTOR Vector44
#define KINETIS_DMA2_IRQ_VECTOR Vector48
#define KINETIS_DMA3_IRQ_VECTOR Vector4C
#define KINETIS_DMA4_IRQ_VECTOR Vector50
#define KINETIS_DMA5_IRQ_VECTOR Vector54
#define KINETIS_DMA6_IRQ_VECTOR Vector58
#define KINETIS_DMA7_IRQ_VECTOR Vector5C
#define KINETIS_DMA8_IRQ_VECTOR Vector60
#define KINETIS_DMA9_IRQ_VECTOR Vector64
#define KINETIS_DMA10_IRQ_VECTOR Vector68
#define KINETIS_DMA11_IRQ_VECTOR Vector6C
#define KINETIS_DMA12_IRQ_VECTOR Vector70
#define KINETIS_DMA13_IRQ_VECTOR Vector74
#define KINETIS_DMA14_IRQ_VECTOR Vector78
#define KINETIS_DMA15_IRQ_VECTOR Vector7C
#define KINETIS_HAS_DMA_ERROR_IRQ TRUE
#define KINETIS_DMA_ERROR_IRQ_VECTOR Vector80
/* EXT attributes.*/
#define KINETIS_PORTA_IRQ_VECTOR Vector12C
#define KINETIS_PORTB_IRQ_VECTOR Vector130
#define KINETIS_PORTC_IRQ_VECTOR Vector134
#define KINETIS_PORTD_IRQ_VECTOR Vector138
#define KINETIS_PORTE_IRQ_VECTOR Vector13C
#define KINETIS_EXT_HAS_COMMON_CD_IRQ FALSE
#define KINETIS_EXT_HAS_COMMON_BCDE_IRQ FALSE
#define KINETIS_GPIO_HAS_OPENDRAIN TRUE
/* I2C attributes.*/
#define KINETIS_HAS_I2C0 TRUE
#define KINETIS_I2C0_IRQ_VECTOR VectorA0
#define KINETIS_HAS_I2C1 TRUE
#define KINETIS_I2C1_IRQ_VECTOR VectorA4
/* Serial attributes.*/
#define KINETIS_HAS_SERIAL0 TRUE
#define KINETIS_SERIAL0_IRQ_VECTOR VectorBC
#define KINETIS_HAS_SERIAL1 TRUE
#define KINETIS_SERIAL1_IRQ_VECTOR VectorC4
#define KINETIS_HAS_SERIAL2 TRUE
#define KINETIS_SERIAL2_IRQ_VECTOR VectorCC
#define KINETIS_HAS_SERIAL3 TRUE
#define KINETIS_SERIAL3_IRQ_VECTOR VectorD4
#define KINETIS_HAS_SERIAL_ERROR_IRQ TRUE
#define KINETIS_SERIAL0_ERROR_IRQ_VECTOR VectorC0
#define KINETIS_SERIAL1_ERROR_IRQ_VECTOR VectorC8
#define KINETIS_SERIAL2_ERROR_IRQ_VECTOR VectorD0
#define KINETIS_SERIAL3_ERROR_IRQ_VECTOR VectorD8
#define KINETIS_SERIAL0_IS_LPUART FALSE
#define KINETIS_SERIAL0_IS_UARTLP FALSE
#define KINETIS_SERIAL1_IS_LPUART FALSE
#define KINETIS_SERIAL1_IS_UARTLP FALSE
#define KINETIS_SERIAL2_IS_LPUART FALSE
#define KINETIS_SERIAL2_IS_UARTLP FALSE
#define KINETIS_SERIAL3_IS_LPUART FALSE
#define KINETIS_SERIAL3_IS_UARTLP FALSE
/* SPI attributes.*/
#define KINETIS_HAS_SPI0 TRUE
#define KINETIS_SPI0_IRQ_VECTOR VectorA8
#define KINETIS_HAS_SPI1 TRUE
#define KINETIS_SPI1_IRQ_VECTOR VectorAC
/* FlexTimer attributes.*/
#define KINETIS_FTM0_CHANNELS 8
#define KINETIS_FTM1_CHANNELS 2
#define KINETIS_FTM2_CHANNELS 2
#define KINETIS_FTM3_CHANNELS 8
#define KINETIS_HAS_FTM0 TRUE
#define KINETIS_FTM0_IRQ_VECTOR VectorE8
#define KINETIS_HAS_FTM1 TRUE
#define KINETIS_FTM1_IRQ_VECTOR VectorEC
#define KINETIS_HAS_FTM2 TRUE
#define KINETIS_FTM2_IRQ_VECTOR VectorF0
#define KINETIS_HAS_FTM3 TRUE
#define KINETIS_FTM3_IRQ_VECTOR Vector15C
/* GPT attributes.*/
#define KINETIS_HAS_PIT0 TRUE
#define KINETIS_PIT0_IRQ_VECTOR Vector100
#define KINETIS_HAS_PIT1 TRUE
#define KINETIS_PIT1_IRQ_VECTOR Vector104
#define KINETIS_HAS_PIT2 TRUE
#define KINETIS_PIT2_IRQ_VECTOR Vector108
#define KINETIS_HAS_PIT3 TRUE
#define KINETIS_PIT3_IRQ_VECTOR Vector10C
#define KINETIS_HAS_PIT_COMMON_IRQ FALSE
/* USB attributes.*/
#define KINETIS_HAS_USB TRUE
#define KINETIS_USB_IRQ_VECTOR Vector114
#define KINETIS_USB0_IS_USBOTG TRUE
#define KINETIS_HAS_USB_CLOCK_RECOVERY TRUE
/* LPTMR attributes.*/
#define KINETIS_LPTMR0_IRQ_VECTOR Vector128
/** @} */
#endif /* KINETIS_REGISTRY_H_ */
/** @} */

View File

@ -0,0 +1,365 @@
/*
ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* TODO Still need to edit this entire file */
/**
* @defgroup MK66FX1M0_DRIVERS MK66FX1M0 Drivers
* @details This section describes all the supported drivers on the MK66FX1M0
* platform and the implementation details of the single drivers.
*
* @ingroup platforms
*/
/**
* @defgroup MK66FX1M0_HAL MK66FX1M0 Initialization Support
* @details The MK66FX1M0 HAL support is responsible for system initialization.
*
* @section mk66fx1m0_hal_1 Supported HW resources
* - PLL1.
* - PLL2.
* - RCC.
* - Flash.
* .
* @section mk66fx1m0_hal_2 MK66FX1M0 HAL driver implementation features
* - PLL startup and stabilization.
* - Clock tree initialization.
* - Clock source selection.
* - Flash wait states initialization based on the selected clock options.
* - SYSTICK initialization based on current clock and kernel required rate.
* - DMA support initialization.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_ADC MK66FX1M0 ADC Support
* @details The MK66FX1M0 ADC driver supports the ADC peripherals using DMA
* channels for maximum performance.
*
* @section mk66fx1m0_adc_1 Supported HW resources
* - ADC1.
* - ADC2.
* - ADC3.
* - DMA2.
* .
* @section mk66fx1m0_adc_2 MK66FX1M0 ADC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Streaming conversion using DMA for maximum performance.
* - Programmable ADC interrupt priority level.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
* - DMA and ADC errors detection.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_CAN MK66FX1M0 CAN Support
* @details The MK66FX1M0 CAN driver uses the CAN peripherals.
*
* @section mk66fx1m0_can_1 Supported HW resources
* - bxCAN1.
* .
* @section mk66fx1m0_can_2 MK66FX1M0 CAN driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Support for bxCAN sleep mode.
* - Programmable bxCAN interrupts priority level.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_EXT MK66FX1M0 EXT Support
* @details The MK66FX1M0 EXT driver uses the EXTI peripheral.
*
* @section mk66fx1m0_ext_1 Supported HW resources
* - EXTI.
* .
* @section mk66fx1m0_ext_2 MK66FX1M0 EXT driver implementation features
* - Each EXTI channel can be independently enabled and programmed.
* - Programmable EXTI interrupts priority level.
* - Capability to work as event sources (WFE) rather than interrupt sources.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_GPT MK66FX1M0 GPT Support
* @details The MK66FX1M0 GPT driver uses the TIMx peripherals.
*
* @section mk66fx1m0_gpt_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* - TIM8.
* .
* @section mk66fx1m0_gpt_2 MK66FX1M0 GPT driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable TIMx interrupts priority level.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_ICU MK66FX1M0 ICU Support
* @details The MK66FX1M0 ICU driver uses the TIMx peripherals.
*
* @section mk66fx1m0_icu_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* - TIM8.
* .
* @section mk66fx1m0_icu_2 MK66FX1M0 ICU driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable TIMx interrupts priority level.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_MAC MK66FX1M0 MAC Support
* @details The MK66FX1M0 MAC driver supports the ETH peripheral.
*
* @section mk66fx1m0_mac_1 Supported HW resources
* - ETH.
* - PHY (external).
* .
* @section mk66fx1m0_mac_2 MK66FX1M0 MAC driver implementation features
* - Dedicated DMA operations.
* - Support for checksum off-loading.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_PAL MK66FX1M0 PAL Support
* @details The MK66FX1M0 PAL driver uses the GPIO peripherals.
*
* @section mk66fx1m0_pal_1 Supported HW resources
* - GPIOA.
* - GPIOB.
* - GPIOC.
* - GPIOD.
* - GPIOE.
* - GPIOF.
* - GPIOG.
* - GPIOH.
* - GPIOI.
* .
* @section mk66fx1m0_pal_2 MK66FX1M0 PAL driver implementation features
* The PAL driver implementation fully supports the following hardware
* capabilities:
* - 16 bits wide ports.
* - Atomic set/reset functions.
* - Atomic set+reset function (atomic bus operations).
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* @section mk66fx1m0_pal_3 Supported PAL setup modes
* The MK66FX1M0 PAL driver supports the following I/O modes:
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_INPUT_PULLUP.
* - @p PAL_MODE_INPUT_PULLDOWN.
* - @p PAL_MODE_INPUT_ANALOG.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* - @p PAL_MODE_OUTPUT_OPENDRAIN.
* - @p PAL_MODE_ALTERNATE (non standard).
* .
* Any attempt to setup an invalid mode is ignored.
*
* @section mk66fx1m0_pal_4 Suboptimal behavior
* The MK66FX1M0 GPIO is less than optimal in several areas, the limitations
* should be taken in account while using the PAL driver:
* - Pad/port toggling operations are not atomic.
* - Pad/group mode setup is not atomic.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_PWM MK66FX1M0 PWM Support
* @details The MK66FX1M0 PWM driver uses the TIMx peripherals.
*
* @section mk66fx1m0_pwm_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* - TIM5.
* - TIM8.
* .
* @section mk66fx1m0_pwm_2 MK66FX1M0 PWM driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Four independent PWM channels per timer.
* - Programmable TIMx interrupts priority level.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_SDC MK66FX1M0 SDC Support
* @details The MK66FX1M0 SDC driver uses the SDIO peripheral.
*
* @section mk66fx1m0_sdc_1 Supported HW resources
* - SDIO.
* - DMA2.
* .
* @section mk66fx1m0_sdc_2 MK66FX1M0 SDC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Programmable interrupt priority.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_SERIAL MK66FX1M0 Serial Support
* @details The MK66FX1M0 Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
* @section mk66fx1m0_serial_1 Supported HW resources
* The serial driver can support any of the following hardware resources:
* - USART1.
* - USART2.
* - USART3.
* - UART4.
* - UART5.
* - USART6.
* .
* @section mk66fx1m0_serial_2 MK66FX1M0 Serial driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each UART/USART can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Fully interrupt driven.
* - Programmable priority levels for each UART/USART.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_SPI MK66FX1M0 SPI Support
* @details The SPI driver supports the MK66FX1M0 SPI peripherals using DMA
* channels for maximum performance.
*
* @section mk66fx1m0_spi_1 Supported HW resources
* - SPI1.
* - SPI2.
* - SPI3.
* - DMA1.
* - DMA2.
* .
* @section mk66fx1m0_spi_2 MK66FX1M0 SPI driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each SPI can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable interrupt priority levels for each SPI.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
* - Programmable DMA error hook.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_UART MK66FX1M0 UART Support
* @details The UART driver supports the MK66FX1M0 USART peripherals using DMA
* channels for maximum performance.
*
* @section mk66fx1m0_uart_1 Supported HW resources
* The UART driver can support any of the following hardware resources:
* - USART1.
* - USART2.
* - USART3.
* - DMA1.
* - DMA2.
* .
* @section mk66fx1m0_uart_2 MK66FX1M0 UART driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each UART/USART can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable interrupt priority levels for each UART/USART.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
* - Programmable DMA error hook.
* .
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_PLATFORM_DRIVERS MK66FX1M0 Platform Drivers
* @details Platform support drivers. Platform drivers do not implement HAL
* standard driver templates, their role is to support platform
* specific functionalities.
*
* @ingroup MK66FX1M0_DRIVERS
*/
/**
* @defgroup MK66FX1M0_DMA MK66FX1M0 DMA Support
* @details This DMA helper driver is used by the other drivers in order to
* access the shared DMA resources in a consistent way.
*
* @section mk66fx1m0_dma_1 Supported HW resources
* The DMA driver can support any of the following hardware resources:
* - DMA1.
* - DMA2.
* .
* @section mk66fx1m0_dma_2 MK66FX1M0 DMA driver implementation features
* - Exports helper functions/macros to the other drivers that share the
* DMA resource.
* - Automatic DMA clock stop when not in use by any driver.
* - DMA streams and interrupt vectors sharing among multiple drivers.
* .
* @ingroup MK66FX1M0_PLATFORM_DRIVERS
*/
/**
* @defgroup MK66FX1M0_ISR MK66FX1M0 ISR Support
* @details This ISR helper driver is used by the other drivers in order to
* map ISR names to physical vector names.
*
* @ingroup MK66FX1M0_PLATFORM_DRIVERS
*/
/**
* @defgroup MK66FX1M0_RCC MK66FX1M0 RCC Support
* @details This RCC helper driver is used by the other drivers in order to
* access the shared RCC resources in a consistent way.
*
* @section mk66fx1m0_rcc_1 Supported HW resources
* - RCC.
* .
* @section mk66fx1m0_rcc_2 MK66FX1M0 RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
* - Peripherals clock disable.
* .
* @ingroup MK66FX1M0_PLATFORM_DRIVERS
*/

View File

@ -0,0 +1,19 @@
# List of all platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/MK66F18/hal_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_pal_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_serial_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/MK66F18/hal_spi_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_i2c_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_ext_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_adc_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_gpt_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_sdc_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/MK66F18/hal_pwm_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_st_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_usb_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/MK66F18 \
${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD