Merge branch 'master' of git://github.com/Sissors/mbed into Sissors-master

Conflicts:
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/analogin_api.c
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/analogout_api.c
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/gpio_api.c
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/i2c_api.c
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/pinmap.c
	libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL05Z/pwmout_api.c
pull/159/merge
Bogdan Marinescu 2014-01-31 11:46:22 +02:00
commit f2e1518220
104 changed files with 699 additions and 3451 deletions

View File

@ -1,31 +0,0 @@
/* 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.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PortA = 0,
PortB = 1
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,89 +0,0 @@
/* 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 "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_ADC[] = {
/* A0-A5 pins */
{PTA0, ADC0_SE12, 0},
{PTA8, ADC0_SE3, 0},
{PTA9, ADC0_SE2, 0},
{PTB8, ADC0_SE11, 0},
{PTB9, ADC0_SE10, 0},
{PTB13, ADC0_SE13, 0},
/* Rest of pins ADC Mux */
{PTB2, ADC0_SE4, 0},
{PTB1, ADC0_SE5, 0},
{PTB5, ADC0_SE1, 0},
{PTA12, ADC0_SE0, 0},
{PTB10, ADC0_SE9, 0},
{PTB11, ADC0_SE8, 0},
{PTB7, ADC0_SE7, 0},
{PTB0, ADC0_SE6, 0},
{NC, NC, 0}
};
void analogin_init(analogin_t *obj, PinName pin) {
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (obj->adc == (ADCName)NC) {
error("ADC pin mapping failed");
}
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc);
ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration
| ADC_CFG1_ADIV(3) // Clock Divide Select: (Input Clock)/8
| ADC_CFG1_ADLSMP_MASK // Long Sample Time
| ADC_CFG1_MODE(1) // (12)bits Resolution
| ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2
ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb channels are selected
| ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable
| ADC_CFG2_ADHSC_MASK // High-Speed Configuration
| ADC_CFG2_ADLSTS(0); // Long Sample Time Select
ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
| ADC_SC3_AVGS(0); // 4 Samples Averaged
pinmap_pinout(pin, PinMap_ADC);
}
uint16_t analogin_read_u16(analogin_t *obj) {
// start conversion
ADC0->SC1[0] = ADC_SC1_ADCH(obj->adc);
// Wait Conversion Complete
while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
// Return value (12bit)
return (uint16_t)ADC0->R[0];
}
float analogin_read(analogin_t *obj) {
uint16_t value = analogin_read_u16(obj);
return (float)value * (1.0f / (float)0xFFFF);
}

View File

@ -1,88 +0,0 @@
/* 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 "analogout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#define RANGE_12BIT 0xFFF
static const PinMap PinMap_DAC[] = {
{PTB1, DAC_0, 0},
{NC , NC , 0}
};
void analogout_init(dac_t *obj, PinName pin) {
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
if (obj->dac == (DACName)NC) {
error("DAC pin mapping failed");
}
SIM->SCGC6 |= SIM_SCGC6_DAC0_MASK;
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
DAC0->DAT[obj->dac].DATH = 0;
DAC0->DAT[obj->dac].DATL = 0;
DAC0->C1 = DAC_C1_DACBFMD_MASK; // One-Time Scan Mode
DAC0->C0 = DAC_C0_DACEN_MASK // Enable
| DAC_C0_DACSWTRG_MASK; // Software Trigger
pinmap_pinout(pin, PinMap_DAC);
analogout_write_u16(obj, 0);
}
void analogout_free(dac_t *obj) {
}
static inline void dac_write(dac_t *obj, int value) {
DAC0->DAT[obj->dac].DATL = (uint8_t)( value & 0xFF);
DAC0->DAT[obj->dac].DATH = (uint8_t)((value >> 8) & 0xFF);
}
static inline int dac_read(dac_t *obj) {
return ((DAC0->DAT[obj->dac].DATH << 8) | DAC0->DAT[obj->dac].DATL);
}
void analogout_write(dac_t *obj, float value) {
if (value < 0.0) {
dac_write(obj, 0);
} else if (value > 1.0) {
dac_write(obj, RANGE_12BIT);
} else {
dac_write(obj, value * (float)RANGE_12BIT);
}
}
void analogout_write_u16(dac_t *obj, uint16_t value) {
dac_write(obj, value >> 4); // 12-bit
}
float analogout_read(dac_t *obj) {
uint32_t value = dac_read(obj);
return (float)value * (1.0f / (float)RANGE_12BIT);
}
uint16_t analogout_read_u16(dac_t *obj) {
uint32_t value = dac_read(obj); // 12-bit
return (value << 4) | ((value >> 8) & 0x003F);
}

View File

@ -1,64 +0,0 @@
/* 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 "gpio_api.h"
#include "pinmap.h"
uint32_t gpio_set(PinName pin) {
pin_function(pin, 1);
return 1 << ((pin & 0x7F) >> 2); // 1 << pin number
}
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
if (pin == (PinName)NC) {
return;
}
obj->pin = pin;
obj->mask = gpio_set(pin);
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
obj->reg_set = &reg->PSOR;
obj->reg_clr = &reg->PCOR;
obj->reg_in = &reg->PDIR;
obj->reg_dir = &reg->PDDR;
gpio_dir(obj, direction);
switch (direction) {
case PIN_OUTPUT:
pin_mode(pin, PullNone);
break;
case PIN_INPUT :
pin_mode(pin, PullUp); //down not avail
break;
}
}
void gpio_mode(gpio_t *obj, PinMode mode) {
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction) {
switch (direction) {
case PIN_INPUT :
*obj->reg_dir &= ~obj->mask;
break;
case PIN_OUTPUT:
*obj->reg_dir |= obj->mask;
break;
}
}

View File

@ -1,49 +0,0 @@
/* 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.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
uint32_t mask;
__IO uint32_t *reg_dir;
__IO uint32_t *reg_set;
__IO uint32_t *reg_clr;
__I uint32_t *reg_in;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value) {
if (value) {
*obj->reg_set = obj->mask;
} else {
*obj->reg_clr = obj->mask;
}
}
static inline int gpio_read(gpio_t *obj) {
return ((*obj->reg_in & obj->mask) ? 1 : 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,402 +0,0 @@
/* 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 "i2c_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_I2C_SDA[] = {
{PTB4, I2C_0, 2},
{NC , NC , 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PTB3, I2C_0, 2},
{NC , NC , 0}
};
static const uint16_t ICR[0x40] = {
20, 22, 24, 26, 28,
30, 34, 40, 28, 32,
36, 40, 44, 48, 56,
68, 48, 56, 64, 72,
80, 88, 104, 128, 80,
96, 112, 128, 144, 160,
192, 240, 160, 192, 224,
256, 288, 320, 384, 480,
320, 384, 448, 512, 576,
640, 768, 960, 640, 768,
896, 1024, 1152, 1280, 1536,
1920, 1280, 1536, 1792, 2048,
2304, 2560, 3072, 3840
};
static uint8_t first_read;
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2C_Type*)pinmap_merge(i2c_sda, i2c_scl);
if ((int)obj->i2c == NC) {
error("I2C pin mapping failed");
}
// enable clocks
switch ((int)obj->i2c) {
case I2C_0:
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
SIM->SCGC4 |= SIM_SCGC4_I2C0_MASK;
break;
}
// set default frequency at 100k
i2c_frequency(obj, 100000);
// enable I2C interface
obj->i2c->C1 |= 0x80;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
first_read = 1;
}
int i2c_start(i2c_t *obj) {
// if we are in the middle of a transaction
// activate the repeat_start flag
if (obj->i2c->S & I2C_S_BUSY_MASK) {
obj->i2c->C1 |= 0x04;
} else {
obj->i2c->C1 |= I2C_C1_MST_MASK;
obj->i2c->C1 |= I2C_C1_TX_MASK;
}
first_read = 1;
return 0;
}
int i2c_stop(i2c_t *obj) {
volatile uint32_t n = 0;
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// It seems that there are timing problems
// when there is no waiting time after a STOP.
// This wait is also included on the samples
// code provided with the freedom board
for (n = 0; n < 100; n++) __NOP();
first_read = 1;
return 0;
}
static int timeout_status_poll(i2c_t *obj, uint32_t mask) {
uint32_t i, timeout = 1000;
for (i = 0; i < timeout; i++) {
if (obj->i2c->S & mask) {
return 0;
}
}
return 1;
}
// this function waits the end of a tx transfer and return the status of the transaction:
// 0: OK ack received
// 1: OK ack not received
// 2: failure
static int i2c_wait_end_tx_transfer(i2c_t *obj) {
// wait for the interrupt flag
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
return 2;
}
obj->i2c->S |= I2C_S_IICIF_MASK;
// wait transfer complete
if (timeout_status_poll(obj, I2C_S_TCF_MASK)) {
return 2;
}
// check if we received the ACK or not
return obj->i2c->S & I2C_S_RXAK_MASK ? 1 : 0;
}
// this function waits the end of a rx transfer and return the status of the transaction:
// 0: OK
// 1: failure
static int i2c_wait_end_rx_transfer(i2c_t *obj) {
// wait for the end of the rx transfer
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
return 1;
}
obj->i2c->S |= I2C_S_IICIF_MASK;
return 0;
}
static void i2c_send_nack(i2c_t *obj) {
obj->i2c->C1 |= I2C_C1_TXAK_MASK; // NACK
}
static void i2c_send_ack(i2c_t *obj) {
obj->i2c->C1 &= ~I2C_C1_TXAK_MASK; // ACK
}
static int i2c_do_write(i2c_t *obj, int value) {
// write the data
obj->i2c->D = value;
// init and wait the end of the transfer
return i2c_wait_end_tx_transfer(obj);
}
static int i2c_do_read(i2c_t *obj, char * data, int last) {
if (last) {
i2c_send_nack(obj);
} else {
i2c_send_ack(obj);
}
*data = (obj->i2c->D & 0xFF);
// start rx transfer and wait the end of the transfer
return i2c_wait_end_rx_transfer(obj);
}
void i2c_frequency(i2c_t *obj, int hz) {
uint8_t icr = 0;
uint8_t mult = 0;
uint32_t error = 0;
uint32_t p_error = 0xffffffff;
uint32_t ref = 0;
uint8_t i, j;
// bus clk
uint32_t PCLK = 23986176u;
uint32_t pulse;
// we look for the values that minimize the error
// test all the MULT values
for (i = 1; i < 5; i*=2) {
for (j = 0; j < 0x40; j++) {
ref = PCLK / (i*ICR[j]);
if (ref > (uint32_t)hz)
continue;
error = hz - ref;
if (error < p_error) {
icr = j;
mult = i/2;
p_error = error;
}
}
}
pulse = icr | (mult << 6);
// I2C Rate
obj->i2c->F = pulse;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
uint8_t count;
char dummy_read, *ptr;
if (i2c_start(obj)) {
i2c_stop(obj);
return 1;
}
if (i2c_do_write(obj, (address | 0x01))) {
i2c_stop(obj);
return 1;
}
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// Read in bytes
for (count = 0; count < (length); count++) {
ptr = (count == 0) ? &dummy_read : &data[count - 1];
uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
if (i2c_do_read(obj, ptr, stop_)) {
i2c_stop(obj);
return 1;
}
}
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
}
// last read
data[count-1] = obj->i2c->D;
return 0;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
int i;
if (i2c_start(obj)) {
i2c_stop(obj);
return 1;
}
if (i2c_do_write(obj, (address & 0xFE))) {
i2c_stop(obj);
return 1;
}
for (i = 0; i < length; i++) {
if(i2c_do_write(obj, data[i])) {
i2c_stop(obj);
return 1;
}
}
if (stop) {
i2c_stop(obj);
}
return 0;
}
void i2c_reset(i2c_t *obj) {
i2c_stop(obj);
}
int i2c_byte_read(i2c_t *obj, int last) {
char data;
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
if(first_read) {
// first dummy read
i2c_do_read(obj, &data, 0);
first_read = 0;
}
if (last) {
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
return obj->i2c->D;
}
i2c_do_read(obj, &data, last);
return data;
}
int i2c_byte_write(i2c_t *obj, int data) {
first_read = 1;
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
return !i2c_do_write(obj, (data & 0xFF));
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
if (enable_slave) {
// set slave mode
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
obj->i2c->C1 |= I2C_C1_IICIE_MASK;
} else {
// set master mode
obj->i2c->C1 |= I2C_C1_MST_MASK;
}
}
int i2c_slave_receive(i2c_t *obj) {
switch(obj->i2c->S) {
// read addressed
case 0xE6:
return 1;
// write addressed
case 0xE2:
return 3;
default:
return 0;
}
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
uint8_t dummy_read, count;
uint8_t *ptr;
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// first dummy read
dummy_read = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return 0;
}
// read address
dummy_read = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return 0;
}
// read (length - 1) bytes
for (count = 0; count < (length - 1); count++) {
data[count] = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return 0;
}
}
// read last byte
ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
*ptr = obj->i2c->D;
return (length) ? (count + 1) : 0;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int32_t i, count = 0;
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
for (i = 0; i < length; i++) {
if(i2c_do_write(obj, data[count++]) == 2) {
return 0;
}
}
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// dummy rx transfer needed
// otherwise the master cannot generate a stop bit
obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj) == 2) {
return 0;
}
return count;
}
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
obj->i2c->A1 = address & 0xfe;
}

View File

@ -1,75 +0,0 @@
/* 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.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
uint32_t port;
uint32_t pin;
uint32_t ch;
};
struct port_s {
__IO uint32_t *reg_dir;
__IO uint32_t *reg_out;
__I uint32_t *reg_in;
PortName port;
uint32_t mask;
};
struct pwmout_s {
__IO uint32_t *MOD;
__IO uint32_t *CNT;
__IO uint32_t *CnV;
};
struct serial_s {
UARTLP_Type *uart;
int index;
};
struct analogin_s {
ADCName adc;
};
struct dac_s {
DACName dac;
};
struct i2c_s {
I2C_Type *i2c;
};
struct spi_s {
SPI_Type *spi;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,43 +0,0 @@
/* 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 "pinmap.h"
#include "error.h"
void pin_function(PinName pin, int function) {
if (pin == (PinName)NC) {
return;
}
uint32_t port_n = (uint32_t)pin >> PORT_SHIFT;
uint32_t pin_n = (uint32_t)(pin & 0x7C) >> 2;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port_n);
__IO uint32_t* pin_pcr = &(((PORT_Type *)(PORTA_BASE + (1 << PORT_SHIFT) * port_n)))->PCR[pin_n];
// pin mux bits: [10:8] -> 11100000000 = (0x700)
*pin_pcr = (*pin_pcr & ~0x700) | (function << 8);
}
void pin_mode(PinName pin, PinMode mode) {
if (pin == (PinName)NC) {
return;
}
__IO uint32_t* pin_pcr = (__IO uint32_t*)(PORTA_BASE + pin);
// pin pullup bits: [1:0] -> 11 = (0x3)
*pin_pcr = (*pin_pcr & ~0x3) | mode;
}

View File

@ -1,72 +0,0 @@
/* 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 "port_api.h"
#include "pinmap.h"
#include "gpio_api.h"
PinName port_pin(PortName port, int pin_n) {
return (PinName)((port << PORT_SHIFT) | (pin_n << 2));
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
obj->port = port;
obj->mask = mask;
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
obj->reg_out = &reg->PDOR;
obj->reg_in = &reg->PDIR;
obj->reg_dir = &reg->PDDR;
uint32_t i;
// The function is set per pin: reuse gpio logic
for (i=0; i<32; i++) {
if (obj->mask & (1<<i)) {
gpio_set(port_pin(obj->port, i));
}
}
port_dir(obj, dir);
}
void port_mode(port_t *obj, PinMode mode) {
uint32_t i;
// The mode is set per pin: reuse pinmap logic
for (i=0; i<32; i++) {
if (obj->mask & (1<<i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
void port_dir(port_t *obj, PinDirection dir) {
switch (dir) {
case PIN_INPUT:
*obj->reg_dir &= ~obj->mask;
break;
case PIN_OUTPUT:
*obj->reg_dir |= obj->mask;
break;
}
}
void port_write(port_t *obj, int value) {
*obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
}
int port_read(port_t *obj) {
return (*obj->reg_in & obj->mask);
}

View File

@ -1,118 +0,0 @@
/* 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 "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_PWM[] = {
// LEDs
{LED_RED , PWM_4 , 2}, // PTB8 , TPM0 CH3
{LED_GREEN, PWM_3, 2}, // PTB9 , TPM0 CH2
{LED_BLUE , PWM_2 , 2}, // PTB10, TPM0 CH1
// Arduino digital pinout
{D3, PWM_8 , 2}, // PTB5 , TPM1 CH1
{D5, PWM_7 , 2}, // PTA12, TPM1 CH0
{D6, PWM_4 , 2}, // PTB6 , TPM0 CH3
{D7, PWM_3 , 2}, // PTB7 , TPM0 CH2
{D8, PWM_2 , 2}, // PTB10, TPM0 CH1
{D9, PWM_1 , 2}, // PTB11, TPM0 CH0
{D10, PWM_6 , 2}, // PTA5 , TPM0 CH5
{D12, PWM_5 , 2}, // PTA6 , TPM0 CH4
{NC , NC , 0}
};
#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz
void pwmout_init(pwmout_t* obj, PinName pin) {
// determine the channel
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
if (pwm == (PWMName)NC) {
error("PwmOut pin mapping failed");
}
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
unsigned int tpm_n = (pwm >> TPM_SHIFT);
unsigned int ch_n = (pwm & 0xFF);
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz
tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); // No Interrupts; High True pulses on Edge Aligned PWM
obj->CnV = &tpm->CONTROLS[ch_n].CnV;
obj->MOD = &tpm->MOD;
obj->CNT = &tpm->CNT;
// default to 20ms: standard for servos, and fine for e.g. brightness control
pwmout_period_ms(obj, 20);
pwmout_write(obj, 0);
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
}
void pwmout_free(pwmout_t* obj) {
}
void pwmout_write(pwmout_t* obj, float value) {
if (value < 0.0) {
value = 0.0;
} else if (value > 1.0) {
value = 1.0;
}
*obj->CnV = (uint32_t)((float)(*obj->MOD) * value);
*obj->CNT = 0;
}
float pwmout_read(pwmout_t* obj) {
float v = (float)(*obj->CnV) / (float)(*obj->MOD);
return (v > 1.0) ? (1.0) : (v);
}
void pwmout_period(pwmout_t* obj, float seconds) {
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t* obj, int ms) {
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us) {
float dc = pwmout_read(obj);
*obj->MOD = PWM_CLOCK_MHZ * us;
pwmout_write(obj, dc);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
*obj->CnV = PWM_CLOCK_MHZ * us;
}

View File

@ -1,84 +0,0 @@
/* 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 "rtc_api.h"
static void init(void) {
// enable RTC clock
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
// select OSC32 as RTC clock source
SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;
}
void rtc_init(void) {
uint32_t i;
init();
//Configure the TSR. default value: 1
RTC->TSR = 1;
RTC->CR |= RTC_CR_OSCE_MASK;
//delay for OSCE stabilization
for(i=0; i<0x1000; i++) __NOP();
// enable counter
RTC->SR |= RTC_SR_TCE_MASK;
}
void rtc_free(void) {
// [TODO]
}
int rtc_isenabled(void) {
// even if the RTC module is enabled,
// as we use RTC_CLKIN and an external clock,
// we need to reconfigure the pins. That is why we
// call init() if the rtc is enabled
// if RTC not enabled return 0
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
if ((RTC->SR & RTC_SR_TCE_MASK) == 0) {
return 0;
}
init();
return 1;
}
time_t rtc_read(void) {
return RTC->TSR;
}
void rtc_write(time_t t) {
// disable counter
RTC->SR &= ~RTC_SR_TCE_MASK;
// we do not write 0 into TSR
// to avoid invalid time
if (t == 0) {
t = 1;
}
// write seconds
RTC->TSR = t;
// re-enable counter
RTC->SR |= RTC_SR_TCE_MASK;
}

View File

@ -1,288 +0,0 @@
/* 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 "serial_api.h"
// math.h required for floating point operations for baud rate calculation
#include <math.h>
#include <string.h>
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#define UART_CLOCK_HZ 47972352u
#define UART_NUM 1
static const PinMap PinMap_UART_TX[] = {
{PTB1, UART_0, 2},
{NC , NC , 0}
};
static const PinMap PinMap_UART_RX[] = {
{PTB2, UART_0, 2},
{NC , NC , 0}
};
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler;
int stdio_uart_inited = 0;
serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx) {
// determine the UART to use
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
if ((int)uart == NC) {
error("Serial pinout mapping failed");
}
obj->uart = (UARTLP_Type *)uart;
// enable clk
switch (uart) {
case UART_0:
SIM->SOPT2 |= 1 << SIM_SOPT2_UART0SRC_SHIFT;
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
SIM->SCGC4 |= SIM_SCGC4_UART0_MASK;
break;
}
// Disable UART before changing registers
obj->uart->C2 &= ~(UART0_C2_RE_MASK | UART0_C2_TE_MASK);
switch (uart) {
case UART_0:
obj->index = 0;
break;
}
// set default baud rate and format
serial_baud (obj, 9600);
serial_format(obj, 8, ParityNone, 1);
// pinout the chosen uart
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// set rx/tx pins in PullUp mode
pin_mode(tx, PullUp);
pin_mode(rx, PullUp);
obj->uart->C2 |= (UART0_C2_RE_MASK | UART0_C2_TE_MASK);
if (uart == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj) {
serial_irq_ids[obj->index] = 0;
}
void serial_baud(serial_t *obj, int baudrate) {
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART0_C2_RE_MASK | UART0_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART0_C2_RE_MASK | UART0_C2_TE_MASK);
// First we check to see if the basic divide with no DivAddVal/MulVal
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
// MulVal = 1. Otherwise, we search the valid ratio value range to find
// the closest match. This could be more elegant, using search methods
// and/or lookup tables, but the brute force method is not that much
// slower, and is more maintainable.
uint16_t DL = UART_CLOCK_HZ / (16 * baudrate);
// set BDH and BDL
obj->uart->BDH = (obj->uart->BDH & ~(0x1f)) | ((DL >> 8) & 0x1f);
obj->uart->BDL = (obj->uart->BDL & ~(0xff)) | ((DL >> 0) & 0xff);
// restore C2 state
obj->uart->C2 |= c2_state;
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
uint8_t m10 = 0;
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART0_C2_RE_MASK | UART0_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART0_C2_RE_MASK | UART0_C2_TE_MASK);
// 8 data bits = 0 ... 9 data bits = 1
if ((data_bits < 8) || (data_bits > 9)) {
error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
}
data_bits -= 8;
uint8_t parity_enable, parity_select;
switch (parity) {
case ParityNone: parity_enable = 0; parity_select = 0; break;
case ParityOdd : parity_enable = 1; parity_select = 1; data_bits++; break;
case ParityEven: parity_enable = 1; parity_select = 0; data_bits++; break;
default:
error("Invalid serial parity setting\r\n");
return;
}
// 1 stop bits = 0, 2 stop bits = 1
if ((stop_bits != 1) && (stop_bits != 2)) {
error("Invalid stop bits specified\r\n");
}
stop_bits -= 1;
// 9 data bits + parity
if (data_bits == 2) {
// only uart0 supports 10 bit communication
if (obj->index != 0) {
error("Invalid number of bits (9) to be used with parity\r\n");
}
data_bits = 0;
m10 = 1;
}
// data bits, parity and parity mode
obj->uart->C1 = ((data_bits << 4)
| (parity_enable << 1)
| (parity_select << 0));
// enable 10bit mode if needed
if (obj->index == 0) {
obj->uart->C4 &= ~UARTLP_C4_M10_MASK;
obj->uart->C4 |= (m10 << UARTLP_C4_M10_SHIFT);
}
// stop bits
obj->uart->BDH &= ~UART0_BDH_SBNS_MASK;
obj->uart->BDH |= (stop_bits << UART0_BDH_SBNS_SHIFT);
// restore C2 state
obj->uart->C2 |= c2_state;
}
static inline void uart_irq(uint8_t status, uint32_t index) {
if (serial_irq_ids[index] != 0) {
if (status & UART0_S1_TDRE_MASK)
irq_handler(serial_irq_ids[index], TxIrq);
if (status & UART0_S1_RDRF_MASK)
irq_handler(serial_irq_ids[index], RxIrq);
}
}
void uart0_irq() {
uart_irq(UART0->S1, 0);
if (UART0->S1 & UART0_S1_OR_MASK)
UART0->S1 |= UART0_S1_OR_MASK;
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
switch ((int)obj->uart) {
case UART_0:
irq_n=UART0_IRQn;
vector = (uint32_t)&uart0_irq;
break;
}
if (enable) {
switch (irq) {
case RxIrq:
obj->uart->C2 |= (UART0_C2_RIE_MASK);
break;
case TxIrq:
obj->uart->C2 |= (UART0_C2_TIE_MASK);
break;
}
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
} else { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) {
case RxIrq:
obj->uart->C2 &= ~(UART0_C2_RIE_MASK);
break;
case TxIrq:
obj->uart->C2 &= ~(UART0_C2_TIE_MASK);
break;
}
switch (other_irq) {
case RxIrq:
all_disabled = (obj->uart->C2 & (UART0_C2_RIE_MASK)) == 0;
break;
case TxIrq:
all_disabled = (obj->uart->C2 & (UART0_C2_TIE_MASK)) == 0;
break;
}
if (all_disabled)
NVIC_DisableIRQ(irq_n);
}
}
int serial_getc(serial_t *obj) {
while (!serial_readable(obj));
return obj->uart->D;
}
void serial_putc(serial_t *obj, int c) {
while (!serial_writable(obj));
obj->uart->D = c;
}
int serial_readable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART0_S1_OR_MASK) {
obj->uart->S1 |= UART0_S1_OR_MASK;
}
return (obj->uart->S1 & UART0_S1_RDRF_MASK);
}
int serial_writable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART0_S1_OR_MASK) {
obj->uart->S1 |= UART0_S1_OR_MASK;
}
return (obj->uart->S1 & UART0_S1_TDRE_MASK);
}
void serial_clear(serial_t *obj) {
}
void serial_pinout_tx(PinName tx) {
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj) {
obj->uart->C2 |= UART0_C2_SBK_MASK;
}
void serial_break_clear(serial_t *obj) {
obj->uart->C2 &= ~UART0_C2_SBK_MASK;
}

View File

@ -1,134 +0,0 @@
/* 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 <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
/* Prototypes */
static void pit_init(void);
static void lptmr_init(void);
static void lptmr_isr(void);
/* Global variables */
static uint32_t us_ticker_inited = 0;
static uint32_t us_ticker_int_counter = 0;
static uint16_t us_ticker_int_remainder = 0;
void us_ticker_init(void) {
if (us_ticker_inited) {
return;
}
us_ticker_inited = 1;
pit_init();
lptmr_init();
}
static void pit_init(void) {
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
PIT->MCR = 0; // Enable PIT
// Channel 1
PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;
PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK; // Chain to timer 0, disable Interrupts
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1
// Use channel 0 as a prescaler for channel 1
PIT->CHANNEL[0].LDVAL = 23;
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts
}
uint32_t us_ticker_read() {
if (!us_ticker_inited) {
us_ticker_init();
}
// The PIT is a countdown timer
return ~(PIT->CHANNEL[1].CVAL);
}
static void lptmr_init(void) {
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
LPTMR0->CSR = 0;
NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr);
NVIC_EnableIRQ(LPTimer_IRQn);
// Clock at (1)MHz -> (1)tick/us
LPTMR0->PSR = LPTMR_PSR_PCS(0); // MCGIRCLK -> 2MHz / presc 2 = 1MHz
}
void us_ticker_disable_interrupt(void) {
LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK;
}
void us_ticker_clear_interrupt(void) {
// we've already cleared interrupt in lptmr_isr
}
static void lptmr_set(unsigned short count) {
// Reset
LPTMR0->CSR = 0;
// Set the compare register
LPTMR0->CMR = count;
// Enable interrupt
LPTMR0->CSR |= LPTMR_CSR_TIE_MASK;
// Start the timer
LPTMR0->CSR |= LPTMR_CSR_TEN_MASK;
}
static void lptmr_isr(void) {
// write 1 to TCF to clear the LPT timer compare flag
LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;
if (us_ticker_int_counter > 0) {
lptmr_set(0xFFFF);
us_ticker_int_counter--;
} else {
if (us_ticker_int_remainder > 0) {
lptmr_set(us_ticker_int_remainder);
us_ticker_int_remainder = 0;
} else {
// This function is going to disable the interrupts if there are
// no other events in the queue
us_ticker_irq_handler();
}
}
}
void us_ticker_set_interrupt(unsigned int timestamp) {
int32_t delta = (int32_t)(timestamp - us_ticker_read());
if (delta <= 0) {
// This event was in the past:
us_ticker_irq_handler();
return;
}
us_ticker_int_counter = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta);
if (us_ticker_int_counter > 0) {
lptmr_set(0xFFFF);
us_ticker_int_counter--;
} else {
lptmr_set(us_ticker_int_remainder);
us_ticker_int_remainder = 0;
}
}

View File

@ -1,86 +0,0 @@
/* 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 "analogout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#define RANGE_12BIT 0xFFF
static const PinMap PinMap_DAC[] = {
{PTE30, DAC_0, 0},
{NC , NC , 0}
};
void analogout_init(dac_t *obj, PinName pin) {
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
if (obj->dac == (DACName)NC) {
error("DAC pin mapping failed");
}
SIM->SCGC6 |= SIM_SCGC6_DAC0_MASK;
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
DAC0->DAT[obj->dac].DATH = 0;
DAC0->DAT[obj->dac].DATL = 0;
DAC0->C1 = DAC_C1_DACBFMD_MASK; // One-Time Scan Mode
DAC0->C0 = DAC_C0_DACEN_MASK // Enable
| DAC_C0_DACSWTRG_MASK; // Software Trigger
pinmap_pinout(pin, PinMap_DAC);
analogout_write_u16(obj, 0);
}
void analogout_free(dac_t *obj) {}
static inline void dac_write(dac_t *obj, int value) {
DAC0->DAT[obj->dac].DATL = (uint8_t)( value & 0xFF);
DAC0->DAT[obj->dac].DATH = (uint8_t)((value >> 8) & 0xFF);
}
static inline int dac_read(dac_t *obj) {
return ((DAC0->DAT[obj->dac].DATH << 8) | DAC0->DAT[obj->dac].DATL);
}
void analogout_write(dac_t *obj, float value) {
if (value < 0.0) {
dac_write(obj, 0);
} else if (value > 1.0) {
dac_write(obj, RANGE_12BIT);
} else {
dac_write(obj, value * (float)RANGE_12BIT);
}
}
void analogout_write_u16(dac_t *obj, uint16_t value) {
dac_write(obj, value >> 4); // 12-bit
}
float analogout_read(dac_t *obj) {
uint32_t value = dac_read(obj);
return (float)value * (1.0f / (float)RANGE_12BIT);
}
uint16_t analogout_read_u16(dac_t *obj) {
uint32_t value = dac_read(obj); // 12-bit
return (value << 4) | ((value >> 8) & 0x003F);
}

View File

@ -1,91 +0,0 @@
/* 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 "rtc_api.h"
static void init(void) {
// enable PORTC clock
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
// enable RTC clock
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
/*
* configure PTC1 with alternate function 1: RTC_CLKIN
* As the kl25z board does not have a 32kHz osc,
* we use an external clock generated by the
* interface chip
*/
PORTC->PCR[1] &= ~PORT_PCR_MUX_MASK;
PORTC->PCR[1] = PORT_PCR_MUX(1);
// select RTC_CLKIN as RTC clock source
SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(2);
}
void rtc_init(void) {
init();
//Configure the TSR. default value: 1
RTC->TSR = 1;
// enable counter
RTC->SR |= RTC_SR_TCE_MASK;
}
void rtc_free(void) {
// [TODO]
}
/*
* Little check routine to see if the RTC has been enabled
* 0 = Disabled, 1 = Enabled
*/
int rtc_isenabled(void) {
// even if the RTC module is enabled,
// as we use RTC_CLKIN and an external clock,
// we need to reconfigure the pins. That is why we
// call init() if the rtc is enabled
// if RTC not enabled return 0
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
if ((RTC->SR & RTC_SR_TCE_MASK) == 0)
return 0;
init();
return 1;
}
time_t rtc_read(void) {
return RTC->TSR;
}
void rtc_write(time_t t) {
// disable counter
RTC->SR &= ~RTC_SR_TCE_MASK;
// we do not write 0 into TSR
// to avoid invalid time
if (t == 0)
t = 1;
// write seconds
RTC->TSR = t;
// re-enable counter
RTC->SR |= RTC_SR_TCE_MASK;
}

View File

@ -1,34 +0,0 @@
/* 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.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PortA = 0,
PortB = 1,
PortC = 2,
PortD = 3,
PortE = 4
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,94 +0,0 @@
/* 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 "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_ADC[] = {
{PTE20, ADC0_SE0, 0},
{PTE22, ADC0_SE3, 0},
{PTE21, ADC0_SE4a, 0},
{PTE29, ADC0_SE4b, 0},
{PTE30, ADC0_SE23, 0},
{PTE23, ADC0_SE7a, 0},
{PTB0, ADC0_SE8, 0},
{PTB1, ADC0_SE9, 0},
{PTB2, ADC0_SE12, 0},
{PTB3, ADC0_SE13, 0},
{PTC0, ADC0_SE14, 0},
{PTC1, ADC0_SE15, 0},
{PTC2, ADC0_SE11, 0},
{PTD1, ADC0_SE5b, 0},
{PTD5, ADC0_SE6b, 0},
{PTD6, ADC0_SE7b, 0},
{NC, NC, 0}
};
void analogin_init(analogin_t *obj, PinName pin) {
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (obj->adc == (ADCName)NC) {
error("ADC pin mapping failed");
}
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
uint32_t cfg2_muxsel = ADC_CFG2_MUXSEL_MASK;
if (obj->adc & (1 << CHANNELS_A_SHIFT)) {
cfg2_muxsel = 0;
}
ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc & ~(1 << CHANNELS_A_SHIFT));
ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration
| ADC_CFG1_ADIV(3) // Clock Divide Select: (Input Clock)/8
| ADC_CFG1_ADLSMP_MASK // Long Sample Time
| ADC_CFG1_MODE(3) // (16)bits Resolution
| ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2
ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels
| ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable
| ADC_CFG2_ADHSC_MASK // High-Speed Configuration
| ADC_CFG2_ADLSTS(0); // Long Sample Time Select
ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
| ADC_SC3_AVGS(0); // 4 Samples Averaged
pinmap_pinout(pin, PinMap_ADC);
}
uint16_t analogin_read_u16(analogin_t *obj) {
// start conversion
ADC0->SC1[0] = ADC_SC1_ADCH(obj->adc & ~(1 << CHANNELS_A_SHIFT));
// Wait Conversion Complete
while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
// Return value
return (uint16_t)ADC0->R[0];
}
float analogin_read(analogin_t *obj) {
uint16_t value = analogin_read_u16(obj);
return (float)value * (1.0f / (float)0xFFFF);
}

View File

@ -1,54 +0,0 @@
/* 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 "gpio_api.h"
#include "pinmap.h"
uint32_t gpio_set(PinName pin) {
pin_function(pin, 1);
return 1 << ((pin & 0x7F) >> 2);
}
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
if(pin == NC) return;
obj->pin = pin;
obj->mask = gpio_set(pin);
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
obj->reg_set = &reg->PSOR;
obj->reg_clr = &reg->PCOR;
obj->reg_in = &reg->PDIR;
obj->reg_dir = &reg->PDDR;
gpio_dir(obj, direction);
switch (direction) {
case PIN_OUTPUT: pin_mode(pin, PullNone); break;
case PIN_INPUT : pin_mode(pin, PullUp); break;
}
}
void gpio_mode(gpio_t *obj, PinMode mode) {
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction) {
switch (direction) {
case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
}
}

View File

@ -1,48 +0,0 @@
/* 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.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
uint32_t mask;
__IO uint32_t *reg_dir;
__IO uint32_t *reg_set;
__IO uint32_t *reg_clr;
__I uint32_t *reg_in;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value) {
if (value)
*obj->reg_set = obj->mask;
else
*obj->reg_clr = obj->mask;
}
static inline int gpio_read(gpio_t *obj) {
return ((*obj->reg_in & obj->mask) ? 1 : 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,423 +0,0 @@
/* 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 "i2c_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_I2C_SDA[] = {
{PTE25, I2C_0, 5},
{PTC9, I2C_0, 2},
{PTE0, I2C_1, 6},
{PTB1, I2C_0, 2},
{PTB3, I2C_0, 2},
{PTC11, I2C_1, 2},
{PTC2, I2C_1, 2},
{PTA4, I2C_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PTE24, I2C_0, 5},
{PTC8, I2C_0, 2},
{PTE1, I2C_1, 6},
{PTB0, I2C_0, 2},
{PTB2, I2C_0, 2},
{PTC10, I2C_1, 2},
{PTC1, I2C_1, 2},
{NC , NC, 0}
};
static const uint16_t ICR[0x40] = {
20, 22, 24, 26, 28,
30, 34, 40, 28, 32,
36, 40, 44, 48, 56,
68, 48, 56, 64, 72,
80, 88, 104, 128, 80,
96, 112, 128, 144, 160,
192, 240, 160, 192, 224,
256, 288, 320, 384, 480,
320, 384, 448, 512, 576,
640, 768, 960, 640, 768,
896, 1024, 1152, 1280, 1536,
1920, 1280, 1536, 1792, 2048,
2304, 2560, 3072, 3840
};
static uint8_t first_read;
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2C_Type*)pinmap_merge(i2c_sda, i2c_scl);
if ((int)obj->i2c == NC) {
error("I2C pin mapping failed");
}
// enable power
switch ((int)obj->i2c) {
case I2C_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 6; break;
case I2C_1: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 7; break;
}
// set default frequency at 100k
i2c_frequency(obj, 100000);
// enable I2C interface
obj->i2c->C1 |= 0x80;
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
first_read = 1;
}
int i2c_start(i2c_t *obj) {
uint8_t temp;
volatile int i;
// if we are in the middle of a transaction
// activate the repeat_start flag
if (obj->i2c->S & I2C_S_BUSY_MASK) {
// KL25Z errata sheet: repeat start cannot be generated if the
// I2Cx_F[MULT] field is set to a non-zero value
temp = obj->i2c->F >> 6;
obj->i2c->F &= 0x3F;
obj->i2c->C1 |= 0x04;
for (i = 0; i < 100; i ++) __NOP();
obj->i2c->F |= temp << 6;
} else {
obj->i2c->C1 |= I2C_C1_MST_MASK;
obj->i2c->C1 |= I2C_C1_TX_MASK;
}
first_read = 1;
return 0;
}
int i2c_stop(i2c_t *obj) {
volatile uint32_t n = 0;
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// It seems that there are timing problems
// when there is no waiting time after a STOP.
// This wait is also included on the samples
// code provided with the freedom board
for (n = 0; n < 100; n++) __NOP();
first_read = 1;
return 0;
}
static int timeout_status_poll(i2c_t *obj, uint32_t mask) {
uint32_t i, timeout = 1000;
for (i = 0; i < timeout; i++) {
if (obj->i2c->S & mask)
return 0;
}
return 1;
}
// this function waits the end of a tx transfer and return the status of the transaction:
// 0: OK ack received
// 1: OK ack not received
// 2: failure
static int i2c_wait_end_tx_transfer(i2c_t *obj) {
// wait for the interrupt flag
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
return 2;
}
obj->i2c->S |= I2C_S_IICIF_MASK;
// wait transfer complete
if (timeout_status_poll(obj, I2C_S_TCF_MASK)) {
return 2;
}
// check if we received the ACK or not
return obj->i2c->S & I2C_S_RXAK_MASK ? 1 : 0;
}
// this function waits the end of a rx transfer and return the status of the transaction:
// 0: OK
// 1: failure
static int i2c_wait_end_rx_transfer(i2c_t *obj) {
// wait for the end of the rx transfer
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
return 1;
}
obj->i2c->S |= I2C_S_IICIF_MASK;
return 0;
}
static void i2c_send_nack(i2c_t *obj) {
obj->i2c->C1 |= I2C_C1_TXAK_MASK; // NACK
}
static void i2c_send_ack(i2c_t *obj) {
obj->i2c->C1 &= ~I2C_C1_TXAK_MASK; // ACK
}
static int i2c_do_write(i2c_t *obj, int value) {
// write the data
obj->i2c->D = value;
// init and wait the end of the transfer
return i2c_wait_end_tx_transfer(obj);
}
static int i2c_do_read(i2c_t *obj, char * data, int last) {
if (last)
i2c_send_nack(obj);
else
i2c_send_ack(obj);
*data = (obj->i2c->D & 0xFF);
// start rx transfer and wait the end of the transfer
return i2c_wait_end_rx_transfer(obj);
}
void i2c_frequency(i2c_t *obj, int hz) {
uint8_t icr = 0;
uint8_t mult = 0;
uint32_t error = 0;
uint32_t p_error = 0xffffffff;
uint32_t ref = 0;
uint8_t i, j;
// bus clk
uint32_t PCLK = 24000000u;
uint32_t pulse = PCLK / (hz * 2);
// we look for the values that minimize the error
// test all the MULT values
for (i = 1; i < 5; i*=2) {
for (j = 0; j < 0x40; j++) {
ref = PCLK / (i*ICR[j]);
if (ref > (uint32_t)hz)
continue;
error = hz - ref;
if (error < p_error) {
icr = j;
mult = i/2;
p_error = error;
}
}
}
pulse = icr | (mult << 6);
// I2C Rate
obj->i2c->F = pulse;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int count;
char dummy_read, *ptr;
if (i2c_start(obj)) {
i2c_stop(obj);
return I2C_ERROR_BUS_BUSY;
}
if (i2c_do_write(obj, (address | 0x01))) {
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// Read in bytes
for (count = 0; count < (length); count++) {
ptr = (count == 0) ? &dummy_read : &data[count - 1];
uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
if (i2c_do_read(obj, ptr, stop_)) {
i2c_stop(obj);
return count;
}
}
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
}
// last read
data[count-1] = obj->i2c->D;
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
int i;
if (i2c_start(obj)) {
i2c_stop(obj);
return I2C_ERROR_BUS_BUSY;
}
if (i2c_do_write(obj, (address & 0xFE))) {
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
for (i = 0; i < length; i++) {
if(i2c_do_write(obj, data[i])) {
i2c_stop(obj);
return i;
}
}
if (stop) {
i2c_stop(obj);
}
return length;
}
void i2c_reset(i2c_t *obj) {
i2c_stop(obj);
}
int i2c_byte_read(i2c_t *obj, int last) {
char data;
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
if(first_read) {
// first dummy read
i2c_do_read(obj, &data, 0);
first_read = 0;
}
if (last) {
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
return obj->i2c->D;
}
i2c_do_read(obj, &data, last);
return data;
}
int i2c_byte_write(i2c_t *obj, int data) {
first_read = 1;
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
return !i2c_do_write(obj, (data & 0xFF));
}
#if DEVICE_I2CSLAVE
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
if (enable_slave) {
// set slave mode
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
obj->i2c->C1 |= I2C_C1_IICIE_MASK;
} else {
// set master mode
obj->i2c->C1 |= I2C_C1_MST_MASK;
}
}
int i2c_slave_receive(i2c_t *obj) {
switch(obj->i2c->S) {
// read addressed
case 0xE6: return 1;
// write addressed
case 0xE2: return 3;
default: return 0;
}
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
uint8_t dummy_read;
uint8_t * ptr;
int count;
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// first dummy read
dummy_read = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return 0;
}
// read address
dummy_read = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return 0;
}
// read (length - 1) bytes
for (count = 0; count < (length - 1); count++) {
data[count] = obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj)) {
return count;
}
}
// read last byte
ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
*ptr = obj->i2c->D;
return (length) ? (count + 1) : 0;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int i, count = 0;
// set tx mode
obj->i2c->C1 |= I2C_C1_TX_MASK;
for (i = 0; i < length; i++) {
if(i2c_do_write(obj, data[count++]) == 2) {
return i;
}
}
// set rx mode
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
// dummy rx transfer needed
// otherwise the master cannot generate a stop bit
obj->i2c->D;
if(i2c_wait_end_rx_transfer(obj) == 2) {
return count;
}
return count;
}
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
obj->i2c->A1 = address & 0xfe;
}
#endif

View File

@ -1,75 +0,0 @@
/* 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.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
uint32_t port;
uint32_t pin;
uint32_t ch;
};
struct port_s {
__IO uint32_t *reg_dir;
__IO uint32_t *reg_out;
__I uint32_t *reg_in;
PortName port;
uint32_t mask;
};
struct pwmout_s {
__IO uint32_t *MOD;
__IO uint32_t *CNT;
__IO uint32_t *CnV;
};
struct serial_s {
UART0_Type *uart;
int index;
};
struct analogin_s {
ADCName adc;
};
struct dac_s {
DACName dac;
};
struct i2c_s {
I2C_Type *i2c;
};
struct spi_s {
SPI_Type *spi;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,39 +0,0 @@
/* 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 "pinmap.h"
#include "error.h"
void pin_function(PinName pin, int function) {
if (pin == (PinName)NC) return;
uint32_t port_n = (uint32_t)pin >> PORT_SHIFT;
uint32_t pin_n = (uint32_t)(pin & 0x7C) >> 2;
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port_n);
__IO uint32_t* pin_pcr = &(((PORT_Type *)(PORTA_BASE + 0x1000 * port_n)))->PCR[pin_n];
// pin mux bits: [10:8] -> 11100000000 = (0x700)
*pin_pcr = (*pin_pcr & ~0x700) | (function << 8);
}
void pin_mode(PinName pin, PinMode mode) {
if (pin == (PinName)NC) { return; }
__IO uint32_t* pin_pcr = (__IO uint32_t*)(PORTA_BASE + pin);
// pin pullup bits: [1:0] -> 11 = (0x3)
*pin_pcr = (*pin_pcr & ~0x3) | mode;
}

View File

@ -1,68 +0,0 @@
/* 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 "port_api.h"
#include "pinmap.h"
#include "gpio_api.h"
PinName port_pin(PortName port, int pin_n) {
return (PinName)((port << PORT_SHIFT) | (pin_n << 2));
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
obj->port = port;
obj->mask = mask;
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
obj->reg_out = &reg->PDOR;
obj->reg_in = &reg->PDIR;
obj->reg_dir = &reg->PDDR;
uint32_t i;
// The function is set per pin: reuse gpio logic
for (i=0; i<32; i++) {
if (obj->mask & (1<<i)) {
gpio_set(port_pin(obj->port, i));
}
}
port_dir(obj, dir);
}
void port_mode(port_t *obj, PinMode mode) {
uint32_t i;
// The mode is set per pin: reuse pinmap logic
for (i=0; i<32; i++) {
if (obj->mask & (1<<i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
void port_dir(port_t *obj, PinDirection dir) {
switch (dir) {
case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
}
}
void port_write(port_t *obj, int value) {
*obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
}
int port_read(port_t *obj) {
return (*obj->reg_in & obj->mask);
}

View File

@ -1,143 +0,0 @@
/* 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 "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
static const PinMap PinMap_PWM[] = {
// LEDs - only RED pin is PWM capable
{LED_RED, PWM_3, 3}, // PTE29, TPM0 CH2
// Arduino digital pinout
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
{D2, PWM_4 , 4}, // PTD3 , TPM0 CH3
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
{D9, PWM_3 , 4}, // PTD2 , TPM0 CH2
{D10, PWM_5 , 4}, // PTD4 , TPM0 CH4
//PWM on D11 not available
//PWM on D12 not available
{D13, PWM_2 , 4}, // PTD5 , TPM0 CH1,
{PTA0, PWM_6, 3},
{PTA3, PWM_1, 3},
{PTA6, PWM_4, 3},
{PTA7, PWM_5, 3},
{PTB0, PWM_7, 3},
{PTB1, PWM_8, 3},
{PTB2, PWM_9, 3},
{PTB3, PWM_10, 3},
{PTC1, PWM_1, 4},
{PTC2, PWM_2, 4},
{PTC3, PWM_3, 4},
{PTC4, PWM_4, 4},
{PTE20, PWM_7, 3},
{PTE21, PWM_8, 3},
{PTE22, PWM_9, 3},
{PTE23, PWM_10, 3},
{PTE24, PWM_1, 3},
{PTE25, PWM_2, 3},
{PTE26, PWM_6, 3},
{PTE29, PWM_3, 3},
{PTE30, PWM_4, 3},
{PTE31, PWM_5, 3},
{NC , NC , 0}
};
#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz
void pwmout_init(pwmout_t* obj, PinName pin) {
// determine the channel
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
if (pwm == (PWMName)NC)
error("PwmOut pin mapping failed");
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
unsigned int tpm_n = (pwm >> TPM_SHIFT);
unsigned int ch_n = (pwm & 0xFF);
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz
tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */
obj->CnV = &tpm->CONTROLS[ch_n].CnV;
obj->MOD = &tpm->MOD;
obj->CNT = &tpm->CNT;
// default to 20ms: standard for servos, and fine for e.g. brightness control
pwmout_period_ms(obj, 20);
pwmout_write (obj, 0);
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
}
void pwmout_free(pwmout_t* obj) {}
void pwmout_write(pwmout_t* obj, float value) {
if (value < 0.0) {
value = 0.0;
} else if (value > 1.0) {
value = 1.0;
}
*obj->CnV = (uint32_t)((float)(*obj->MOD) * value);
*obj->CNT = 0;
}
float pwmout_read(pwmout_t* obj) {
float v = (float)(*obj->CnV) / (float)(*obj->MOD);
return (v > 1.0) ? (1.0) : (v);
}
void pwmout_period(pwmout_t* obj, float seconds) {
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t* obj, int ms) {
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us) {
float dc = pwmout_read(obj);
*obj->MOD = PWM_CLOCK_MHZ * us;
pwmout_write(obj, dc);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
*obj->CnV = PWM_CLOCK_MHZ * us;
}

View File

@ -1,317 +0,0 @@
/* 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 "serial_api.h"
// math.h required for floating point operations for baud rate calculation
#include <math.h>
#include <string.h>
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
/******************************************************************************
* INITIALIZATION
******************************************************************************/
static const PinMap PinMap_UART_TX[] = {
{PTA2, UART_0, 2},
{PTA14, UART_0, 3},
{PTC4, UART_1, 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},
{NC , NC , 0}
};
static const PinMap PinMap_UART_RX[] = {
{PTA1, UART_0, 2},
{PTA15, 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}
};
#define UART_NUM 3
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler;
int stdio_uart_inited = 0;
serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx) {
// determine the UART to use
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
if ((int)uart == NC) {
error("Serial pinout mapping failed");
}
obj->uart = (UART0_Type *)uart;
// enable clk
switch (uart) {
case UART_0: SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | (1<<SIM_SOPT2_UART0SRC_SHIFT);
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
case UART_1: SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; break;
case UART_2: SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; break;
}
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
switch (uart) {
case UART_0: obj->index = 0; break;
case UART_1: obj->index = 1; break;
case UART_2: obj->index = 2; break;
}
// set default baud rate and format
serial_baud (obj, 9600);
serial_format(obj, 8, ParityNone, 1);
// pinout the chosen uart
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// set rx/tx pins in PullUp mode
pin_mode(tx, PullUp);
pin_mode(rx, PullUp);
obj->uart->C2 |= (UART_C2_RE_MASK | UART_C2_TE_MASK);
if (uart == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj) {
serial_irq_ids[obj->index] = 0;
}
// serial_baud
//
// set the baud rate, taking in to account the current SystemFrequency
//
// The LPC2300 and LPC1700 have a divider and a fractional divider to control the
// baud rate. The formula is:
//
// Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal)
// where:
// 1 < MulVal <= 15
// 0 <= DivAddVal < 14
// DivAddVal < MulVal
//
void serial_baud(serial_t *obj, int baudrate) {
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
// [TODO] not hardcode this value
uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u;
// First we check to see if the basic divide with no DivAddVal/MulVal
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
// MulVal = 1. Otherwise, we search the valid ratio value range to find
// the closest match. This could be more elegant, using search methods
// and/or lookup tables, but the brute force method is not that much
// slower, and is more maintainable.
uint16_t DL = PCLK / (16 * baudrate);
// set BDH and BDL
obj->uart->BDH = (obj->uart->BDH & ~(0x1f)) | ((DL >> 8) & 0x1f);
obj->uart->BDL = (obj->uart->BDL & ~(0xff)) | ((DL >> 0) & 0xff);
// restore C2 state
obj->uart->C2 |= c2_state;
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
uint8_t m10 = 0;
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
// 8 data bits = 0 ... 9 data bits = 1
if ((data_bits < 8) || (data_bits > 9)) {
error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
}
data_bits -= 8;
uint8_t parity_enable, parity_select;
switch (parity) {
case ParityNone: parity_enable = 0; parity_select = 0; break;
case ParityOdd : parity_enable = 1; parity_select = 1; data_bits++; break;
case ParityEven: parity_enable = 1; parity_select = 0; data_bits++; break;
default:
error("Invalid serial parity setting\r\n");
return;
}
// 1 stop bits = 0, 2 stop bits = 1
if ((stop_bits != 1) && (stop_bits != 2)) {
error("Invalid stop bits specified\r\n");
}
stop_bits -= 1;
// 9 data bits + parity
if (data_bits == 2) {
// only uart0 supports 10 bit communication
if (obj->index != 0) {
error("Invalid number of bits (9) to be used with parity\r\n");
}
data_bits = 0;
m10 = 1;
}
// data bits, parity and parity mode
obj->uart->C1 = ((data_bits << 4)
| (parity_enable << 1)
| (parity_select << 0));
// enable 10bit mode if needed
if (obj->index == 0) {
obj->uart->C4 &= ~UART0_C4_M10_MASK;
obj->uart->C4 |= (m10 << UART0_C4_M10_SHIFT);
}
// stop bits
obj->uart->BDH &= ~UART_BDH_SBNS_MASK;
obj->uart->BDH |= (stop_bits << UART_BDH_SBNS_SHIFT);
// restore C2 state
obj->uart->C2 |= c2_state;
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
static inline void uart_irq(uint8_t status, uint32_t index) {
if (serial_irq_ids[index] != 0) {
if (status & UART_S1_TDRE_MASK)
irq_handler(serial_irq_ids[index], TxIrq);
if (status & UART_S1_RDRF_MASK)
irq_handler(serial_irq_ids[index], RxIrq);
}
}
void uart0_irq() {
uart_irq(UART0->S1, 0);
if (UART0->S1 & UART_S1_OR_MASK)
UART0->S1 |= UART_S1_OR_MASK;
}
void uart1_irq() {uart_irq(UART1->S1, 1);}
void uart2_irq() {uart_irq(UART2->S1, 2);}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
switch ((int)obj->uart) {
case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
}
if (enable) {
switch (irq) {
case RxIrq: obj->uart->C2 |= (UART_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 |= (UART_C2_TIE_MASK); break;
}
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
} else { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) {
case RxIrq: obj->uart->C2 &= ~(UART_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 &= ~(UART_C2_TIE_MASK); break;
}
switch (other_irq) {
case RxIrq: all_disabled = (obj->uart->C2 & (UART_C2_RIE_MASK)) == 0; break;
case TxIrq: all_disabled = (obj->uart->C2 & (UART_C2_TIE_MASK)) == 0; break;
}
if (all_disabled)
NVIC_DisableIRQ(irq_n);
}
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj) {
while (!serial_readable(obj));
return obj->uart->D;
}
void serial_putc(serial_t *obj, int c) {
while (!serial_writable(obj));
obj->uart->D = c;
}
int serial_readable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART_S1_OR_MASK) {
obj->uart->S1 |= UART_S1_OR_MASK;
}
return (obj->uart->S1 & UART_S1_RDRF_MASK);
}
int serial_writable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART_S1_OR_MASK) {
obj->uart->S1 |= UART_S1_OR_MASK;
}
return (obj->uart->S1 & UART_S1_TDRE_MASK);
}
void serial_clear(serial_t *obj) {
}
void serial_pinout_tx(PinName tx) {
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj) {
obj->uart->C2 |= UART_C2_SBK_MASK;
}
void serial_break_clear(serial_t *obj) {
obj->uart->C2 &= ~UART_C2_SBK_MASK;
}

View File

@ -1,51 +0,0 @@
/* 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 "sleep_api.h"
#include "cmsis.h"
//Normal wait mode
void sleep(void)
{
SMC->PMPROT = SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK;
//Normal sleep mode for ARM core:
SCB->SCR = 0;
__WFI();
}
//Very low-power stop mode
void deepsleep(void)
{
//Check if PLL/FLL is enabled:
uint32_t PLL_FLL_en = (MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0);
SMC->PMPROT = SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK;
SMC->PMCTRL = SMC_PMCTRL_STOPM(2);
//Deep sleep for ARM core:
SCB->SCR = 1<<SCB_SCR_SLEEPDEEP_Pos;
__WFI();
//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) {
if (MCG->C6 & (1<<MCG_C6_PLLS_SHIFT) != 0) /* If PLL */
while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U); /* Wait until locked */
MCG->C1 &= ~MCG_C1_CLKS_MASK;
}
}

View File

@ -1,146 +0,0 @@
/* 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 <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
static void pit_init(void);
static void lptmr_init(void);
static int us_ticker_inited = 0;
void us_ticker_init(void) {
if (us_ticker_inited) return;
us_ticker_inited = 1;
pit_init();
lptmr_init();
}
/******************************************************************************
* Timer for us timing.
******************************************************************************/
static void pit_init(void) {
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
PIT->MCR = 0; // Enable PIT
// Channel 1
PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;
PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK; // Chain to timer 0, disable Interrupts
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1
// Use channel 0 as a prescaler for channel 1
PIT->CHANNEL[0].LDVAL = 23;
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts
}
uint32_t us_ticker_read() {
if (!us_ticker_inited)
us_ticker_init();
// The PIT is a countdown timer
return ~(PIT->CHANNEL[1].CVAL);
}
/******************************************************************************
* Timer Event
*
* It schedules interrupts at given (32bit)us interval of time.
* It is implemented used the 16bit Low Power Timer that remains powered in all
* power modes.
******************************************************************************/
static void lptmr_isr(void);
static void lptmr_init(void) {
/* Clock the timer */
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
/* Reset */
LPTMR0->CSR = 0;
/* Set interrupt handler */
NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr);
NVIC_EnableIRQ(LPTimer_IRQn);
/* Clock at (1)MHz -> (1)tick/us */
LPTMR0->PSR = LPTMR_PSR_PCS(3); // OSCERCLK -> 8MHz
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8
}
void us_ticker_disable_interrupt(void) {
LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK;
}
void us_ticker_clear_interrupt(void) {
// we already clear interrupt in lptmr_isr
}
static uint32_t us_ticker_int_counter = 0;
static uint16_t us_ticker_int_remainder = 0;
static void lptmr_set(unsigned short count) {
/* Reset */
LPTMR0->CSR = 0;
/* Set the compare register */
LPTMR0->CMR = count;
/* Enable interrupt */
LPTMR0->CSR |= LPTMR_CSR_TIE_MASK;
/* Start the timer */
LPTMR0->CSR |= LPTMR_CSR_TEN_MASK;
}
static void lptmr_isr(void) {
// write 1 to TCF to clear the LPT timer compare flag
LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;
if (us_ticker_int_counter > 0) {
lptmr_set(0xFFFF);
us_ticker_int_counter--;
} else {
if (us_ticker_int_remainder > 0) {
lptmr_set(us_ticker_int_remainder);
us_ticker_int_remainder = 0;
} else {
// This function is going to disable the interrupts if there are
// no other events in the queue
us_ticker_irq_handler();
}
}
}
void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read());
if (delta <= 0) {
// This event was in the past:
us_ticker_irq_handler();
return;
}
us_ticker_int_counter = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta);
if (us_ticker_int_counter > 0) {
lptmr_set(0xFFFF);
us_ticker_int_counter--;
} else {
lptmr_set(us_ticker_int_remainder);
us_ticker_int_remainder = 0;
}
}

View File

@ -0,0 +1,49 @@
/* 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.
*/
#ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
/************RTC***************/
extern const PinMap PinMap_RTC[];
/************ADC***************/
extern const PinMap PinMap_ADC[];
/************DAC***************/
extern const PinMap PinMap_DAC[];
/************I2C***************/
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
/************UART***************/
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
/************SPI***************/
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SSEL[];
/************PWM***************/
extern const PinMap PinMap_PWM[];
#endif

View File

@ -22,6 +22,11 @@
extern "C" {
#endif
typedef enum {
OSC32KCLK = 0,
RTC_CLKIN = 2
} RTCName;
typedef enum {
UART_0 = (int)UART0_BASE
} UARTName;
@ -31,7 +36,8 @@ typedef enum {
#define STDIO_UART UART_0
typedef enum {
I2C_0 = (int)I2C0_BASE
I2C_0 = (int)I2C0_BASE,
I2C_1 = -1
} I2CName;
typedef enum {

View File

@ -0,0 +1,111 @@
/* 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 "PeripheralPins.h"
/************RTC***************/
const PinMap PinMap_RTC[] = {
{NC, OSC32KCLK, 0},
};
/************ADC***************/
const PinMap PinMap_ADC[] = {
/* A0-A5 pins */
{PTA0, ADC0_SE12, 0},
{PTA8, ADC0_SE3, 0},
{PTA9, ADC0_SE2, 0},
{PTB8, ADC0_SE11, 0},
{PTB9, ADC0_SE10, 0},
{PTB13, ADC0_SE13, 0},
/* Rest of pins ADC Mux */
{PTB2, ADC0_SE4, 0},
{PTB1, ADC0_SE5, 0},
{PTB5, ADC0_SE1, 0},
{PTA12, ADC0_SE0, 0},
{PTB10, ADC0_SE9, 0},
{PTB11, ADC0_SE8, 0},
{PTB7, ADC0_SE7, 0},
{PTB0, ADC0_SE6, 0},
{NC, NC, 0}
};
/************DAC***************/
const PinMap PinMap_DAC[] = {
{PTB1, DAC_0, 0},
{NC , NC , 0}
};
/************I2C***************/
const PinMap PinMap_I2C_SDA[] = {
{PTB4, I2C_0, 2},
{NC , NC , 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PTB3, I2C_0, 2},
{NC , NC , 0}
};
/************UART***************/
const PinMap PinMap_UART_TX[] = {
{PTB1, UART_0, 2},
{NC , NC , 0}
};
const PinMap PinMap_UART_RX[] = {
{PTB2, UART_0, 2},
{NC , NC , 0}
};
/************SPI***************/
const PinMap PinMap_SPI_SCLK[] = {
{PTB0, SPI_0, 3},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MOSI[] = {
{PTA7, SPI_0, 3},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PTA6, SPI_0, 3},
{NC , NC , 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PTA5, SPI_0, 3},
{NC , NC , 0}
};
/************PWM***************/
const PinMap PinMap_PWM[] = {
// LEDs
{LED_RED , PWM_4 , 2}, // PTB8 , TPM0 CH3
{LED_GREEN, PWM_3, 2}, // PTB9 , TPM0 CH2
{LED_BLUE , PWM_2 , 2}, // PTB10, TPM0 CH1
// Arduino digital pinout
{D3, PWM_8 , 2}, // PTB5 , TPM1 CH1
{D5, PWM_7 , 2}, // PTA12, TPM1 CH0
{D6, PWM_4 , 2}, // PTB6 , TPM0 CH3
{D7, PWM_3 , 2}, // PTB7 , TPM0 CH2
{D8, PWM_2 , 2}, // PTB10, TPM0 CH1
{D9, PWM_1 , 2}, // PTB11, TPM0 CH0
{D10, PWM_6 , 2}, // PTA5 , TPM0 CH5
{D12, PWM_5 , 2}, // PTA6 , TPM0 CH4
{NC , NC , 0}
};

View File

@ -22,6 +22,11 @@
extern "C" {
#endif
typedef enum {
OSC32KCLK = 0,
RTC_CLKIN = 2
} RTCName;
typedef enum {
UART_0 = (int)UART0_BASE,
UART_1 = (int)UART1_BASE,
@ -52,7 +57,7 @@ typedef enum {
PWM_10 = (2 << TPM_SHIFT) | (1) // TPM2 CH1
} PWMName;
#define CHANNELS_A_SHIFT 5
#define CHANNELS_A_SHIFT 5
typedef enum {
ADC0_SE0 = 0,
ADC0_SE3 = 3,

View File

@ -0,0 +1,198 @@
/* 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 "PeripheralPins.h"
/************RTC***************/
const PinMap PinMap_RTC[] = {
{PTC1, RTC_CLKIN, 2},
};
/************ADC***************/
const PinMap PinMap_ADC[] = {
{PTE20, ADC0_SE0, 0},
{PTE22, ADC0_SE3, 0},
{PTE21, ADC0_SE4a, 0},
{PTE29, ADC0_SE4b, 0},
{PTE30, ADC0_SE23, 0},
{PTE23, ADC0_SE7a, 0},
{PTB0, ADC0_SE8, 0},
{PTB1, ADC0_SE9, 0},
{PTB2, ADC0_SE12, 0},
{PTB3, ADC0_SE13, 0},
{PTC0, ADC0_SE14, 0},
{PTC1, ADC0_SE15, 0},
{PTC2, ADC0_SE11, 0},
{PTD1, ADC0_SE5b, 0},
{PTD5, ADC0_SE6b, 0},
{PTD6, ADC0_SE7b, 0},
{NC, NC, 0}
};
/************DAC***************/
const PinMap PinMap_DAC[] = {
{PTE30, DAC_0, 0},
{NC , NC , 0}
};
/************I2C***************/
const PinMap PinMap_I2C_SDA[] = {
{PTE25, I2C_0, 5},
{PTC9, I2C_0, 2},
{PTE0, I2C_1, 6},
{PTB1, I2C_0, 2},
{PTB3, I2C_0, 2},
{PTC11, I2C_1, 2},
{PTC2, I2C_1, 2},
{PTA4, I2C_1, 2},
{NC , NC , 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PTE24, I2C_0, 5},
{PTC8, I2C_0, 2},
{PTE1, I2C_1, 6},
{PTB0, I2C_0, 2},
{PTB2, I2C_0, 2},
{PTC10, I2C_1, 2},
{PTC1, I2C_1, 2},
{NC , NC, 0}
};
/************UART***************/
const PinMap PinMap_UART_TX[] = {
{PTC4, UART_1, 3},
{PTA2, UART_0, 2},
{PTD5, UART_2, 3},
{PTD3, UART_2, 3},
{PTD7, UART_0, 3},
{PTE20, UART_0, 4},
{PTE22, UART_2, 4},
{PTE0, UART_1, 3},
{NC , NC , 0}
};
const PinMap PinMap_UART_RX[] = {
{PTC3, UART_1, 3},
{PTA1, UART_0, 2},
{PTD4, UART_2, 3},
{PTD2, UART_2, 3},
{PTD6, UART_0, 3},
{PTE23, UART_2, 4},
{PTE21, UART_0, 4},
{PTE1, UART_1, 3},
{NC , NC , 0}
};
/************SPI***************/
const PinMap PinMap_SPI_SCLK[] = {
{PTA15, SPI_0, 2},
{PTB11, SPI_1, 2},
{PTC5, SPI_0, 2},
{PTD1, SPI_0, 2},
{PTD5, SPI_1, 2},
{PTE2, SPI_1, 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},
{PTC7, SPI_0, 5},
{PTD2, SPI_0, 2},
{PTD3, SPI_0, 5},
{PTD6, SPI_1, 2},
{PTD7, SPI_1, 5},
{PTE1, SPI_1, 2},
{PTE3, SPI_1, 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},
{PTC7, SPI_0, 2},
{PTD2, SPI_0, 5},
{PTD3, SPI_0, 2},
{PTD6, SPI_1, 5},
{PTD7, SPI_1, 2},
{PTE1, SPI_1, 5},
{PTE3, SPI_1, 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},
{NC , NC , 0}
};
/************PWM***************/
const PinMap PinMap_PWM[] = {
// LEDs
{LED_RED , PWM_9 , 3}, // PTB18, TPM2 CH0
{LED_GREEN, PWM_10, 3}, // PTB19, TPM2 CH1
{LED_BLUE , PWM_2 , 4}, // PTD1 , TPM0 CH1
// Arduino digital pinout
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
{D2, PWM_5 , 4}, // PTD4 , TPM0 CH4
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
{D9, PWM_6 , 4}, // PTD5 , TPM0 CH5
{D10, PWM_1 , 4}, // PTD0 , TPM0 CH0
{D11, PWM_3 , 4}, // PTD2 , TPM0 CH2
{D12, PWM_4 , 4}, // PTD3 , TPM0 CH3
{D13, PWM_2 , 4}, // PTD1 , TPM0 CH1,
{PTA0, PWM_6, 3},
{PTA3, PWM_1, 3},
{PTB0, PWM_7, 3},
{PTB1, PWM_8, 3},
{PTB2, PWM_9, 3},
{PTB3, PWM_10, 3},
{PTC1, PWM_1, 4},
{PTC2, PWM_2, 4},
{PTC3, PWM_3, 4},
{PTC4, PWM_4, 4},
{PTE20, PWM_7, 3},
{PTE21, PWM_8, 3},
{PTE22, PWM_9, 3},
{PTE23, PWM_10, 3},
{PTE24, PWM_1, 3},
{PTE25, PWM_2, 3},
{PTE29, PWM_3, 3},
{PTE30, PWM_4, 3},
{PTE31, PWM_5, 3},
{NC , NC , 0}
};

View File

@ -21,58 +21,7 @@
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"
static const PinMap PinMap_SPI_SCLK[] = {
{PTA15, SPI_0, 2},
{PTB11, SPI_1, 2},
{PTC5, SPI_0, 2},
{PTD1, SPI_0, 2},
{PTD5, SPI_1, 2},
{PTE2, SPI_1, 2},
{NC , NC , 0}
};
static 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},
{PTC7, SPI_0, 5},
{PTD2, SPI_0, 2},
{PTD3, SPI_0, 5},
{PTD6, SPI_1, 2},
{PTD7, SPI_1, 5},
{PTE1, SPI_1, 2},
{PTE3, SPI_1, 5},
{NC , NC , 0}
};
static 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},
{PTC7, SPI_0, 2},
{PTD2, SPI_0, 5},
{PTD3, SPI_0, 2},
{PTD6, SPI_1, 5},
{PTD7, SPI_1, 2},
{PTE1, SPI_1, 5},
{PTE3, SPI_1, 2},
{NC , NC , 0}
};
static 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},
{NC , NC , 0}
};
#include "PeripheralPins.h"
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
// determine the SPI to use

View File

@ -22,6 +22,11 @@
extern "C" {
#endif
typedef enum {
OSC32KCLK = 0,
RTC_CLKIN = 2
} RTCName;
typedef enum {
UART_0 = (int)UART0_BASE,
UART_1 = (int)UART1_BASE,
@ -52,7 +57,7 @@ typedef enum {
PWM_10 = (2 << TPM_SHIFT) | (1) // TPM2 CH1
} PWMName;
#define CHANNELS_A_SHIFT 5
#define CHANNELS_A_SHIFT 5
typedef enum {
ADC0_SE0 = 0,
ADC0_SE3 = 3,

View File

@ -0,0 +1,209 @@
/* 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 "PeripheralPins.h"
/************RTC***************/
const PinMap PinMap_RTC[] = {
{PTC1, RTC_CLKIN, 2},
};
/************ADC***************/
const PinMap PinMap_ADC[] = {
{PTE20, ADC0_SE0, 0},
{PTE22, ADC0_SE3, 0},
{PTE21, ADC0_SE4a, 0},
{PTE29, ADC0_SE4b, 0},
{PTE30, ADC0_SE23, 0},
{PTE23, ADC0_SE7a, 0},
{PTB0, ADC0_SE8, 0},
{PTB1, ADC0_SE9, 0},
{PTB2, ADC0_SE12, 0},
{PTB3, ADC0_SE13, 0},
{PTC0, ADC0_SE14, 0},
{PTC1, ADC0_SE15, 0},
{PTC2, ADC0_SE11, 0},
{PTD1, ADC0_SE5b, 0},
{PTD5, ADC0_SE6b, 0},
{PTD6, ADC0_SE7b, 0},
{NC, NC, 0}
};
/************DAC***************/
const PinMap PinMap_DAC[] = {
{PTE30, DAC_0, 0},
{NC , NC , 0}
};
/************I2C***************/
const PinMap PinMap_I2C_SDA[] = {
{PTE25, I2C_0, 5},
{PTC9, I2C_0, 2},
{PTE0, I2C_1, 6},
{PTB1, I2C_0, 2},
{PTB3, I2C_0, 2},
{PTC11, I2C_1, 2},
{PTC2, I2C_1, 2},
{PTA4, I2C_1, 2},
{NC , NC , 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PTE24, I2C_0, 5},
{PTC8, I2C_0, 2},
{PTE1, I2C_1, 6},
{PTB0, I2C_0, 2},
{PTB2, I2C_0, 2},
{PTC10, I2C_1, 2},
{PTC1, I2C_1, 2},
{NC , NC, 0}
};
/************UART***************/
const PinMap PinMap_UART_TX[] = {
{PTA2, UART_0, 2},
{PTA14, UART_0, 3},
{PTC4, UART_1, 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},
{NC , NC , 0}
};
const PinMap PinMap_UART_RX[] = {
{PTA1, UART_0, 2},
{PTA15, 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}
};
/************SPI***************/
const PinMap PinMap_SPI_SCLK[] = {
{PTA15, SPI_0, 2},
{PTB9, SPI_1, 2},
{PTB11, 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},
{PTC7, SPI_0, 5},
{PTD2, SPI_0, 2},
{PTD3, SPI_0, 5},
{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},
{PTC7, SPI_0, 2},
{PTD2, SPI_0, 5},
{PTD3, SPI_0, 2},
{PTD6, SPI_1, 5},
{PTD7, 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}
};
/************PWM***************/
const PinMap PinMap_PWM[] = {
// LEDs - only RED pin is PWM capable
{LED_RED, PWM_3, 3}, // PTE29, TPM0 CH2
// Arduino digital pinout
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
{D2, PWM_4 , 4}, // PTD3 , TPM0 CH3
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
{D9, PWM_3 , 4}, // PTD2 , TPM0 CH2
{D10, PWM_5 , 4}, // PTD4 , TPM0 CH4
//PWM on D11 not available
//PWM on D12 not available
{D13, PWM_2 , 4}, // PTD5 , TPM0 CH1,
{PTA0, PWM_6, 3},
{PTA3, PWM_1, 3},
{PTA6, PWM_4, 3},
{PTA7, PWM_5, 3},
{PTB0, PWM_7, 3},
{PTB1, PWM_8, 3},
{PTB2, PWM_9, 3},
{PTB3, PWM_10, 3},
{PTC1, PWM_1, 4},
{PTC2, PWM_2, 4},
{PTC3, PWM_3, 4},
{PTC4, PWM_4, 4},
{PTE20, PWM_7, 3},
{PTE21, PWM_8, 3},
{PTE22, PWM_9, 3},
{PTE23, PWM_10, 3},
{PTE24, PWM_1, 3},
{PTE25, PWM_2, 3},
{PTE26, PWM_6, 3},
{PTE29, PWM_3, 3},
{PTE30, PWM_4, 3},
{PTE31, PWM_5, 3},
{NC , NC , 0}
};

View File

@ -197,13 +197,13 @@ typedef enum {
// mbed original LED naming
LED1 = LED_GREEN,
LED2 = LED_RED,
LED3 = LED_GREEN,
LED3 = LED_GREEN,
LED4 = LED_RED,
//Push buttons
SW1 = PTC3,
SW3 = PTC12,
// USB Pins
USBTX = PTA2,
USBRX = PTA1,

View File

@ -19,28 +19,11 @@
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"
#include "PeripheralPins.h"
#define MAX_FADC 6000000
#define MAX_FADC 6000000
#define CHANNELS_A_SHIFT 5
static const PinMap PinMap_ADC[] = {
{PTE20, ADC0_SE0, 0},
{PTE22, ADC0_SE3, 0},
{PTE21, ADC0_SE4a, 0},
{PTE29, ADC0_SE4b, 0},
{PTE30, ADC0_SE23, 0},
{PTE23, ADC0_SE7a, 0},
{PTB0, ADC0_SE8, 0},
{PTB1, ADC0_SE9, 0},
{PTB2, ADC0_SE12, 0},
{PTB3, ADC0_SE13, 0},
{PTC0, ADC0_SE14, 0},
{PTC1, ADC0_SE15, 0},
{PTC2, ADC0_SE11, 0},
{PTD1, ADC0_SE5b, 0},
{PTD5, ADC0_SE6b, 0},
{PTD6, ADC0_SE7b, 0},
{NC, NC, 0}
};
void analogin_init(analogin_t *obj, PinName pin) {
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);

View File

@ -18,13 +18,10 @@
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#include "PeripheralPins.h"
#define RANGE_12BIT 0xFFF
static const PinMap PinMap_DAC[] = {
{PTE30, DAC_0, 0},
{NC , NC , 0}
};
void analogout_init(dac_t *obj, PinName pin) {
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);

View File

@ -20,6 +20,8 @@
extern "C" {
#endif
#include "PeripheralPins.h"
//Get the peripheral bus clock frequency
static inline uint32_t bus_frequency(void) {
return SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
@ -32,9 +34,11 @@ static uint32_t extosc_frequency(void) {
if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(2)) //MCG clock = external reference clock
return MCGClock;
uint32_t divider, multiplier;
#ifdef MCG_C5_PLLCLKEN0_MASK //PLL available
if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0)) { //PLL/FLL is selected
uint32_t divider, multiplier;
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected
#endif
if ((MCG->S & MCG_S_IREFST_MASK) == 0x0u) { //FLL uses external reference
divider = (uint8_t)(1u << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
if ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u)
@ -70,12 +74,14 @@ static uint32_t extosc_frequency(void) {
return MCGClock * divider / multiplier;
}
#ifdef MCG_C5_PLLCLKEN0_MASK
} else { //PLL is selected
divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));
multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
return MCGClock * divider / multiplier;
}
}
#endif
//In all other cases either there is no crystal or we cannot determine it
//For example when the FLL is running on the internal reference, and there is also an
@ -89,13 +95,17 @@ static uint32_t mcgpllfll_frequency(void) {
return 0;
uint32_t MCGClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
#ifdef MCG_C5_PLLCLKEN0_MASK
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected
SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is FLL output
#endif
return MCGClock;
#ifdef MCG_C5_PLLCLKEN0_MASK
} else { //PLL is selected
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is PLL output
return (MCGClock >> 1);
}
#endif
//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

View File

@ -19,29 +19,7 @@
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"
static const PinMap PinMap_I2C_SDA[] = {
{PTE25, I2C_0, 5},
{PTC9, I2C_0, 2},
{PTE0, I2C_1, 6},
{PTB1, I2C_0, 2},
{PTB3, I2C_0, 2},
{PTC11, I2C_1, 2},
{PTC2, I2C_1, 2},
{PTA4, I2C_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PTE24, I2C_0, 5},
{PTC8, I2C_0, 2},
{PTE1, I2C_1, 6},
{PTB0, I2C_0, 2},
{PTB2, I2C_0, 2},
{PTC10, I2C_1, 2},
{PTC1, I2C_1, 2},
{NC , NC, 0}
};
#include "PeripheralPins.h"
static const uint16_t ICR[0x40] = {
20, 22, 24, 26, 28,

View File

@ -25,6 +25,10 @@
extern "C" {
#endif
#ifdef TARGET_KL46Z
#define UARTLP_Type UART0_Type
#endif
struct gpio_irq_s {
uint32_t port;
uint32_t pin;

View File

@ -19,51 +19,7 @@
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"
static const PinMap PinMap_PWM[] = {
// LEDs
{LED_RED , PWM_9 , 3}, // PTB18, TPM2 CH0
{LED_GREEN, PWM_10, 3}, // PTB19, TPM2 CH1
{LED_BLUE , PWM_2 , 4}, // PTD1 , TPM0 CH1
// Arduino digital pinout
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
{D2, PWM_5 , 4}, // PTD4 , TPM0 CH4
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
{D9, PWM_6 , 4}, // PTD5 , TPM0 CH5
{D10, PWM_1 , 4}, // PTD0 , TPM0 CH0
{D11, PWM_3 , 4}, // PTD2 , TPM0 CH2
{D12, PWM_4 , 4}, // PTD3 , TPM0 CH3
{D13, PWM_2 , 4}, // PTD1 , TPM0 CH1,
{PTA0, PWM_6, 3},
{PTA3, PWM_1, 3},
{PTB0, PWM_7, 3},
{PTB1, PWM_8, 3},
{PTB2, PWM_9, 3},
{PTB3, PWM_10, 3},
{PTC1, PWM_1, 4},
{PTC2, PWM_2, 4},
{PTC3, PWM_3, 4},
{PTC4, PWM_4, 4},
{PTE20, PWM_7, 3},
{PTE21, PWM_8, 3},
{PTE22, PWM_9, 3},
{PTE23, PWM_10, 3},
{PTE24, PWM_1, 3},
{PTE25, PWM_2, 3},
{PTE29, PWM_3, 3},
{PTE30, PWM_4, 3},
{PTE31, PWM_5, 3},
{NC , NC , 0}
};
#include "PeripheralPins.h"
static float pwm_clock;

View File

@ -14,26 +14,17 @@
* limitations under the License.
*/
#include "rtc_api.h"
#include "PeripheralPins.h"
static void init(void) {
// enable PORTC clock
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
// enable RTC clock
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
/*
* configure PTC1 with alternate function 1: RTC_CLKIN
* As the KL46Z board does not have a 32kHz osc,
* we use an external clock generated by the
* interface chip
*/
PORTC->PCR[1] &= ~PORT_PCR_MUX_MASK;
PORTC->PCR[1] = PORT_PCR_MUX(1);
pinmap_pinout(PinMap_RTC[0].pin, PinMap_RTC); //Map RTC clk input (if not NC)
// select RTC_CLKIN as RTC clock source
// select RTC clock source
SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(2);
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(PinMap_RTC[0].peripheral);
}
void rtc_init(void) {
@ -41,6 +32,12 @@ void rtc_init(void) {
//Configure the TSR. default value: 1
RTC->TSR = 1;
if (PinMap_RTC[0].pin == NC) { //Use OSC32K
RTC->CR |= RTC_CR_OSCE_MASK;
//delay for OSCE stabilization
for(int i=0; i<0x1000; i++) __NOP();
}
// enable counter
RTC->SR |= RTC_SR_TCE_MASK;
@ -61,7 +58,7 @@ int rtc_isenabled(void) {
// call init() if the rtc is enabled
// if RTC not enabled return 0
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
if ((RTC->SR & RTC_SR_TCE_MASK) == 0)
return 0;

View File

@ -24,35 +24,32 @@
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"
#include "PeripheralPins.h"
//Devices either user UART0 or UARTLP
#ifndef UARTLP_BASES
#define UARTLP_C2_RE_MASK UART0_C2_RE_MASK
#define UARTLP_C2_TE_MASK UART0_C2_TE_MASK
#define UARTLP_BDH_SBNS_MASK UART0_BDH_SBNS_MASK
#define UARTLP_BDH_SBNS_SHIFT UART0_BDH_SBNS_SHIFT
#define UARTLP_S1_TDRE_MASK UART0_S1_TDRE_MASK
#define UARTLP_S1_OR_MASK UART0_S1_OR_MASK
#define UARTLP_C2_RIE_MASK UART0_C2_RIE_MASK
#define UARTLP_C2_TIE_MASK UART0_C2_TIE_MASK
#define UARTLP_C2_SBK_MASK UART0_C2_SBK_MASK
#define UARTLP_S1_RDRF_MASK UART0_S1_RDRF_MASK
#endif
#ifdef UART2
#define UART_NUM 3
#else
#define UART_NUM 1
#endif
/******************************************************************************
* INITIALIZATION
******************************************************************************/
static const PinMap PinMap_UART_TX[] = {
{PTC4, UART_1, 3},
{PTA2, UART_0, 2},
{PTD5, UART_2, 3},
{PTD3, UART_2, 3},
{PTD7, UART_0, 3},
{PTE20, UART_0, 4},
{PTE22, UART_2, 4},
{PTE0, UART_1, 3},
{NC , NC , 0}
};
static const PinMap PinMap_UART_RX[] = {
{PTC3, UART_1, 3},
{PTA1, UART_0, 2},
{PTD4, UART_2, 3},
{PTD2, UART_2, 3},
{PTD6, UART_0, 3},
{PTE23, UART_2, 4},
{PTE21, UART_0, 4},
{PTE1, UART_1, 3},
{NC , NC , 0}
};
#define UART_NUM 3
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler;
@ -75,17 +72,21 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
SIM->SOPT2 |= (1<<SIM_SOPT2_UART0SRC_SHIFT);
else
SIM->SOPT2 |= (2<<SIM_SOPT2_UART0SRC_SHIFT);
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
case UART_1: SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; break;
case UART_2: SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; break;
SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
#if UART_NUM > 1
case UART_1: SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; break;
case UART_2: SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; break;
#endif
}
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
obj->uart->C2 &= ~(UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
switch (uart) {
case UART_0: obj->index = 0; break;
#if UART_NUM > 1
case UART_1: obj->index = 1; break;
case UART_2: obj->index = 2; break;
#endif
}
// set default baud rate and format
@ -100,7 +101,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
pin_mode(tx, PullUp);
pin_mode(rx, PullUp);
obj->uart->C2 |= (UART_C2_RE_MASK | UART_C2_TE_MASK);
obj->uart->C2 |= (UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
if (uart == STDIO_UART) {
stdio_uart_inited = 1;
@ -118,10 +119,10 @@ void serial_free(serial_t *obj) {
void serial_baud(serial_t *obj, int baudrate) {
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
uint8_t c2_state = (obj->uart->C2 & (UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
obj->uart->C2 &= ~(UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
uint32_t PCLK;
if (obj->uart == UART0) {
@ -149,19 +150,17 @@ void serial_baud(serial_t *obj, int baudrate) {
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
uint8_t m10 = 0;
// save C2 state
uint8_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
uint8_t c2_state = (obj->uart->C2 & (UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK));
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
obj->uart->C2 &= ~(UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK);
// 8 data bits = 0 ... 9 data bits = 1
if ((data_bits < 8) || (data_bits > 9)) {
error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
// TODO: Support other number of data bits (also in the write method!)
if ((data_bits < 8) || (data_bits > 8)) {
error("Invalid number of bits (%d) in serial format, should be 8\r\n", data_bits);
}
data_bits -= 8;
uint8_t parity_enable, parity_select;
switch (parity) {
@ -178,31 +177,14 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
error("Invalid stop bits specified\r\n");
}
stop_bits -= 1;
// 9 data bits + parity
if (data_bits == 2) {
// only uart0 supports 10 bit communication
if (obj->index != 0) {
error("Invalid number of bits (9) to be used with parity\r\n");
}
data_bits = 0;
m10 = 1;
}
// data bits, parity and parity mode
obj->uart->C1 = ((data_bits << 4)
| (parity_enable << 1)
obj->uart->C1 = ((parity_enable << 1)
| (parity_select << 0));
// enable 10bit mode if needed
if (obj->index == 0) {
obj->uart->C4 &= ~UARTLP_C4_M10_MASK;
obj->uart->C4 |= (m10 << UARTLP_C4_M10_SHIFT);
}
// stop bits
obj->uart->BDH &= ~UART_BDH_SBNS_MASK;
obj->uart->BDH |= (stop_bits << UART_BDH_SBNS_SHIFT);
obj->uart->BDH &= ~UARTLP_BDH_SBNS_MASK;
obj->uart->BDH |= (stop_bits << UARTLP_BDH_SBNS_SHIFT);
// restore C2 state
obj->uart->C2 |= c2_state;
@ -213,21 +195,23 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
******************************************************************************/
static inline void uart_irq(uint8_t status, uint32_t index) {
if (serial_irq_ids[index] != 0) {
if (status & UART_S1_TDRE_MASK)
if (status & UARTLP_S1_TDRE_MASK)
irq_handler(serial_irq_ids[index], TxIrq);
if (status & UART_S1_RDRF_MASK)
if (status & UARTLP_S1_RDRF_MASK)
irq_handler(serial_irq_ids[index], RxIrq);
}
}
void uart0_irq() {
uart_irq(UART0->S1, 0);
if (UART0->S1 & UART_S1_OR_MASK)
UART0->S1 |= UART_S1_OR_MASK;
if (UART0->S1 & UARTLP_S1_OR_MASK)
UART0->S1 |= UARTLP_S1_OR_MASK;
}
#if UART_NUM > 1
void uart1_irq() {uart_irq(UART1->S1, 1);}
void uart2_irq() {uart_irq(UART2->S1, 2);}
#endif
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler;
@ -239,14 +223,16 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
uint32_t vector = 0;
switch ((int)obj->uart) {
case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
#if UART_NUM > 1
case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
#endif
}
if (enable) {
switch (irq) {
case RxIrq: obj->uart->C2 |= (UART_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 |= (UART_C2_TIE_MASK); break;
case RxIrq: obj->uart->C2 |= (UARTLP_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 |= (UARTLP_C2_TIE_MASK); break;
}
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
@ -255,12 +241,12 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) {
case RxIrq: obj->uart->C2 &= ~(UART_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 &= ~(UART_C2_TIE_MASK); break;
case RxIrq: obj->uart->C2 &= ~(UARTLP_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 &= ~(UARTLP_C2_TIE_MASK); break;
}
switch (other_irq) {
case RxIrq: all_disabled = (obj->uart->C2 & (UART_C2_RIE_MASK)) == 0; break;
case TxIrq: all_disabled = (obj->uart->C2 & (UART_C2_TIE_MASK)) == 0; break;
case RxIrq: all_disabled = (obj->uart->C2 & (UARTLP_C2_RIE_MASK)) == 0; break;
case TxIrq: all_disabled = (obj->uart->C2 & (UARTLP_C2_TIE_MASK)) == 0; break;
}
if (all_disabled)
NVIC_DisableIRQ(irq_n);
@ -282,18 +268,18 @@ void serial_putc(serial_t *obj, int c) {
int serial_readable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART_S1_OR_MASK) {
obj->uart->S1 |= UART_S1_OR_MASK;
if (obj->uart->S1 & UARTLP_S1_OR_MASK) {
obj->uart->S1 |= UARTLP_S1_OR_MASK;
}
return (obj->uart->S1 & UART_S1_RDRF_MASK);
return (obj->uart->S1 & UARTLP_S1_RDRF_MASK);
}
int serial_writable(serial_t *obj) {
// check overrun
if (obj->uart->S1 & UART_S1_OR_MASK) {
obj->uart->S1 |= UART_S1_OR_MASK;
if (obj->uart->S1 & UARTLP_S1_OR_MASK) {
obj->uart->S1 |= UARTLP_S1_OR_MASK;
}
return (obj->uart->S1 & UART_S1_TDRE_MASK);
return (obj->uart->S1 & UARTLP_S1_TDRE_MASK);
}
void serial_clear(serial_t *obj) {
@ -304,10 +290,10 @@ void serial_pinout_tx(PinName tx) {
}
void serial_break_set(serial_t *obj) {
obj->uart->C2 |= UART_C2_SBK_MASK;
obj->uart->C2 |= UARTLP_C2_SBK_MASK;
}
void serial_break_clear(serial_t *obj) {
obj->uart->C2 &= ~UART_C2_SBK_MASK;
obj->uart->C2 &= ~UARTLP_C2_SBK_MASK;
}

View File

@ -15,6 +15,7 @@
*/
#include "sleep_api.h"
#include "cmsis.h"
#include "PeripheralPins.h"
//Normal wait mode
void sleep(void)
@ -43,8 +44,10 @@ void deepsleep(void)
//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) {
#ifdef MCG_C5_PLLCLKEN0_MASK //PLL available
if (MCG->C6 & (1<<MCG_C6_PLLS_SHIFT) != 0) /* If PLL */
while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U); /* Wait until locked */
#endif
MCG->C1 &= ~MCG_C1_CLKS_MASK;
}

Some files were not shown because too many files have changed in this diff Show More