mirror of https://github.com/ARMmbed/mbed-os.git
SPI, RTC, Serial changes
- SPI - implementation - RTC - there's 32.768kHz crystal, use that as a source - Serial - 10bit transferpull/135/head
parent
988894e837
commit
366221524a
|
@ -52,7 +52,7 @@ void analogin_init(analogin_t *obj, PinName pin) {
|
|||
| ADC_CFG1_MODE(3) // (16)bits Resolution
|
||||
| ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2
|
||||
|
||||
ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels
|
||||
ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // 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
|
||||
|
|
|
@ -22,7 +22,8 @@ uint32_t gpio_set(PinName pin) {
|
|||
}
|
||||
|
||||
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
|
||||
if(pin == NC) return;
|
||||
if(pin == NC)
|
||||
return;
|
||||
|
||||
obj->pin = pin;
|
||||
obj->mask = gpio_set(pin);
|
||||
|
@ -37,8 +38,12 @@ void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
|
|||
|
||||
gpio_dir(obj, direction);
|
||||
switch (direction) {
|
||||
case PIN_OUTPUT: pin_mode(pin, PullNone); break;
|
||||
case PIN_INPUT : pin_mode(pin, PullUp); break;
|
||||
case PIN_OUTPUT:
|
||||
pin_mode(pin, PullNone);
|
||||
break;
|
||||
case PIN_INPUT :
|
||||
pin_mode(pin, PullUp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +53,11 @@ void gpio_mode(gpio_t *obj, PinMode 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;
|
||||
case PIN_INPUT :
|
||||
*obj->reg_dir &= ~obj->mask;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
*obj->reg_dir |= obj->mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ static void handle_interrupt_in(PORT_Type *port, int ch_base) {
|
|||
|
||||
case IRQ_EITHER_EDGE:
|
||||
gpio += (port_num * 0x40);
|
||||
//gpio = (port == PORTA) ? (PTA) : (PTD);
|
||||
event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL);
|
||||
break;
|
||||
}
|
||||
|
@ -82,23 +81,32 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
|
|||
IRQn_Type irq_n;
|
||||
switch (obj->port) {
|
||||
case PortA:
|
||||
ch_base = 0; irq_n = PORTA_IRQn; vector = (uint32_t)gpio_irqA;
|
||||
ch_base = 0;
|
||||
irq_n = PORTA_IRQn;
|
||||
vector = (uint32_t)gpio_irqA;
|
||||
break;
|
||||
case PortB:
|
||||
ch_base = 0; irq_n = PORTB_IRQn; vector = (uint32_t)gpio_irqB;
|
||||
ch_base = 32;
|
||||
irq_n = PORTB_IRQn;
|
||||
vector = (uint32_t)gpio_irqB;
|
||||
break;
|
||||
case PortC:
|
||||
ch_base = 0; irq_n = PORTC_IRQn; vector = (uint32_t)gpio_irqC;
|
||||
ch_base = 64;
|
||||
irq_n = PORTC_IRQn;
|
||||
vector = (uint32_t)gpio_irqC;
|
||||
break;
|
||||
case PortD:
|
||||
ch_base = 32; irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD;
|
||||
ch_base = 96;
|
||||
irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD;
|
||||
break;
|
||||
case PortE:
|
||||
ch_base = 0; irq_n = PORTE_IRQn; vector = (uint32_t)gpio_irqE;
|
||||
ch_base = 128;
|
||||
irq_n = PORTE_IRQn;
|
||||
vector = (uint32_t)gpio_irqE;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("gpio_irq only supported on port A and D\n");
|
||||
error("gpio_irq only supported on port A-E.\n");
|
||||
break;
|
||||
}
|
||||
NVIC_SetVector(irq_n, vector);
|
||||
|
|
|
@ -22,23 +22,17 @@ static void init(void) {
|
|||
// 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
|
||||
// OSC32 as source
|
||||
SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;
|
||||
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(2);
|
||||
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(0);
|
||||
}
|
||||
|
||||
void rtc_init(void) {
|
||||
init();
|
||||
|
||||
// Enable the oscillator
|
||||
RTC_CR |= RTC_CR_OSCE_MASK;
|
||||
|
||||
//Configure the TSR. default value: 1
|
||||
RTC->TSR = 1;
|
||||
|
||||
|
|
|
@ -24,20 +24,18 @@
|
|||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
/******************************************************************************
|
||||
* INITIALIZATION
|
||||
******************************************************************************/
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{PTB17, UART_0, 3},
|
||||
{PTB17, UART_0, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
{PTB16, UART_0, 3},
|
||||
{PTB16, UART_0, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
#define UART_NUM 3
|
||||
|
||||
static uint32_t serial_irq_ids[UART_NUM] = {0};
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
|
@ -49,9 +47,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
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) {
|
||||
if ((int)uart == NC)
|
||||
error("Serial pinout mapping failed");
|
||||
}
|
||||
|
||||
obj->uart = (UART_Type *)uart;
|
||||
// enable clk
|
||||
|
@ -63,7 +60,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
}
|
||||
// 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;
|
||||
|
@ -94,27 +91,13 @@ 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));
|
||||
|
||||
uint32_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;
|
||||
|
||||
|
@ -129,27 +112,26 @@ void serial_baud(serial_t *obj, int 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));
|
||||
|
||||
uint32_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)) {
|
||||
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;
|
||||
uint32_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;
|
||||
|
@ -160,36 +142,36 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
}
|
||||
|
||||
// 1 stop bits = 0, 2 stop bits = 1
|
||||
if ((stop_bits != 1) && (stop_bits != 2)) {
|
||||
if ((stop_bits != 1) && (stop_bits != 2))
|
||||
error("Invalid stop bits specified\r\n");
|
||||
}
|
||||
stop_bits -= 1;
|
||||
|
||||
|
||||
uint32_t m10 = 0;
|
||||
|
||||
// 9 data bits + parity
|
||||
if (data_bits == 2) {
|
||||
// only uart0 supports 10 bit communication
|
||||
if (obj->index != 0) {
|
||||
if (obj->index != 0)
|
||||
error("Invalid number of bits (9) to be used with parity\r\n");
|
||||
}
|
||||
data_bits = 0;
|
||||
//m10 = 1;
|
||||
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);
|
||||
// }
|
||||
|
||||
|
||||
//enable 10bit mode if needed
|
||||
if (obj->index == 0) {
|
||||
obj->uart->C4 &= ~UART_C4_M10_MASK;
|
||||
obj->uart->C4 |= (m10 << UART_C4_M10_SHIFT);
|
||||
}
|
||||
|
||||
// stop bits
|
||||
obj->uart->BDH &= ~UART_BDH_SBR_MASK;
|
||||
obj->uart->BDH |= (stop_bits << UART_BDH_SBR_SHIFT);
|
||||
|
||||
|
||||
// restore C2 state
|
||||
obj->uart->C2 |= c2_state;
|
||||
}
|
||||
|
@ -220,15 +202,28 @@ 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_RX_TX_IRQn; vector = (uint32_t)&uart0_irq; break;
|
||||
case UART_1: irq_n=UART1_RX_TX_IRQn; vector = (uint32_t)&uart1_irq; break;
|
||||
case UART_2: irq_n=UART2_RX_TX_IRQn; vector = (uint32_t)&uart2_irq; break;
|
||||
case UART_0:
|
||||
irq_n=UART0_RX_TX_IRQn;
|
||||
vector = (uint32_t)&uart0_irq;
|
||||
break;
|
||||
case UART_1:
|
||||
irq_n=UART1_RX_TX_IRQn;
|
||||
vector = (uint32_t)&uart1_irq;
|
||||
break;
|
||||
case UART_2:
|
||||
irq_n=UART2_RX_TX_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;
|
||||
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);
|
||||
|
@ -237,21 +232,26 @@ 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 &= ~(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;
|
||||
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;
|
||||
|
@ -263,7 +263,7 @@ void serial_putc(serial_t *obj, int c) {
|
|||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
|
||||
|
||||
return (obj->uart->S1 & UART_S1_RDRF_MASK);
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ void serial_pinout_tx(PinName tx) {
|
|||
}
|
||||
|
||||
void serial_break_set(serial_t *obj) {
|
||||
obj->uart->C2 |= UART_C2_SBK_MASK;
|
||||
obj->uart->C2 |= UART_C2_SBK_MASK;
|
||||
}
|
||||
|
||||
void serial_break_clear(serial_t *obj) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
* Copyright (c) 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.
|
||||
|
@ -24,25 +24,25 @@
|
|||
static const PinMap PinMap_SPI_SCLK[] = {
|
||||
{PTC5, SPI_0, 2},
|
||||
{PTD1, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MOSI[] = {
|
||||
{PTD2, SPI_0, 2},
|
||||
{PTC6, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MISO[] = {
|
||||
{PTD3, SPI_0, 2},
|
||||
{PTC7, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_SSEL[] = {
|
||||
{PTD0, SPI_0, 2},
|
||||
{PTC4, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
|
||||
|
@ -59,10 +59,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
error("SPI pinout mapping failed");
|
||||
}
|
||||
|
||||
// enable power and clocking
|
||||
switch ((int)obj->spi) {
|
||||
case SPI_0: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 22; break;
|
||||
}
|
||||
SIM->SCGC5 |= (1 << 11) | (1 << 12); // PortC & D
|
||||
SIM->SCGC6 |= 1 << 12; // spi clocks
|
||||
|
||||
// halted state
|
||||
obj->spi->MCR = SPI_MCR_HALT_MASK;
|
||||
|
||||
// set default format and frequency
|
||||
if (ssel == NC) {
|
||||
|
@ -72,8 +73,10 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
}
|
||||
spi_frequency(obj, 1000000);
|
||||
|
||||
// not halt in the debug mode
|
||||
obj->spi->SR |= SPI_SR_EOQF_MASK;
|
||||
// enable SPI
|
||||
obj->spi->MCR |= SPI_MCR_CONT_SCKE_MASK;
|
||||
obj->spi->MCR &= (~SPI_MCR_HALT_MASK);
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
|
@ -88,37 +91,38 @@ void spi_free(spi_t *obj) {
|
|||
// [TODO]
|
||||
}
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
if (bits != 8) {
|
||||
error("Only 8bits SPI supported");
|
||||
if ((bits != 8) && (bits != 16)) {
|
||||
error("Only 8/16 bits SPI supported");
|
||||
}
|
||||
|
||||
if ((mode < 0) || (mode > 3)) {
|
||||
error("SPI mode unsupported");
|
||||
}
|
||||
|
||||
uint8_t polarity = (mode & 0x2) ? 1 : 0;
|
||||
uint8_t phase = (mode & 0x1) ? 1 : 0;
|
||||
uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
|
||||
uint32_t polarity = (mode & 0x2) ? 1 : 0;
|
||||
uint32_t phase = (mode & 0x1) ? 1 : 0;
|
||||
|
||||
// clear MSTR, CPOL and CPHA bits
|
||||
// set master/slave
|
||||
obj->spi->MCR &= ~SPI_MCR_MSTR_MASK;
|
||||
obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT);
|
||||
|
||||
// write new value
|
||||
obj->spi->MCR |= c1_data;
|
||||
// CTAR0 is used
|
||||
obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
|
||||
obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT);
|
||||
}
|
||||
|
||||
void spi_frequency(spi_t *obj, int hz) {
|
||||
uint32_t error = 0;
|
||||
uint32_t p_error = 0xffffffff;
|
||||
uint32_t ref = 0;
|
||||
uint8_t spr = 0;
|
||||
uint8_t ref_spr = 0;
|
||||
uint8_t ref_prescaler = 0;
|
||||
uint32_t spr = 0;
|
||||
uint32_t ref_spr = 0;
|
||||
uint32_t ref_prescaler = 0;
|
||||
|
||||
// bus clk
|
||||
uint32_t PCLK = 48000000u;
|
||||
uint8_t prescaler = 1;
|
||||
uint8_t divisor = 2;
|
||||
uint32_t prescaler = 1;
|
||||
uint32_t divisor = 2;
|
||||
|
||||
for (prescaler = 1; prescaler <= 8; prescaler++) {
|
||||
divisor = 2;
|
||||
|
@ -140,32 +144,31 @@ void spi_frequency(spi_t *obj, int hz) {
|
|||
}
|
||||
|
||||
static inline int spi_writeable(spi_t * obj) {
|
||||
return 0;//(obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
|
||||
return (obj->spi->SR & SPI_SR_TCF_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline int spi_readable(spi_t * obj) {
|
||||
return 0;//(obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
|
||||
return (obj->spi->SR & SPI_SR_TFFF_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
int spi_master_write(spi_t *obj, int value) {
|
||||
// wait tx buffer empty
|
||||
// while(!spi_writeable(obj));
|
||||
// obj->spi->D = (value & 0xff);
|
||||
while(!spi_writeable(obj));
|
||||
obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff);
|
||||
|
||||
// // wait rx buffer full
|
||||
// while (!spi_readable(obj));
|
||||
return 0;//obj->spi->D & 0xff;
|
||||
// wait rx buffer full
|
||||
while (!spi_readable(obj));
|
||||
return obj->spi->POPR;
|
||||
}
|
||||
|
||||
int spi_slave_receive(spi_t *obj) {
|
||||
return 0;//spi_readable(obj);
|
||||
return spi_readable(obj);
|
||||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
return 0;//obj->spi->D;
|
||||
return obj->spi->POPR;
|
||||
}
|
||||
|
||||
void spi_slave_write(spi_t *obj, int value) {
|
||||
// while (!spi_writeable(obj));
|
||||
// obj->spi->D = value;
|
||||
while (!spi_writeable(obj));
|
||||
}
|
||||
|
|
|
@ -23,9 +23,10 @@ static void lptmr_init(void);
|
|||
static int us_ticker_inited = 0;
|
||||
|
||||
void us_ticker_init(void) {
|
||||
if (us_ticker_inited) return;
|
||||
if (us_ticker_inited)
|
||||
return;
|
||||
us_ticker_inited = 1;
|
||||
|
||||
|
||||
pit_init();
|
||||
lptmr_init();
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ uint32_t us_ticker_read() {
|
|||
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
|
@ -72,14 +73,14 @@ static void lptmr_isr(void);
|
|||
static void lptmr_init(void) {
|
||||
/* Clock the timer */
|
||||
SIM->SCGC5 |= SIM_SCGC5_LPTIMER_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
|
||||
|
@ -99,13 +100,13 @@ 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;
|
||||
}
|
||||
|
@ -113,16 +114,16 @@ static void lptmr_set(unsigned short count) {
|
|||
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
|
||||
|
@ -138,7 +139,7 @@ void us_ticker_set_interrupt(unsigned int timestamp) {
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue