Added spi_api.c and gcc_arm_kl43z.tmpl files. Fixed some issues in KL43Z target

pull/589/head
Martin Olejar 2014-10-13 00:49:48 +02:00
parent 262f9cff89
commit 1f9586daac
9 changed files with 331 additions and 49 deletions

View File

@ -100,7 +100,7 @@
*/
#include <stdint.h>
#include "device/fsl_device_registers.h"
#include "MKL43Z4.h"

View File

@ -50,52 +50,49 @@ const PinMap PinMap_DAC[] = {
/************I2C***************/
const PinMap PinMap_I2C_SDA[] = {
{PTE25, I2C_0, 5},
{PTC9, I2C_0, 2},
{PTE0, I2C_1, 6},
{PTA4, I2C_0, 2},
{PTB1, I2C_0, 2},
{PTB3, I2C_0, 2},
{PTC11, I2C_1, 2},
{PTC2, I2C_1, 2},
{PTA4, I2C_1, 2},
{PTE0, I2C_1, 6},
{PTE25, I2C_0, 5},
{NC , NC , 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PTE24, I2C_0, 5},
{PTC8, I2C_0, 2},
{PTE1, I2C_1, 6},
{PTA3, I2C_0, 2},
{PTB0, I2C_0, 2},
{PTB2, I2C_0, 2},
{PTC10, I2C_1, 2},
{PTC1, I2C_1, 2},
{PTE1, I2C_1, 6},
{PTE24, I2C_0, 5},
{NC , NC, 0}
};
/************UART***************/
const PinMap PinMap_UART_TX[] = {
{PTA2, UART_0, 2},
{PTA14, UART_0, 3},
{PTC4, UART_1, 3},
{PTA19, UART_1, 3},
{PTB17, UART_0, 3},
{PTD3, UART_2, 3},
{PTD5, UART_2, 3},
{PTD7, UART_0, 3},
{PTE0, UART_1, 3},
{PTE16, UART_2, 3},
{PTE20, UART_0, 4},
{PTE22, UART_2, 4},
{PTE30, UART_1, 5},
{NC , NC , 0}
};
const PinMap PinMap_UART_RX[] = {
{PTA1, UART_0, 2},
{PTA15, UART_0, 3},
{PTA18, UART_1, 3},
{PTB16, UART_0, 3},
{PTC3, UART_1, 3},
{PTD2, UART_2, 3},
{PTD4, UART_2, 3},
{PTD6, UART_0, 3},
{PTE1, UART_1, 3},
{PTE17, UART_2, 3},
{PTE21, UART_0, 4},
{PTE23, UART_2, 4},
{NC , NC , 0}
@ -103,20 +100,14 @@ const PinMap PinMap_UART_RX[] = {
/************SPI***************/
const PinMap PinMap_SPI_SCLK[] = {
{PTA15, SPI_0, 2},
{PTB9, SPI_1, 2},
{PTB11, SPI_1, 2},
{PTC3, SPI_1, 2},
{PTC5, SPI_0, 2},
{PTD1, SPI_0, 2},
{PTD5, SPI_1, 2},
{PTE2, SPI_1, 2},
{PTE17, SPI_0, 2},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MOSI[] = {
{PTA16, SPI_0, 2},
{PTA17, SPI_0, 5},
{PTB16, SPI_1, 2},
{PTB17, SPI_1, 5},
{PTC6, SPI_0, 2},
@ -126,15 +117,10 @@ const PinMap PinMap_SPI_MOSI[] = {
{PTD6, SPI_1, 2},
{PTD7, SPI_1, 5},
{PTE1, SPI_1, 2},
{PTE3, SPI_1, 5},
{PTE18, SPI_0, 2},
{PTE19, SPI_0, 5},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PTA16, SPI_0, 5},
{PTA17, SPI_0, 2},
{PTB16, SPI_1, 5},
{PTB17, SPI_1, 2},
{PTC6, SPI_0, 5},
@ -143,21 +129,15 @@ const PinMap PinMap_SPI_MISO[] = {
{PTD3, SPI_0, 2},
{PTD6, SPI_1, 5},
{PTD7, SPI_1, 2},
{PTE0, SPI_1, 2},
{PTE1, SPI_1, 5},
{PTE3, SPI_1, 2},
{PTE18, SPI_0, 5},
{PTE19, SPI_0, 2},
{NC , NC , 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PTA14, SPI_0, 2},
{PTB10, SPI_1, 2},
{PTC4, SPI_0, 2},
{PTD0, SPI_0, 2},
{PTD4, SPI_1, 2},
{PTE4, SPI_1, 2},
{PTE16, SPI_0, 2},
{NC , NC , 0}
};
@ -169,8 +149,6 @@ const PinMap PinMap_PWM[] = {
{PTA3, PWM_1, 3}, // PTA3 , TPM0 CH0
{PTA4, PWM_2 , 3}, // PTA4 , TPM0 CH1
{PTA5, PWM_3 , 3}, // PTA5 , TPM0 CH2
{PTA6, PWM_4, 3}, // PTA6 , TPM0 CH3
{PTA7, PWM_5, 3}, // PTA7 , TPM0 CH4
{PTA12, PWM_7 , 3}, // PTA12, TPM1 CH0
{PTA13, PWM_8 , 3}, // PTA13, TPM1 CH1
@ -185,8 +163,6 @@ const PinMap PinMap_PWM[] = {
{PTC2, PWM_2, 4}, // PTC2 , TPM0 CH1
{PTC3, PWM_3, 4}, // PTC3 , TPM0 CH2
{PTC4, PWM_4, 4}, // PTC4 , TPM0 CH3
{PTC8, PWM_5 , 3}, // PTC8 , TPM0 CH4
{PTC9, PWM_6 , 3}, // PTC9 , TPM0 CH5
{PTD0, PWM_1 , 4}, // PTD0 , TPM0 CH0
{PTD1, PWM_2 , 4}, // PTD0 , TPM0 CH1
@ -201,7 +177,6 @@ const PinMap PinMap_PWM[] = {
{PTE23, PWM_10, 3}, // PTE23, TPM2 CH1
{PTE24, PWM_1, 3}, // PTE24, TPM0 CH0
{PTE25, PWM_2, 3}, // PTE25, TPM0 CH1
{PTE26, PWM_6, 3}, // PTE26, TPM0 CH5
{PTE29, PWM_3, 3}, // PTE29, TPM0 CH2
{PTE30, PWM_4, 3}, // PTE30, TPM0 CH3
{PTE31, PWM_5, 3}, // PTE31, TPM0 CH4

View File

@ -191,7 +191,7 @@ typedef enum {
PTE30 = 0x4078,
PTE31 = 0x407c,
LED_RED = PTE29,
LED_RED = PTE31,
LED_GREEN = PTD5,
// mbed original LED naming
@ -201,8 +201,8 @@ typedef enum {
LED4 = LED_RED,
//Push buttons
SW1 = PTC3,
SW3 = PTC12,
SW1 = PTA4,
SW3 = PTC3,
// USB Pins
USBTX = PTA2,

View File

@ -0,0 +1,218 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* 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 "mbed_assert.h"
#include "spi_api.h"
#include <math.h>
#include "cmsis.h"
#include "pinmap.h"
static const PinMap PinMap_SPI_SCLK[] = {
{PTC3, SPI_1, 2},
{PTC5, SPI_0, 2},
{PTD1, SPI_0, 2},
{PTD5, SPI_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MOSI[] = {
{PTB16, SPI_1, 2},
{PTB17, SPI_1, 5},
{PTC6, SPI_0, 2},
{PTC7, SPI_0, 5},
{PTD2, SPI_0, 2},
{PTD3, SPI_0, 5},
{PTD6, SPI_1, 2},
{PTD7, SPI_1, 5},
{PTE1, SPI_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{PTB16, SPI_1, 5},
{PTB17, SPI_1, 2},
{PTC6, SPI_0, 5},
{PTC7, SPI_0, 2},
{PTD2, SPI_0, 5},
{PTD3, SPI_0, 2},
{PTD6, SPI_1, 5},
{PTD7, SPI_1, 2},
{PTE0, SPI_1, 2},
{PTE1, SPI_1, 5},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{PTC4, SPI_0, 2},
{PTD0, SPI_0, 2},
{PTD4, SPI_1, 2},
{NC , NC , 0}
};
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
// determine the SPI to use
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT((int)obj->spi != NC);
// enable power and clocking
switch ((int)obj->spi) {
case SPI_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 22; break;
case SPI_1: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 23; break;
}
// set default format and frequency
if (ssel == NC) {
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
} else {
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
}
spi_frequency(obj, 1000000);
// enable SPI
obj->spi->C1 |= SPI_C1_SPE_MASK;
obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK; //8bit
// pin out the spi pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
}
}
void spi_free(spi_t *obj) {
// [TODO]
}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
MBED_ASSERT((bits == 8) || (bits == 16));
MBED_ASSERT((mode >= 0) && (mode <= 3));
uint8_t polarity = (mode & 0x2) ? 1 : 0;
uint8_t phase = (mode & 0x1) ? 1 : 0;
uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
// clear MSTR, CPOL and CPHA bits
obj->spi->C1 &= ~(0x7 << 2);
// write new value
obj->spi->C1 |= c1_data;
if (bits == 8) {
obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK;
} else {
obj->spi->C2 |= SPI_C2_SPIMODE_MASK;
}
}
void spi_frequency(spi_t *obj, int hz) {
uint32_t error = 0;
uint32_t p_error = 0xffffffff;
uint32_t ref = 0;
uint8_t spr = 0;
uint8_t ref_spr = 0;
uint8_t ref_prescaler = 0;
// bus clk
uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
uint8_t prescaler = 1;
uint8_t divisor = 2;
for (prescaler = 1; prescaler <= 8; prescaler++) {
divisor = 2;
for (spr = 0; spr <= 8; spr++, divisor *= 2) {
ref = PCLK / (prescaler*divisor);
if (ref > (uint32_t)hz)
continue;
error = hz - ref;
if (error < p_error) {
ref_spr = spr;
ref_prescaler = prescaler - 1;
p_error = error;
}
}
}
// set SPPR and SPR
obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
}
static inline int spi_writeable(spi_t * obj) {
return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
}
static inline int spi_readable(spi_t * obj) {
return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
}
int spi_master_write(spi_t *obj, int value) {
int ret;
if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
// 16bit
while(!spi_writeable(obj));
obj->spi->DL = (value & 0xff);
obj->spi->DH = ((value >> 8) & 0xff);
// wait rx buffer full
while (!spi_readable(obj));
ret = obj->spi->DH;
ret = (ret << 8) | obj->spi->DL;
} else {
//8bit
while(!spi_writeable(obj));
obj->spi->DL = (value & 0xff);
// wait rx buffer full
while (!spi_readable(obj));
ret = (obj->spi->DL & 0xff);
}
return ret;
}
int spi_slave_receive(spi_t *obj) {
return spi_readable(obj);
}
int spi_slave_read(spi_t *obj) {
int ret;
if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
ret = obj->spi->DH;
ret = ((ret << 8) | obj->spi->DL);
} else {
ret = obj->spi->DL;
}
return ret;
}
void spi_slave_write(spi_t *obj, int value) {
while (!spi_writeable(obj));
if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
obj->spi->DL = (value & 0xff);
obj->spi->DH = ((value >> 8) & 0xff);
} else {
obj->spi->DL = value;
}
}

View File

@ -27,6 +27,16 @@ static inline uint32_t bus_frequency(void) {
return SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
}
#if defined(TARGET_KL43Z)
static inline uint32_t extosc_frequency(void) {
return CPU_XTAL_CLK_HZ;
}
static uint32_t mcgirc_frequency(void) {
uint32_t mcgirc_clock = CPU_INT_SLOW_CLK_HZ / (1u + ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
return (mcgirc_clock / (1u + (MCG->MC & MCG_MC_LIRC_DIV2_MASK)));
}
#else
//Get external oscillator (crystal) frequency
static uint32_t extosc_frequency(void) {
uint32_t MCGClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
@ -35,7 +45,7 @@ static uint32_t extosc_frequency(void) {
return MCGClock;
uint32_t divider, multiplier;
#ifdef MCG_C5_PLLCLKEN0_MASK //PLL available
#ifdef MCG_C5_PLLCLKEN0_MASK //PLL available
if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0)) { //PLL/FLL is selected
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected
#endif
@ -110,6 +120,7 @@ static uint32_t mcgpllfll_frequency(void) {
//It is possible the SystemCoreClock isn't running on the PLL, and the PLL is still active
//for the peripherals, this is however an unlikely setup
}
#endif
#ifdef __cplusplus
}

View File

@ -30,9 +30,11 @@ void sleep(void)
//Very low-power stop mode
void deepsleep(void)
{
#if ! defined(TARGET_KL43Z)
//Check if PLL/FLL is enabled:
uint32_t PLL_FLL_en = (MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0);
#endif
SMC->PMPROT = SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK;
SMC->PMCTRL = SMC_PMCTRL_STOPM(2);
@ -41,6 +43,7 @@ void deepsleep(void)
__WFI();
#if ! defined(TARGET_KL43Z)
//Switch back to PLL as clock source if needed
//The interrupt that woke up the device will run at reduced speed
if (PLL_FLL_en) {
@ -50,5 +53,5 @@ void deepsleep(void)
#endif
MCG->C1 &= ~MCG_C1_CLKS_MASK;
}
#endif
}

View File

@ -66,6 +66,8 @@ uint32_t us_ticker_read() {
static void lptmr_isr(void);
static void lptmr_init(void) {
uint32_t extosc;
/* Clock the timer */
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
@ -75,11 +77,15 @@ static void lptmr_init(void) {
/* Set interrupt handler */
NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr);
NVIC_EnableIRQ(LPTimer_IRQn);
#if defined(TARGET_KL43Z)
extosc = mcgirc_frequency();
MCG->C1 |= MCG_C1_IRCLKEN_MASK;
#else
/* Clock at (1)MHz -> (1)tick/us */
/* Check if the external oscillator can be divided to 1MHz */
uint32_t extosc = extosc_frequency();
extosc = extosc_frequency();
#else
if (extosc != 0) { //If external oscillator found
if (extosc % 1000000u == 0) { //If it is a multiple if 1MHz
extosc /= 1000000;
@ -102,6 +108,12 @@ static void lptmr_init(void) {
}
}
}
#if defined(TARGET_KL43Z)
//No suitable actual IRC oscillator clock -> Set it to (8MHz / divider)
MCG->SC &= ~MCG_SC_FCRDIV_MASK;
MCG->MC &= ~MCG->MC & MCG_MC_LIRC_DIV2_MASK;
LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(2);
#else
//No suitable external oscillator clock -> Use fast internal oscillator (4MHz / divider)
MCG->C1 |= MCG_C1_IRCLKEN_MASK;
MCG->C2 |= MCG_C2_IRCS_MASK;
@ -118,7 +130,7 @@ static void lptmr_init(void) {
MCG->SC |= MCG_SC_FCRDIV(2);
LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK;
}
#endif
}
void us_ticker_disable_interrupt(void) {

View File

@ -0,0 +1,52 @@
# This file was automagically generated by mbed.org. For more information,
# see http://mbed.org/handbook/Exporting-to-GCC-ARM-Embedded
GCC_BIN =
PROJECT = {{name}}
OBJECTS = {% for f in to_be_compiled %}{{f}} {% endfor %}
SYS_OBJECTS = {% for f in object_files %}{{f}} {% endfor %}
INCLUDE_PATHS = {% for p in include_paths %}-I{{p}} {% endfor %}
LIBRARY_PATHS = {% for p in library_paths %}-L{{p}} {% endfor %}
LIBRARIES = {% for lib in libraries %}-l{{lib}} {% endfor %}
LINKER_SCRIPT = {{linker_script}}
###############################################################################
AS = $(GCC_BIN)arm-none-eabi-as
CC = $(GCC_BIN)arm-none-eabi-gcc
CPP = $(GCC_BIN)arm-none-eabi-g++
LD = $(GCC_BIN)arm-none-eabi-gcc
OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
CPU = -mcpu=cortex-m0plus -mthumb
CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer
CC_SYMBOLS = {% for s in symbols %}-D{{s}} {% endfor %}
LD_FLAGS = -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float
LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
ifeq ($(DEBUG), 1)
CC_FLAGS += -DDEBUG -O0
else
CC_FLAGS += -DNDEBUG -Os
endif
all: $(PROJECT).bin
clean:
rm -f $(PROJECT).bin $(PROJECT).elf $(OBJECTS)
.s.o:
$(AS) $(CPU) -o $@ $<
.c.o:
$(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $<
.cpp.o:
$(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $<
$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
$(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
$(PROJECT).bin: $(PROJECT).elf
$(OBJCOPY) -O binary $< $@

View File

@ -132,6 +132,16 @@ class KL25Z(Target):
self.detect_code = "0200"
class KL43Z(Target):
def __init__(self):
Target.__init__(self)
self.core = "Cortex-M0+"
self.extra_labels = ['Freescale', 'KLXX']
self.supported_toolchains = ["GCC_ARM", "ARM"]
self.supported_form_factors = ["ARDUINO"]
self.is_disk_virtual = True
class KL46Z(Target):
def __init__(self):
Target.__init__(self)
@ -716,6 +726,7 @@ TARGETS = [
LPC11U24_301(),
KL05Z(),
KL25Z(),
KL43Z(),
KL46Z(),
K20D50M(),
K64F(),