mirror of https://github.com/ARMmbed/mbed-os.git
[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 driverpull/594/head
parent
193bdaa8c9
commit
9ddce12aa6
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef RESERVED_PINS_H
|
||||||
|
#define RESERVED_PINS_H
|
||||||
|
|
||||||
|
#define TARGET_RESERVED_PINS {}
|
||||||
|
|
||||||
|
#endif
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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__*/
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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; }
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue