[RZ/A1H] commit for HAL changes

- adds GPIO driver
- adds I2C driver
- adds SPI driver
- adds PWM driver
- adds serial driver (irq not supported)
- adds ticker driver
- add analogin driver
pull/594/head
Takayuki Kurosawa 2014-10-24 11:05:17 +09:00
parent 193bdaa8c9
commit 9ddce12aa6
17 changed files with 1990 additions and 0 deletions

View File

@ -0,0 +1,128 @@
/* 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_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
UART0,
UART1,
UART2,
UART3,
} UARTName;
// PWMType & 1 == 1 then have to use PWDTR[12] == 1
typedef enum {
PWM1A = 0,
PWM1B,
PWM1C,
PWM1D,
PWM1E,
PWM1F,
PWM1G,
PWM1H,
PWM2A = 0x10,
PWM2B,
PWM2C,
PWM2D,
PWM2E,
PWM2F,
PWM2G,
PWM2H,
} PWMType;
#define PTM_SHIFT 8
typedef enum {
PWM0_PIN = (1 << PTM_SHIFT) | PWM2E, // LED_R (through MTU2) TIOC4A [T.B.D]
PWM1_PIN = (0 << PTM_SHIFT) | PWM2F, // LED_G
PWM2_PIN = (0 << PTM_SHIFT) | PWM2G, // LED_B
PWM3_PIN = (0 << PTM_SHIFT) | PWM2H, // LED_USER (not explicitly supported)
PWM4_PIN = (0 << PTM_SHIFT) | PWM1G, // D9
PWM5_PIN = (0 << PTM_SHIFT) | PWM1H, // D8 not explicitly supported
PWM6_PIN = (0 << PTM_SHIFT) | PWM1F, // D7 not explicitly supported
PWM7_PIN = (0 << PTM_SHIFT) | PWM1D, // D6
} PWMName;
typedef enum {
AN0= 0,
AN1= 1,
AN2= 2,
AN3= 3,
AN4= 4,
AN5= 5,
AN6= 6,
AN7= 7,
} ADCName;
typedef enum {
SPI_0 = 0,
SPI_1,
} SPIName;
typedef enum {
I2C_0 = 0,
I2C_1,
I2C_2,
I2C_3
} I2CName;
#define STDIO_UART_TX USBTX
#define STDIO_UART_RX USBRX
#define STDIO_UART P_SCIF2
// Default peripherals
#define MBED_SPI0 p5, p6, p7, p8
#define MBED_SPI1 p11, p12, p13, p14
#define MBED_UART0 p9, p10
#define MBED_UART1 p13, p14
#define MBED_UART2 p28, p27
#define MBED_UARTUSB USBTX, USBRX
#define MBED_I2C0 p28, p27
#define MBED_I2C1 p9, p10
#define MBED_CAN0 p30, p29
#define MBED_ANALOGOUT0 p18
#define MBED_ANALOGIN0 p15
#define MBED_ANALOGIN1 p16
#define MBED_ANALOGIN2 p17
#define MBED_ANALOGIN3 p18
#define MBED_ANALOGIN4 p19
#define MBED_ANALOGIN5 p20
#define MBED_PWMOUT0 p26
#define MBED_PWMOUT1 p25
#define MBED_PWMOUT2 p24
#define MBED_PWMOUT3 p23
#define MBED_PWMOUT4 p22
#define MBED_PWMOUT5 p21
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,119 @@
/* 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_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
#define PORT_SHIFT 4
typedef enum {
P0_0 = 0,
P0_1, P0_2, P0_3, P0_4, P0_5,_P0_6,_P0_7,_P0_8,_P0_9,_P0_10,_P0_11,_P0_12,_P0_13,_P0_14,_P0_15,
P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15,
P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15,
P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15,
P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15,
P5_0, P5_1, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, P5_8, P5_9, P5_10, P5_11, P5_12, P5_13, P5_14, P5_15,
P6_0, P6_1, P6_2, P6_3, P6_4, P6_5, P6_6, P6_7, P6_8, P6_9, P6_10, P6_11, P6_12, P6_13, P6_14, P6_15,
P7_0, P7_1, P7_2, P7_3, P7_4, P7_5, P7_6, P7_7, P7_8, P7_9, P7_10, P7_11, P7_12, P7_13, P7_14, P7_15,
P8_0, P8_1, P8_2, P8_3, P8_4, P8_5, P8_6, P8_7, P8_8, P8_9, P8_10, P8_11, P8_12, P8_13, P8_14, P8_15,
P9_0, P9_1, P9_2, P9_3, P9_4, P9_5, P9_6, P9_7, P9_8, P9_9, P9_10, P9_11, P9_12, P9_13, P9_14, P9_15,
P10_0,P10_1,P10_2,P10_3,P10_4,P10_5,P10_6,P10_7,P10_8,P10_9,P10_10,P10_11,P10_12,P10_13,P10_14,P10_15,
P11_0,P11_1,P11_2,P11_3,P11_4,P11_5,P11_6,P11_7,P11_8,P11_9,P11_10,P11_11,P11_12,P11_13,P11_14,P11_15,
// mbed DIP Pin Names
p10 = P0_1,
p21 = P2_5,
p22 = P2_4,
p23 = P2_3,
p24 = P2_2,
p25 = P2_1,
p26 = P2_0,
p29 = P0_5,
p30 = P0_4,
// Other mbed Pin Names
LED1 = P4_4,
LED2 = P4_5,
LED3 = P4_6,
LED4 = P4_7,
LED_RED = LED1,
LED_GREEN= LED2,
LED_BLUE = LED3,
LED_USER = LED4,
USBTX = P6_3,
USBRX = P6_2,
// Arduiono Pin Names
D0 = P2_15,
D1 = P2_14,
D2 = P11_15,
D3 = P11_14,
D4 = P11_13,
D5 = P11_12,
D6 = P8_11,
D7 = P8_13,
D8 = P8_15,
D9 = P8_14,
D10 = P10_13,
D11 = P10_14,
D12 = P10_15,
D13 = P10_12,
D14 = P1_3,
D15 = P1_2,
A0 = P1_8,
A1 = P1_9,
A2 = P1_10,
A3 = P1_11,
A4 = P1_13,
A5 = P1_15,
I2C_SCL = D15,
I2C_SDA = D14,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {
PullUp = 0,
PullDown = 3,
PullNone = 2,
OpenDrain = 4,
PullDefault = PullDown
} PinMode;
#define PINGROUP(pin) (((pin)>>PORT_SHIFT)&0x0f)
#define PINNO(pin) ((pin)&0x0f)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,34 @@
/* 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 {
Port0 = 0,
Port1 = 1,
Port2 = 2,
Port3 = 3,
Port4 = 4
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,6 @@
#ifndef RESERVED_PINS_H
#define RESERVED_PINS_H
#define TARGET_RESERVED_PINS {}
#endif

View File

@ -0,0 +1,117 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "adc_iodefine.h"
#include "cpg_iodefine.h"
#define ANALOGIN_MEDIAN_FILTER 1
#define ADC_12BIT_RANGE 0xFFF
static const PinMap PinMap_ADC[] = {
{P1_8, AN0, 1},
{P1_9, AN1, 1},
{P1_10, AN2, 1},
{P1_11, AN3, 1},
{P1_13, AN5, 1},
{P1_15, AN7, 1},
{NC, NC, 0}
};
static volatile uint16_t *ADCDR[] = {
&ADCADDRA,
&ADCADDRB,
&ADCADDRC,
&ADCADDRD,
&ADCADDRE,
&ADCADDRF,
&ADCADDRG,
&ADCADDRH,
};
#define ADC_RANGE ADC_12BIT_RANGE
void analogin_init(analogin_t *obj, PinName pin) {
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
CPGSTBCR3 &= ~(1 << 1);
CPGSTBCR6 &= ~(1 << 7);
// 000_0 000_1 11_00 0_xxx
// 15: ADFlag 14: IntEn 13: start, [12:9] Triger..0
// [8:6] CLK 100 :: 12-bit 1054tclk
// [5:3] scanmode 000 :: single mode
// [2:0] channel select
ADCADCSR = 0x0100 | (obj->adc&0xf);
pinmap_pinout(pin, PinMap_ADC);
}
static inline uint32_t adc_read(analogin_t *obj) {
// Select the appropriate channel and start conversion
ADCADCSR |= (1 << 13 | (obj->adc&0xf));
// Repeatedly get the sample data until DONE bit
#define nothing
while ((ADCADCSR & (1 << 15)) == 0 || (ADCADCSR & (1<<13)) != 0) nothing;
// clear flag
ADCADCSR &= ~(1 << 15);
return ((*(ADCDR[obj->adc]))>>4) & ADC_RANGE; // 12 bit
}
static inline void order(uint32_t *a, uint32_t *b) {
if (*a > *b) {
uint32_t t = *a;
*a = *b;
*b = t;
}
}
static inline uint32_t adc_read_u32(analogin_t *obj) {
uint32_t value;
#if ANALOGIN_MEDIAN_FILTER
uint32_t v1 = adc_read(obj);
uint32_t v2 = adc_read(obj);
uint32_t v3 = adc_read(obj);
order(&v1, &v2);
order(&v2, &v3);
order(&v1, &v2);
value = v2;
#else
value = adc_read(obj);
#endif
return value;
}
uint16_t analogin_read_u16(analogin_t *obj) {
uint32_t value = adc_read_u32(obj);
return value;
//(value << 4) | ((value >> 8) & 0x000F); // 12 bit
}
float analogin_read(analogin_t *obj) {
uint32_t value = adc_read_u32(obj);
return (float)value * (1.0f / (float)ADC_RANGE);
}

View File

@ -0,0 +1,60 @@
/* 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_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_PORTIN 1
#define DEVICE_PORTOUT 1
#define DEVICE_PORTINOUT 1
#define DEVICE_INTERRUPTIN 1
#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0
#define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1
#define DEVICE_SPISLAVE 1
#define DEVICE_CAN 0
#define DEVICE_RTC 0
#define DEVICE_ETHERNET 0
#define DEVICE_PWMOUT 1
#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_ID_LENGTH 32
#define DEVICE_MAC_OFFSET 20
#define DEVICE_SLEEP 0
#define DEVICE_DEBUG_AWARENESS 0
#define DEVICE_STDIO_MESSAGES 0
#define DEVICE_ERROR_PATTERN 0
#include "objects.h"
#endif

View File

@ -0,0 +1,22 @@
#ifndef __GPIO_ADDRDEFINE__
#define __GPIO_ADDRDEFINE__
#define GPIO_BASE ((long)0xFCFE3000uL) /* GPIO */
#define PORT(n) (volatile unsigned short *)(GPIO_BASE + 0x000 + ((n)*4))
#define PSR(n) (volatile unsigned long *)(GPIO_BASE + 0x100 + ((n)*4))
#define PPR(n) (volatile unsigned short *)(GPIO_BASE + 0x200 + ((n)*4))
#define PM(n) (volatile unsigned short *)(GPIO_BASE + 0x300 + ((n)*4))
#define PMC(n) (volatile unsigned short *)(GPIO_BASE + 0x400 + ((n)*4))
#define PFC(n) (volatile unsigned short *)(GPIO_BASE + 0x500 + ((n)*4))
#define PFCE(n) (volatile unsigned short *)(GPIO_BASE + 0x600 + ((n)*4))
#define PNOT(n) (volatile unsigned short *)(GPIO_BASE + 0x700 + ((n)*4))
#define PMSR(n) (volatile unsigned long *)(GPIO_BASE + 0x800 + ((n)*4))
#define PMCSR(n) (volatile unsigned long *)(GPIO_BASE + 0x900 + ((n)*4))
#define PFCAE(n) (volatile unsigned short *)(GPIO_BASE + 0xa00 + ((n)*4))
#define PIBC(n) (volatile unsigned short *)(GPIO_BASE + 0x4000 +((n)*4))
#define PBDC(n) (volatile unsigned short *)(GPIO_BASE + 0x4100 +((n)*4))
#define PIPC(n) (volatile unsigned short *)(GPIO_BASE + 0x4200 +((n)*4))
#endif/*__GPIO_ADDRDEFINE__*/

View File

@ -0,0 +1,53 @@
/* 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"
#include "gpio_addrdefine.h"
uint32_t gpio_set(PinName pin) {
pin_function(pin, 0);
return (1 << PINNO(pin));
}
void gpio_init(gpio_t *obj, PinName pin) {
int group ;
if(pin == NC) return;
obj->pin = pin;
obj->mask = gpio_set(pin);
group = PINGROUP(pin);
if (group > 11) return;
obj->reg_set = (volatile uint32_t *)PORT(group);
obj->reg_in = (volatile uint32_t *) PPR(group);
obj->reg_dir = (volatile uint32_t *) PM(group);
obj->reg_buf = (volatile uint32_t *)PIBC(group);
}
void gpio_mode(gpio_t *obj, PinMode mode) {
// pullup, pulldown, open...etc
}
void gpio_dir(gpio_t *obj, PinDirection direction) {
switch (direction) {
case PIN_INPUT : *obj->reg_dir |= obj->mask;
*obj->reg_buf |= obj->mask; break;
case PIN_OUTPUT: *obj->reg_dir &= ~obj->mask;
*obj->reg_buf &= ~obj->mask; break;
}
}

View File

@ -0,0 +1,48 @@
/* 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;
__I uint32_t *reg_in;
__IO uint32_t *reg_buf;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value) {
if (value)
*obj->reg_set |= obj->mask;
else
*obj->reg_set &= ~obj->mask;
}
static inline int gpio_read(gpio_t *obj) {
return ((*obj->reg_in & obj->mask) ? 1 : 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,357 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "riic_iodefine.h"
volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
#define REG(N) \
RIIC[obj->i2c]->RIICn##N
#define NACKF (1 << 4)
static const PinMap PinMap_I2C_SDA[] = {
{P1_1 , I2C_0, 1},
{P1_3 , I2C_1, 1},
{P1_7 , I2C_3, 1},
{NC , NC , 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{P1_0 , I2C_0, 1},
{P1_2 , I2C_1, 1},
{P1_6 , I2C_3, 1},
{NC , NC, 0}
};
// Clear the Transmit data Empty TDRE
static inline int i2c_addressed(i2c_t *obj) {
volatile int sar0 = (REG(SR1.UINT8[0])&1),
trs = (REG(CR2.UINT8[0])&0x20) >> 5;
return sar0 | (trs <<1);
}
static inline int i2c_status(i2c_t *obj) {
return REG(SR2.UINT8[0]);
}
static inline void i2c_clear_TDRE(i2c_t *obj) {
REG(SR2.UINT32) &= ~(1 << 7);
}
static inline void i2c_wait_RDRF(i2c_t *obj) {
while (!(i2c_status(obj) & (1 << 5))) ;
}
// Wait until the Trans Data Empty (TDRE) is set
static int i2c_wait_TDRE(i2c_t *obj) {
int timeout = 0;
while (!(i2c_status(obj) & (1 << 7))) {
if (timeout > 100000) return -1;
}
return 0;
}
static inline void i2c_power_enable(i2c_t *obj) {
volatile uint8_t dummy;
switch ((int)obj->i2c) {
case I2C_0: CPGSTBCR9 &= ~(0x80); break;
case I2C_1: CPGSTBCR9 &= ~(0x40); break;
case I2C_2: CPGSTBCR9 &= ~(0x20); break;
case I2C_3: CPGSTBCR9 &= ~(0x10); break;
}
dummy = CPGSTBCR9;
}
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// determine the SPI to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
obj->dummy = 1;
MBED_ASSERT((int)obj->i2c != NC);
// enable power
i2c_power_enable(obj);
// full reset
REG(CR1.UINT8[0]) &= ~(1 << 7); // CR1.ICE off
REG(CR1.UINT8[0]) |= (1 << 6); // CR1.IICRST on
REG(CR1.UINT8[0]) |= (1 << 7); // CR1.ICE on
REG(MR1.UINT8[0]) = 0x08; // P_phi /8 9bit (including Ack)
REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
// set default frequency at 100k
i2c_frequency(obj, 100000);
REG(MR2.UINT8[0]) = 0x07;
REG(MR3.UINT8[0]) = 0x00;
REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT
REG(IER.UINT8[0]) = 0x00; // no interrupt
REG(CR1.UINT32) &= ~(1 << 6); // CR1.IICRST negate reset
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
}
inline int i2c_start(i2c_t *obj) {
if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check
return 0xff;
}
REG(CR2.UINT8[0]) |= 0x62; // start
return 0x10;
}
inline int i2c_stop(i2c_t *obj) {
int timeout = 0;
// write the stop bit
REG(CR2.UINT32) |= (1 << 3);
// wait for SP bit to reset
while(REG(CR2.UINT32) & (1 << 3)) {
timeout ++;
if (timeout > 100000) return 1;
}
obj->dummy = 1;
REG(CR2.UINT32) &= ~ (1 << 3);
return 0;
}
static inline int i2c_do_write(i2c_t *obj, int value) {
// write the data
if (!(i2c_status(obj) & NACKF)) { // NACF=0
i2c_wait_TDRE(obj);
REG(DRT.UINT32) = value;
} else {
return 0xff;
}
return i2c_status(obj);
}
static inline int i2c_do_read(i2c_t *obj, int last) {
if (obj->dummy) {
volatile int dummy = REG(DRR.UINT32);
obj->dummy = 0;
}
if (last) {
// send a NOT ACK
REG(MR2.UINT32) |= (1 <<6);
} else {
// send a ACK
REG(MR2.UINT32) &= ~(1 <<6);
}
// wait for it to arrive
i2c_wait_RDRF(obj);
// return the data
return (REG(DRR.UINT32) & 0xFF);
}
void i2c_frequency(i2c_t *obj, int hz) {
uint32_t PCLK = 6666666;
uint32_t pulse = PCLK / (hz * 2);
// I2C Rate
REG(BRL.UINT32) = pulse;
REG(BRH.UINT32) = pulse;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int count, status;
status = i2c_start(obj);
if (status == 0xff) {
i2c_stop(obj);
return I2C_ERROR_BUS_BUSY;
}
status = i2c_do_write(obj, (address | 0x01));
if (status & 0x01) {
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
// Read in all except last byte
for (count = 0; count < (length - 1); count++) {
int value = i2c_do_read(obj, 0);
status = i2c_status(obj);
if (status & 0x10) {
i2c_stop(obj);
return count;
}
data[count] = (char) value;
}
// read in last byte
int value = i2c_do_read(obj, 1);
status = i2c_status(obj);
if (status & 0x10) {
i2c_stop(obj);
return length - 1;
}
data[count] = (char) value;
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
int i, status;
status = i2c_start(obj);
if ((status == 0xff)) {
i2c_stop(obj);
return I2C_ERROR_BUS_BUSY;
}
status = i2c_do_write(obj, address);
if (status & 0x10) {
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
for (i=0; i<length; i++) {
status = i2c_do_write(obj, data[i]);
if(status & 0x10) {
i2c_stop(obj);
return i;
}
}
// If not repeated start, send stop.
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) {
return (i2c_do_read(obj, last) & 0xFF);
}
int i2c_byte_write(i2c_t *obj, int data) {
int ack;
int status = i2c_do_write(obj, (data & 0xFF));
if (status & NACKF) {
ack = 0;
} else {
ack = 1;
}
return ack;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
if (enable_slave != 0) {
REG(SER.UINT32) = 0x01; // only slave addr 1 is enabled
} else {
REG(SER.UINT32) = 0x00; // no slave addr enabled
}
}
int i2c_slave_receive(i2c_t *obj) {
int status;
int retval;
status = i2c_addressed(obj);
switch(status) {
case 0x3: retval = 1; break;
case 0x2: retval = 2; break;
case 0x1: retval = 3; break;
default : retval = 1; break;
}
return(retval);
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
int count = 0;
int status;
if (obj->dummy) {
volatile int dummy = REG(DRR.UINT32) ;
obj->dummy = 0;
}
do {
i2c_wait_RDRF(obj);
status = i2c_status(obj);
if(!(status & 0x10)) {
data[count] = REG(DRR.UINT32) & 0xFF;
}
count++;
} while ( !(status & 0x10) && (count < length) );
if(status & 0x10) {
i2c_stop(obj);
}
//i2c_clear_TDRE(obj);
return count;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int count = 0;
int status;
if(length <= 0) {
return(0);
}
do {
status = i2c_do_write(obj, data[count]);
count++;
} while ((count < length) && !(status & 0x10));
if (!(status & 0x10)) {
i2c_stop(obj);
}
i2c_clear_TDRE(obj);
return(count);
}
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
REG(SAR0.UINT32) = address & 0xfe;
}

View File

@ -0,0 +1,73 @@
/* 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 <stdint.h>
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "gpio_object.h"
#ifdef __cplusplus
extern "C" {
#endif
struct i2c_s {
uint32_t i2c;
uint32_t dummy;
};
struct spi_s {
uint32_t spi;
};
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 serial_s {
struct st_scif *uart;
int index;
};
struct pwmout_s {
__IO uint16_t *MR;
__IO uint16_t *CY;
uint16_t flag;
PWMName pwm;
};
struct analogin_s {
ADCName adc;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,47 @@
/* 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 "mbed_error.h"
#include "gpio_addrdefine.h"
void pin_function(PinName pin, int function) {
if (pin == (PinName)NC) return;
int n = pin >> 4;
int bitmask = 1<<(pin & 0xf);
if (function == 0) {
// means GPIO mode
*PMC(n) &= ~bitmask;
} else {
// alt-function mode
*PMC(n) |= bitmask;
--function;
if (function & (1 << 2)) { *PFCAE(n) |= bitmask;}else { *PFCAE(n) &= ~bitmask;}
if (function & (1 << 1)) { *PFCE(n) |= bitmask;}else { *PFCE(n) &= ~bitmask;}
if (function & (1 << 0)) { *PFC(n) |= bitmask;}else { *PFC(n) &= ~bitmask;}
*PIPC(n) |= bitmask;
if (P1_0 <= pin && pin <= P1_7 && function == 0) {
*PBDC(n) |= bitmask;
}
}
}
void pin_mode(PinName pin, PinMode mode) {
// if (pin == (PinName)NC) { return; }
}

View File

@ -0,0 +1,65 @@
/* 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)(0);
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
obj->port = port;
obj->mask = mask;
// Do not use masking, because it prevents the use of the unmasked pins
// port_reg->FIOMASK = ~mask;
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

@ -0,0 +1,174 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "cpg_iodefine.h"
#include "pwm_iodefine.h"
#define TCR_CNT_EN 0x00000001
#define TCR_RESET 0x00000002
// PORT ID, PWM ID, Pin function
static const PinMap PinMap_PWM[] = {
{LED_RED , 0, 4},
{LED_GREEN, 1, 4},
{LED_BLUE , 2, 4},
{P4_7 , 3, 4},
{P8_14 , 4, 6},
{P8_15 , 5, 6},
{P8_13 , 6, 6},
{P8_11 , 7, 6},
{NC, NC, 0}
};
static __IO uint16_t PORT[] = {
PWM2E,
PWM2F,
PWM2G,
PWM2H,
PWM1G,
PWM1H,
PWM1F,
PWM1D,
};
static __IO uint16_t *PWM_MATCH[] = {
&PWMPWBFR_2E,
&PWMPWBFR_2E,
&PWMPWBFR_2G,
&PWMPWBFR_2G,
&PWMPWBFR_1G,
&PWMPWBFR_1G,
&PWMPWBFR_1E,
&PWMPWBFR_1C,
};
#define TCR_PWM_EN 0x00000008
static unsigned int pwm_clock_mhz;
void pwmout_init(pwmout_t* obj, PinName pin) {
// determine the channel
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(pwm != (PWMName)NC);
obj->pwm = pwm;
obj->MR = PWM_MATCH[pwm];
obj->flag = (PORT[pwm]&1)<<12;
// power on
CPGSTBCR3 &= ~(1<<0);
// clk mode settings PWM mode
PWMPWCR_1_BYTE_L = 0xc4;
PWMPWCR_2_BYTE_L = 0xc4;
// output settings
PWMPWPR_1_BYTE_L = 0x00;
PWMPWPR_2_BYTE_L = 0x00;
// cycle reg.
PWMPWCYR_1 = 0x3ff;
PWMPWCYR_2 = 0x3ff;
//pwm_clock_mhz = SystemCoreClock / 4000000;
PWMPWCR_1_BYTE_L = 0xcc;
PWMPWCR_2_BYTE_L = 0xcc;
// 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) {
// [TODO]
}
void pwmout_write(pwmout_t* obj, float value) {
if (value < 0.0f) {
value = 0.0;
} else if (value > 1.0f) {
value = 1.0;
}
// set channel match to percentage
uint16_t v = (uint32_t)((float)0x3ff* value);
v |= (obj->flag);
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
*obj->MR = v;
// accept on next period start
//LPC_PWM1->LER |= 1 << obj->pwm;
}
float pwmout_read(pwmout_t* obj) {
float v = (float)((*obj->MR&0x3ff)) / 0x3ff;
return (v > 1.0f) ? (1.0f) : (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) {
// calculate number of ticks
uint16_t ticks = 0x3ff * us;
// stop timer
*obj->MR = ticks;
// Scale the pulse width to preserve the duty ratio
// set the channel latch to update value at next period start
// LPC_PWM1->LER |= 1 << 0;
// enable counter and pwm, clear reset
// LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN;
}
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) {
// calculate number of ticks
uint32_t v = pwm_clock_mhz * us;
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
// set the match register value
*obj->MR = v;
// set the channel latch to update value at next period start
//LPC_PWM1->LER |= 1 << obj->pwm;
}

View File

@ -0,0 +1,357 @@
/* 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.
*/
// math.h required for floating point operations for baud rate calculation
#include "mbed_assert.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "serial_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "gpio_api.h"
#include "scif_iodefine.h"
typedef struct st_scif SCIF_TypeDef;
#include "cpg_iodefine.h"
/******************************************************************************
* INITIALIZATION
******************************************************************************/
#define UART_NUM 6
static const PinMap PinMap_UART_TX[] = {
{P6_3 , P_SCIF2, 7},
{P2_14, P_SCIF0, 6},
{P5_0 , P_SCIF4, 5},
{P5_3 , P_SCIF3, 5},
{P5_6 , P_SCIF6, 5},
{P2_5 , P_SCIF1, 6},
{P8_14, P_SCIF4, 7},
{P8_13, P_SCIF5, 5},
{P7_5 , P_SCIF7, 4},
{NC , NC , 0}
};
static const PinMap PinMap_UART_RX[] = {
{P6_2 , P_SCIF2, 7},
{P2_15, P_SCIF0, 6},
{P5_1 , P_SCIF4, 5},
{P5_4 , P_SCIF3, 5},
{P5_7 , P_SCIF6, 5},
{P2_6 , P_SCIF1, 6},
{P8_15, P_SCIF4, 7},
{P8_11, P_SCIF5, 5},
{P7_4 , P_SCIF7, 4},
{NC , NC , 0}
};
/* [TODO] impliment hardware Flow Control, interrupt
static const PinMap PinMap_UART_RTS[] = {
{P7_7, (int)P_SCIF7, 4},
{P2_7 , (int)P_SCIF1, 6},
{NC, NC, 0}
};
static const PinMap PinMap_UART_CTS[] = {
{P7_6, (int)P_SCIF7, 4},
{P2_3, (int)P_SCIF1, 6},
{NC, NC, 0}
};*/
static uart_irq_handler irq_handler;
int stdio_uart_inited = 0;
serial_t stdio_uart;
struct serial_global_data_s {
uint32_t serial_irq_id;
gpio_t sw_rts, sw_cts;
uint8_t count, rx_irq_set_flow, rx_irq_set_api;
};
static struct serial_global_data_s uart_data[UART_NUM];
void serial_init(serial_t *obj, PinName tx, PinName rx) {
int is_stdio_uart = 0;
// determine the UART to use
uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
uint32_t uart = pinmap_merge(uart_tx, uart_rx);
MBED_ASSERT((int)uart != NC);
obj->uart = (SCIF_TypeDef *)uart;
// enable power
switch (uart) {
case P_SCIF0: CPG.STBCR4 &= ~(1 << 7); break;
case P_SCIF1: CPG.STBCR4 &= ~(1 << 6); break;
case P_SCIF2: CPG.STBCR4 &= ~(1 << 5); break;
case P_SCIF3: CPG.STBCR4 &= ~(1 << 4); break;
case P_SCIF4: CPG.STBCR4 &= ~(1 << 3); break;
case P_SCIF5: CPG.STBCR4 &= ~(1 << 2); break;
case P_SCIF6: CPG.STBCR4 &= ~(1 << 1); break;
case P_SCIF7: CPG.STBCR4 &= ~(1 << 0); break;
}
volatile uint8_t dummy ;
dummy = CPG.STBCR4;
/* ==== SCIF initial setting ==== */
/* ---- Serial control register (SCSCR) setting ---- */
/* B'00 : Internal CLK */
obj->uart->SCSCR = 0x0000u; /* SCIF transmitting and receiving operations stop */
/* ---- FIFO control register (SCFCR) setting ---- */
/* Transmit FIFO reset & Receive FIFO data register reset */
obj->uart->SCFCR = 0x0006;
/* ---- Serial status register (SCFSR) setting ---- */
obj->uart->SCFSR &= 0xFF6Cu; /* ER,BRK,DR bit clear */
/* ---- Line status register (SCLSR) setting ---- */
/* ORER bit clear */
obj->uart->SCLSR = 0;
/* ---- Serial extension mode register (SCEMR) setting ----
b7 BGDM - Baud rate generator double-speed mode : Normal mode
b0 ABCS - Base clock select in asynchronous mode : Base clock is 16 times the bit rate */
obj->uart->SCEMR = 0x0000u;
/* ---- Bit rate register (SCBRR) setting ---- */
serial_baud (obj, 9600);
serial_format(obj, 8, ParityNone, 1);
/* ---- FIFO control register (SCFCR) setting ---- */
obj->uart->SCFCR = 0x0030u;
/* ---- Serial port register (SCSPTR) setting ----
b1 SPB2IO - Serial port break output : disabled
b0 SPB2DT - Serial port break data : High-level */
//obj->uart->SCSPTR |= 0x0000u;
obj->uart->SCSCR = 0x0030;
// pinout the chosen uart
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
switch (uart) {
case P_SCIF0: obj->index = 0; break;
case P_SCIF1: obj->index = 1; break;
case P_SCIF2: obj->index = 2; break;
case P_SCIF3: obj->index = 3; break;
case P_SCIF4: obj->index = 4; break;
case P_SCIF5: obj->index = 5; break;
case P_SCIF6: obj->index = 6; break;
}
uart_data[obj->index].sw_rts.pin = NC;
uart_data[obj->index].sw_cts.pin = NC;
serial_set_flow_control(obj, FlowControlNone, NC, NC);
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
if (is_stdio_uart) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj) {
uart_data[obj->index].serial_irq_id = 0;
}
// serial_baud
// set the baud rate, taking in to account the current SystemFrequency
void serial_baud(serial_t *obj, int baudrate) {
uint32_t PCLK = 66666666;
uint16_t DL = (PCLK / (32 * baudrate)) -1;
// set LCR[DLAB] to enable writing to divider registers
obj->uart->SCBRR = DL;
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
MBED_ASSERT((data_bits > 6) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
(parity == ParityForced1) || (parity == ParityForced0));
stop_bits = (stop_bits == 1)? 0:
(stop_bits == 2)? 1:
0; // must not to be
data_bits = (data_bits == 8)? 0:
(data_bits == 7)? 1:
0; // must not to be
int parity_enable, parity_select;
switch (parity) {
case ParityNone: parity_enable = 0; parity_select = 0; break;
case ParityOdd : parity_enable = 1; parity_select = 0; break;
case ParityEven: parity_enable = 1; parity_select = 1; break;
default:
parity_enable = 0, parity_select = 0;
break;
}
obj->uart->SCSMR = data_bits << 6
| parity_enable << 5
| parity_select << 4
| stop_bits << 3;
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
void uart0_irq() {irq_handler(0, RxIrq);//dummy call
}
void uart1_irq() {/*uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_UART_TypeDef*)LPC_UART1);*/}
void uart2_irq() {/*uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2, (LPC_UART_TypeDef*)LPC_UART2);*/}
void uart3_irq() {/*uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LPC_UART3);*/}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler;
uart_data[obj->index].serial_irq_id = id;
}
static void serial_irq_set_internal(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;
case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break;
}
if (enable) {
obj->uart->IER |= 1 << irq;
//NVIC_SetVector(irq_n, vector);
//NVIC_EnableIRQ(irq_n);
} else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
obj->uart->IER &= ~(1 << irq);
all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
if (all_disabled) ;
//NVIC_DisableIRQ(irq_n);
}*/
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
if (RxIrq == irq)
uart_data[obj->index].rx_irq_set_api = enable;
serial_irq_set_internal(obj, irq, enable);
}
static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
uart_data[obj->index].rx_irq_set_flow = enable;
serial_irq_set_internal(obj, RxIrq, enable);
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj) {
if (obj->uart->SCFSR & 0x93) { obj->uart->SCFSR = ~0x93;}
while (!serial_readable(obj));
int data = obj->uart->SCFRDR & 0xff;
/* Clear DR,RDF */
obj->uart->SCFSR &= 0xfffc;
return data;
}
void serial_putc(serial_t *obj, int c) {
while (!serial_writable(obj));
obj->uart->SCFTDR = c;
obj->uart->SCFSR &= 0xff9f; // Clear TEND/TDFE
uart_data[obj->index].count++;
}
int serial_readable(serial_t *obj) {
return obj->uart->SCFSR & 0x02; // RDF
}
int serial_writable(serial_t *obj) {
return obj->uart->SCFSR & 0x20; // TDFE
}
void serial_clear(serial_t *obj) {
obj->uart->SCFCR = 0x06;
obj->uart->SCFCR = 0x06;
}
void serial_pinout_tx(PinName tx) {
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj) {
//obj->uart->LCR |= (1 << 6);
}
void serial_break_clear(serial_t *obj) {
//obj->uart->LCR &= ~(1 << 6);
}
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
serial_flow_irq_set(obj, 0);
// Only UART1 has hardware flow control on LPC176x
/*LPC_UART1_TypeDef *uart1 = (uint32_t)obj->uart == (uint32_t)LPC_UART1 ? LPC_UART1 : NULL;
int index = obj->index;
// First, disable flow control completely
if (uart1)
uart1->MCR = uart1->MCR & ~UART_MCR_FLOWCTRL_MASK;
uart_data[index].sw_rts.pin = uart_data[index].sw_cts.pin = NC;
serial_flow_irq_set(obj, 0);
if (FlowControlNone == type)
return;
// Check type(s) of flow control to use
UARTName uart_rts = (UARTName)pinmap_find_peripheral(rxflow, PinMap_UART_RTS);
UARTName uart_cts = (UARTName)pinmap_find_peripheral(txflow, PinMap_UART_CTS);
if (((FlowControlCTS == type) || (FlowControlRTSCTS == type)) && (NC != txflow)) {
// Can this be enabled in hardware?
if ((UART_1 == uart_cts) && (NULL != uart1)) {
// Enable auto-CTS mode
uart1->MCR |= UART_MCR_CTSEN_MASK;
pinmap_pinout(txflow, PinMap_UART_CTS);
} else {
// Can't enable in hardware, use software emulation
gpio_init_in(&uart_data[index].sw_cts, txflow);
}
}
if (((FlowControlRTS == type) || (FlowControlRTSCTS == type)) && (NC != rxflow)) {
// Enable FIFOs, trigger level of 1 char on RX FIFO
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
| 1 << 1 // Rx Fifo Reset
| 1 << 2 // Tx Fifo Reset
| 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
// Can this be enabled in hardware?
if ((UART_1 == uart_rts) && (NULL != uart1)) {
// Enable auto-RTS mode
uart1->MCR |= UART_MCR_RTSEN_MASK;
pinmap_pinout(rxflow, PinMap_UART_RTS);
} else { // can't enable in hardware, use software emulation
gpio_init_out_ex(&uart_data[index].sw_rts, rxflow, 0);
// Enable RX interrupt
serial_flow_irq_set(obj, 1);
}
}*/
}

View File

@ -0,0 +1,234 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include <math.h>
#include "spi_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "rspi_iodefine.h"
static const PinMap PinMap_SPI_SCLK[] = {
{P10_12, SPI_0, 4},
{P11_12, SPI_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{P10_13, SPI_0, 4},
{P11_13, SPI_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MOSI[] = {
{P10_14, SPI_0, 4},
{P11_14, SPI_1, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{P10_15, SPI_0, 4},
{P11_15, SPI_1, 2},
{NC , NC , 0}
};
struct st_rspi *RSPI[] = RSPI_ADDRESS_LIST;
static inline void spi_disable(spi_t *obj);
static inline void spi_enable(spi_t *obj);
static inline int spi_readable(spi_t *obj);
static inline void spi_write(spi_t *obj, int value);
static inline int spi_writable(spi_t *obj);
static inline int spi_read(spi_t *obj);
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
// determine the SPI to use
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
//SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
//SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
obj->spi = spi_mosi; //pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT((int)obj->spi != NC);
// enable power and clocking
volatile uint8_t dummy;
switch ((int)obj->spi) {
case SPI_0: CPGSTBCR10 &= ~(0x80); break;
case SPI_1: CPGSTBCR10 &= ~(0x40); break;
}
dummy = CPGSTBCR10;
RSPI[obj->spi]->SPCR = 0x00; // CTRL to 0
RSPI[obj->spi]->SPSCR = 0x00; // no sequential operation
RSPI[obj->spi]->SSLP = 0x00; // SSL 'L' active
RSPI[obj->spi]->SPDCR = 0x20; // byte access
RSPI[obj->spi]->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
RSPI[obj->spi]->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
RSPI[obj->spi]->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
RSPI[obj->spi]->SPPCR = 0x20; //
RSPI[obj->spi]->SPBFCR= 0xf0; // and set trigger count: read 1, write 1
RSPI[obj->spi]->SPBFCR= 0x30; // and reset buffer
// set default format and frequency
if (ssel == NC) {
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
} else {
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
}
spi_frequency(obj, 1000000);
// enable the ssp channel
spi_enable(obj);
// pin out the spi pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
}
}
void spi_free(spi_t *obj) {}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
spi_disable(obj);
MBED_ASSERT(((bits >= 4) && (bits <= 16)) && (mode >= 0 && mode <= 3));
int polarity = (mode & 0x2) ? 1 : 0;
int phase = (mode & 0x1) ? 1 : 0;
uint16_t tmp = 0, mask = 0xf03;
tmp |= phase;
tmp |= polarity << 1;
int DSS; // DSS (data select size)
switch (bits) {
case 8:
DSS = 0x7; break;
case 16:
DSS = 0xf; break;
case 32:
DSS = 0x2; break;
default:
error("SPI module don't support other than 8/16/32bits");
return ;
}
tmp |= (DSS << 8);
// set it up
RSPI[obj->spi]->SPCMD0 &= ~mask;
RSPI[obj->spi]->SPCMD0 |= (mask & tmp);
if (slave) {
RSPI[obj->spi]->SPCR &=~(1 << 3);
} else {
RSPI[obj->spi]->SPCR |= (1 << 3);
}
spi_enable(obj);
}
void spi_frequency(spi_t *obj, int hz) {
spi_disable(obj);
const int P1CLK = 66666666; // 66.6666MHz
uint8_t div, brdv;
uint16_t mask = 0x000c0;
if (hz <= P1CLK/2 && hz >= P1CLK/255) {
div = (P1CLK / hz / 2) -1;
brdv = 0x0 << 2;
} else if (hz >= P1CLK/255/2) {
div = (P1CLK / hz / 2 /2) -1;
brdv = 0x1 << 2;
} else if (hz >= P1CLK/255/4) {
div = (P1CLK / hz / 2 /4) -1;
brdv = 0x2 << 2;
} else if (hz >= P1CLK/255/8) {
div = (P1CLK / hz / 2 /8) -1;
brdv = 0x3 << 2;
} else {
error("Couldn't setup requested SPI frequency");
return;
}
RSPI[obj->spi]->SPBR = div;
RSPI[obj->spi]->SPCMD0 &= ~mask;
RSPI[obj->spi]->SPCMD0 |= (mask & brdv);
spi_enable(obj);
}
static inline void spi_disable(spi_t *obj) {
RSPI[obj->spi]->SPCR &= ~(1 << 6); // SPE to 0
}
static inline void spi_enable(spi_t *obj) {
RSPI[obj->spi]->SPCR |= (1 << 6); // SPE to 1
}
static inline int spi_readable(spi_t *obj) {
return RSPI[obj->spi]->SPSR & (1 << 7);
}
static inline int spi_tend(spi_t *obj) {
return RSPI[obj->spi]->SPSR & (1 << 6);
}
static inline int spi_writable(spi_t *obj) {
return RSPI[obj->spi]->SPSR & (1 << 5);
}
static inline void spi_write(spi_t *obj, int value) {
while (!spi_writable(obj));
RSPI[obj->spi]->SPDR.UINT8[0] = value;
}
static inline int spi_read(spi_t *obj) {
//while (!spi_readable(obj));
return RSPI[obj->spi]->SPDR.UINT8[0];
}
int spi_master_write(spi_t *obj, int value) {
spi_write(obj, value);
while(!spi_tend(obj));
return spi_read(obj);
}
int spi_slave_receive(spi_t *obj) {
return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0);
}
int spi_slave_read(spi_t *obj) {
return RSPI[obj->spi]->SPDR.UINT8[0];
}
void spi_slave_write(spi_t *obj, int value) {
while (spi_writable(obj) == 0) ;
RSPI[obj->spi]->SPDR.UINT8[0] = value;
}
int spi_busy(spi_t *obj) {
return (RSPI[obj->spi]->SPSR & (1 << 6)) ? (0) : (1);
}

View File

@ -0,0 +1,96 @@
/* 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"
#include "mtu2_iodefine.h"
#define US_TICKER_TIMER (OSTM0.OSTMnCMP)
#define US_TICKER_TIMER_IRQn TIMER3_IRQn
int us_ticker_inited = 0;
void us_ticker_interrupt(void) {
us_ticker_irq_handler();
GIC_EndInterrupt(TGI2A_IRQn);
}
void us_ticker_init(void) {
if (us_ticker_inited) return;
us_ticker_inited = 1;
/* Power Control for Peripherals */
CPGSTBCR3 &= ~ 0x8; // turn on MTU2
// timer settings
MTU2.TSYR = 0x6; // cascading T_1-T_2
MTU2.TCR_2 = 0x03; // divider 1/64
MTU2.TCR_1 = 0x07; // count-up from T_2 pulse(cascade)
MTU2.TCNT_1 = 0x00; // counter value set to 0
MTU2.TCNT_2 = 0x00; //
MTU2.TSTR |= 0x06; //
MTU2.TSR_2 = 0xc0; // timer start
// INTC settings
InterruptHandlerRegister(TGI2A_IRQn, (void (*)(uint32_t))us_ticker_interrupt);
GIC_SetPriority(TGI2A_IRQn, 5);
GIC_EnableIRQ(TGI2A_IRQn);
__enable_irq();
}
//static const float PCLK =33.33, // dummy
//PRESCALE =64.0; // dummy
static const float FACTOR_C2U = 1.9201920192019204, //(PRESCALE/PCLK)
FACTOR_U2C = 0.52078125; //(PCLK/PRESCALE)
#define F_CLK2us(val) ((uint32_t)((val)*FACTOR_C2U))
#define F_us2CLK(val) ((uint32_t)((val)*FACTOR_U2C))
uint32_t us_ticker_read() {
static uint32_t max_val = 0x8551eb85; //*F_us2CLK(0xffffffff)+1;
uint32_t val;
if (!us_ticker_inited)
us_ticker_init();
val = MTU2.TCNT_1<<16 | MTU2.TCNT_2; // concat cascaded Counters
if (val > max_val) { // if overflow (in us-timer)
val -= max_val; // correct value
MTU2.TCNT_1 = 0; // reset counter
MTU2.TCNT_2 = val;
}
val = F_CLK2us(val);
return val;
}
void us_ticker_set_interrupt(timestamp_t timestamp) {
// set match value
timestamp = F_us2CLK(timestamp);
MTU2.TGRA_2 = timestamp & 0xffff;
// enable match interrupt
MTU2.TIER_2 = 0x01;
}
void us_ticker_disable_interrupt(void) {
MTU2.TIER_2 &= ~(0xc0);
}
void us_ticker_clear_interrupt(void) {
MTU2.TSR_2 &= 0xc0;
}