mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #875 from masaohamanaka/master
RZ_A1H - Add some function and fix some bugs.pull/879/head
commit
c53fab9e3c
|
@ -22,20 +22,18 @@
|
|||
#include "adc_iodefine.h"
|
||||
#include "cpg_iodefine.h"
|
||||
|
||||
#define ANALOGIN_MEDIAN_FILTER 1
|
||||
|
||||
#define ADC_12BIT_RANGE 0xFFF
|
||||
#define ANALOGIN_MEDIAN_FILTER 0
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
{P1_8, AN0, 1},
|
||||
{P1_9, AN1, 1},
|
||||
{P1_10, AN2, 1},
|
||||
{P1_11, AN3, 1},
|
||||
{P1_12, AN3, 1},
|
||||
{P1_12, AN3, 1},
|
||||
{P1_13, AN5, 1},
|
||||
{P1_14, AN5, 1},
|
||||
{P1_14, AN5, 1},
|
||||
{P1_15, AN7, 1},
|
||||
{NC, NC, 0}
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
static volatile uint16_t *ADCDR[] = {
|
||||
|
@ -49,45 +47,41 @@ static volatile uint16_t *ADCDR[] = {
|
|||
&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 00_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 = 0x01c0 ;
|
||||
|
||||
for (int i = 0; i< sizeof(PinMap_ADC)/sizeof(PinMap); i++) {
|
||||
pinmap_pinout(PinMap_ADC[i].pin, PinMap_ADC);
|
||||
}
|
||||
// 15: ADF 14: ADIE 13: ADST, [12:9] TRGS..0
|
||||
// [8:6] CKS 010 :: 340tclk
|
||||
// [5:3] MDS 000 :: single mode
|
||||
// [2:0] CH 000 :: AN0
|
||||
ADCADCSR = 0x0080;
|
||||
|
||||
//pinmap_pinout(pin, PinMap_ADC);
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
}
|
||||
|
||||
static inline uint32_t adc_read(analogin_t *obj) {
|
||||
volatile uint16_t data;
|
||||
|
||||
// Select the appropriate channel and start conversion
|
||||
|
||||
ADCADCSR &= 0xfff8;
|
||||
ADCADCSR |= (1 << 13 | (obj->adc&0x7));
|
||||
|
||||
// Repeatedly get the sample data until DONE bit
|
||||
#define nothing
|
||||
while ((ADCADCSR & (1 << 15)) == 0 || (ADCADCSR & (1<<13)) != 0) nothing;
|
||||
|
||||
ADCADCSR |= (1 << 13 | (obj->adc & 0x7));
|
||||
|
||||
// Wait end of conversion
|
||||
do {
|
||||
data = ADCADCSR;
|
||||
} while (((data & (1 << 15)) == 0) || ((data & (1 << 13)) != 0));
|
||||
|
||||
// clear flag
|
||||
ADCADCSR &= ~(1 << 15);
|
||||
|
||||
return ((*(ADCDR[obj->adc]))>>4) & ADC_RANGE; // 12 bit
|
||||
|
||||
return ((*(ADCDR[obj->adc])) >> 4) & 0x0FFF; // 12 bits range
|
||||
}
|
||||
|
||||
#if ANALOGIN_MEDIAN_FILTER
|
||||
static inline void order(uint32_t *a, uint32_t *b) {
|
||||
if (*a > *b) {
|
||||
uint32_t t = *a;
|
||||
|
@ -95,6 +89,7 @@ static inline void order(uint32_t *a, uint32_t *b) {
|
|||
*b = t;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t adc_read_u32(analogin_t *obj) {
|
||||
uint32_t value;
|
||||
|
@ -114,12 +109,12 @@ static inline uint32_t adc_read_u32(analogin_t *obj) {
|
|||
|
||||
uint16_t analogin_read_u16(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
|
||||
return value;
|
||||
//(value << 4) | ((value >> 8) & 0x000F); // 12 bit
|
||||
|
||||
return (value << 4) | ((value >> 8) & 0x000F); // 12-bit to 16-bit conversion
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
return (float)value * (1.0f / (float)ADC_RANGE);
|
||||
|
||||
return (float)value * (1.0f / (float)0x0FFF); // 12 bits range
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
#define DEVICE_CAN 0
|
||||
|
||||
#define DEVICE_RTC 0
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_ETHERNET 1
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ uint32_t gpio_set(PinName pin) {
|
|||
|
||||
void gpio_init(gpio_t *obj, PinName pin) {
|
||||
int group ;
|
||||
obj->pin = pin;
|
||||
if(pin == NC) return;
|
||||
|
||||
obj->pin = pin;
|
||||
obj->mask = gpio_set(pin);
|
||||
|
||||
group = PINGROUP(pin);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef MBED_GPIO_OBJECT_H
|
||||
#define MBED_GPIO_OBJECT_H
|
||||
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -34,8 +34,9 @@ volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
|
|||
|
||||
/* RIICnCR2 */
|
||||
#define CR2_ST (1 << 1)
|
||||
#define CR2_RS (1 << 2)
|
||||
#define CR2_SP (1 << 3)
|
||||
#define CR2_NACKF (1 << 4)
|
||||
#define CR2_TRS (1 << 5)
|
||||
#define CR2_BBSY (1 << 7)
|
||||
|
||||
/* RIICnMR3 */
|
||||
|
@ -43,7 +44,14 @@ volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
|
|||
#define MR3_ACKWP (1 << 4)
|
||||
#define MR3_WAIT (1 << 6)
|
||||
|
||||
/* RIICnSER */
|
||||
#define SER_SAR0E (1 << 0)
|
||||
|
||||
/* RIICnSR1 */
|
||||
#define SR1_AAS0 (1 << 0)
|
||||
|
||||
/* RIICnSR2 */
|
||||
#define SR2_START (1 << 2)
|
||||
#define SR2_STOP (1 << 3)
|
||||
#define SR2_NACKF (1 << 4)
|
||||
#define SR2_RDRF (1 << 5)
|
||||
|
@ -67,35 +75,10 @@ static const PinMap PinMap_I2C_SCL[] = {
|
|||
};
|
||||
|
||||
|
||||
/* 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) &= ~SR2_TDRE;
|
||||
}
|
||||
|
||||
static inline int i2c_wait_RDRF(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_RDRF)) {
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_reg_reset(i2c_t *obj) {
|
||||
/* full reset */
|
||||
REG(CR1.UINT8[0]) &= ~CR1_ICE; // CR1.ICE off
|
||||
|
@ -119,7 +102,20 @@ static void i2c_reg_reset(i2c_t *obj) {
|
|||
REG(CR1.UINT32) &= ~CR1_RST; // CR1.IICRST negate reset
|
||||
}
|
||||
|
||||
/* Wait until the Trans Data Empty (TDRE) is set */
|
||||
static inline int i2c_wait_RDRF(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_RDRF)) {
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_wait_TDRE(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
|
@ -149,6 +145,20 @@ static int i2c_wait_TEND(i2c_t *obj) {
|
|||
}
|
||||
|
||||
|
||||
static int i2c_wait_START(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_START)) {
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_wait_STOP(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
|
@ -163,26 +173,42 @@ static int i2c_wait_STOP(i2c_t *obj) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_set_NACKF_STOP(i2c_t *obj) {
|
||||
static void i2c_set_SR2_NACKF_STOP(i2c_t *obj) {
|
||||
/* SR2.NACKF = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_NACKF;
|
||||
/* SR2.STOP = 0 */
|
||||
/* SR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
}
|
||||
|
||||
static void i2c_set_err_noslave(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
static void i2c_set_MR3_NACK(i2c_t *obj) {
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
}
|
||||
|
||||
static void i2c_set_MR3_ACK(i2c_t *obj) {
|
||||
/* send a ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
@ -202,6 +228,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
|||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
obj->last_stop_flag = 1;
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
|
@ -210,10 +238,7 @@ inline int i2c_start(i2c_t *obj) {
|
|||
while (REG(CR2.UINT32) & CR2_BBSY) {
|
||||
timeout ++;
|
||||
if (timeout >= obj->bbsy_wait_cnt) {
|
||||
i2c_reg_reset(obj);
|
||||
/* Start Condition */
|
||||
REG(CR2.UINT8[0]) |= CR2_ST;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Start Condition */
|
||||
|
@ -222,8 +247,17 @@ inline int i2c_start(i2c_t *obj) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline int i2c_restart(i2c_t *obj) {
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
/* ReStart condition */
|
||||
REG(CR2.UINT32) |= CR2_RS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj) {
|
||||
/* SR2.STOP = 0 */
|
||||
/* SR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
/* Stop condition */
|
||||
REG(CR2.UINT32) |= CR2_SP;
|
||||
|
@ -231,6 +265,19 @@ inline int i2c_stop(i2c_t *obj) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_set_err_noslave(i2c_t *obj, int stop) {
|
||||
if (stop) {
|
||||
(void)i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int i2c_do_write(i2c_t *obj, int value) {
|
||||
int timeout = 0;
|
||||
|
||||
|
@ -259,14 +306,14 @@ static inline int i2c_do_write(i2c_t *obj, int value) {
|
|||
|
||||
static inline int i2c_read_address_write(i2c_t *obj, int value) {
|
||||
int status;
|
||||
|
||||
status = i2c_wait_TDRE(obj);
|
||||
if (status == 0) {
|
||||
/* write the data */
|
||||
REG(DRT.UINT32) = value;
|
||||
return 0;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
@ -276,15 +323,9 @@ static inline int i2c_do_read(i2c_t *obj, int last) {
|
|||
/* Set MR3 WAIT bit is 1 */;
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
} else if (last == 1) {
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
i2c_set_MR3_NACK(obj);
|
||||
} else {
|
||||
/* send a ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
i2c_set_MR3_ACK(obj);
|
||||
}
|
||||
|
||||
/* return the data */
|
||||
|
@ -383,27 +424,45 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
int value;
|
||||
volatile uint32_t work_reg = 0;
|
||||
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
if(length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
i2c_set_MR3_ACK(obj);
|
||||
/* There is a STOP condition for last processing */
|
||||
if (obj->last_stop_flag != 0) {
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
}
|
||||
obj->last_stop_flag = stop;
|
||||
/* Send Slave address */
|
||||
status = i2c_read_address_write(obj, (address | 0x01));
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* wati RDRF */
|
||||
/* wait RDRF */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
/* check ACK/NACK */
|
||||
if ((status != 0) || (REG(SR2.UINT32) & CR2_NACKF == 1)) {
|
||||
if ((status != 0) || (REG(SR2.UINT32) & SR2_NACKF == 1)) {
|
||||
/* Slave sends NACK */
|
||||
i2c_stop(obj);
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
/* If not repeated start, send stop. */
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
}
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* Read in all except last byte */
|
||||
|
@ -414,7 +473,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* Recieve the data */
|
||||
|
@ -428,60 +487,55 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
data[count] = (char)value;
|
||||
}
|
||||
} else if (length == 2) {
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
/* Set MR3 WATI bit is 1 */
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
i2c_set_MR3_NACK(obj);
|
||||
data[count] = (char)REG(DRR.UINT32);
|
||||
count++;
|
||||
} else if (length == 1) {
|
||||
} else {
|
||||
/* length == 1 */
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
i2c_set_MR3_NACK(obj);
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
} else {
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
/* If not repeated start, send stop. */
|
||||
if (stop) {
|
||||
/* RIICnSR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
/* RIICnCR2.SP = 1 */
|
||||
REG(CR2.UINT32) |= CR2_SP;
|
||||
(void)i2c_stop(obj);
|
||||
/* RIICnDRR read */
|
||||
value = REG(DRR.UINT32) & 0xFF;
|
||||
data[count] = (char)value;
|
||||
/* RIICnMR3.WAIT = 0 */
|
||||
REG(MR3.UINT32) &= ~MR3_WAIT;
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
/* RIICnDRR read */
|
||||
value = REG(DRR.UINT32) & 0xFF;
|
||||
data[count] = (char)value;
|
||||
/* RIICnMR3.WAIT = 0 */
|
||||
REG(MR3.UINT32) &= ~MR3_WAIT;
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
}
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
@ -490,37 +544,51 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
|||
int cnt;
|
||||
int status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
if(length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* There is a STOP condition for last processing */
|
||||
if (obj->last_stop_flag != 0) {
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
}
|
||||
obj->last_stop_flag = stop;
|
||||
/* Send Slave address */
|
||||
status = i2c_do_write(obj, address);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* Send Write data */
|
||||
for (cnt=0; cnt<length; cnt++) {
|
||||
status = i2c_do_write(obj, data[cnt]);
|
||||
if(status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
/* Wait send end */
|
||||
status = i2c_wait_TEND(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_set_err_noslave(obj, stop);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* If not repeated start, send stop. */
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
(void)i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
|
||||
}
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
@ -528,30 +596,29 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
|||
void i2c_reset(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
int status;
|
||||
|
||||
/* dummy read */
|
||||
(void)REG(DRR.UINT32);
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
i2c_set_err_noslave(obj, 1);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
return (i2c_do_read(obj, last) & 0xFF);
|
||||
return (i2c_do_read(obj, last));
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
int ack;
|
||||
int status = i2c_do_write(obj, (data & 0xFF));
|
||||
int status;
|
||||
|
||||
status = i2c_do_write(obj, (data & 0xFF));
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj, 1);
|
||||
ack = 0;
|
||||
} else {
|
||||
ack = 1;
|
||||
|
@ -562,9 +629,9 @@ int i2c_byte_write(i2c_t *obj, int data) {
|
|||
|
||||
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
|
||||
if (enable_slave != 0) {
|
||||
REG(SER.UINT32) = 0x01; // only slave addr 1 is enabled
|
||||
REG(SER.UINT32) |= SER_SAR0E; // only slave addr 0 is enabled
|
||||
} else {
|
||||
REG(SER.UINT32) = 0x00; // no slave addr enabled
|
||||
REG(SER.UINT32) &= ~SER_SAR0E; // no slave addr enabled
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,67 +639,109 @@ int i2c_slave_receive(i2c_t *obj) {
|
|||
int status;
|
||||
int retval;
|
||||
|
||||
status = i2c_addressed(obj);
|
||||
status = REG(SR1.UINT8[0]) & SR1_AAS0;
|
||||
status |= (REG(CR2.UINT8[0]) & CR2_TRS) >> 4;
|
||||
|
||||
switch(status) {
|
||||
case 0x3: retval = 1; break;
|
||||
case 0x2: retval = 2; break;
|
||||
case 0x1: retval = 3; break;
|
||||
default : retval = 1; break;
|
||||
case 0x01:
|
||||
/* the master is writing to this slave */
|
||||
retval = 3;
|
||||
break;
|
||||
case 0x02:
|
||||
/* the master is writing to all slave */
|
||||
retval = 2;
|
||||
break;
|
||||
case 0x03:
|
||||
/* the master has requested a read from this slave */
|
||||
retval = 1;
|
||||
break;
|
||||
default :
|
||||
/* no data */
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int i2c_slave_read(i2c_t *obj, char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
int timeout = 0;
|
||||
int count;
|
||||
int break_flg = 0;
|
||||
|
||||
volatile int dummy = REG(DRR.UINT32) ;
|
||||
|
||||
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);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
if(length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (count = 0; ((count < (length + 1)) && (break_flg == 0)); count++) {
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while ((i2c_status(obj) & SR2_STOP) || (!(i2c_status(obj) & SR2_RDRF))) {
|
||||
/* RIICnSR2.STOP = 1 or RIICnSR2.RDRF = 0 */
|
||||
if (i2c_status(obj) & SR2_STOP) {
|
||||
/* RIICnSR2.STOP = 1 */
|
||||
break_flg = 1;
|
||||
break;
|
||||
}
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (break_flg == 0) {
|
||||
if (count == 0) {
|
||||
/* dummy read */
|
||||
(void)REG(DRR.UINT32);
|
||||
} else {
|
||||
data[count - 1] = (char)(REG(DRR.UINT32) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (break_flg == 0) {
|
||||
(void)i2c_wait_STOP(obj);
|
||||
} else {
|
||||
if (i2c_status(obj) & SR2_RDRF) {
|
||||
if (count <= 1) {
|
||||
/* fail safe */
|
||||
/* dummy read */
|
||||
(void)REG(DRR.UINT32);
|
||||
} else {
|
||||
data[count - 2] = (char)(REG(DRR.UINT32) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* SR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
|
||||
//i2c_clear_TDRE(obj);
|
||||
|
||||
return count;
|
||||
return (count - 1);
|
||||
}
|
||||
|
||||
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
int status = 0;
|
||||
|
||||
if(length <= 0) {
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
while ((count < length) && (status == 0)) {
|
||||
status = i2c_do_write(obj, data[count]);
|
||||
count++;
|
||||
} while ((count < length) && !(status & 0x10));
|
||||
|
||||
if (!(status & 0x10)) {
|
||||
i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
}
|
||||
if (status == 0) {
|
||||
/* Wait send end */
|
||||
status = i2c_wait_TEND(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* dummy read */
|
||||
(void)REG(DRR.UINT32);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
|
||||
i2c_clear_TDRE(obj);
|
||||
|
||||
return(count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
|
||||
REG(SAR0.UINT32) = address & 0xfe;
|
||||
REG(SAR0.UINT32) = address & 0xfffffffe;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ struct i2c_s {
|
|||
uint8_t width_low;
|
||||
uint8_t width_hi;
|
||||
int bbsy_wait_cnt;
|
||||
int last_stop_flag;
|
||||
};
|
||||
|
||||
struct spi_s {
|
||||
|
|
|
@ -0,0 +1,374 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 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 "device.h"
|
||||
|
||||
#if DEVICE_RTC
|
||||
|
||||
#include "rtc_api.h"
|
||||
#include "rtc_iodefine.h"
|
||||
|
||||
|
||||
#define RCR1_VAL_ON (0x08u) // AIE = 1
|
||||
#define RCR1_VAL_OFF (0x00u)
|
||||
#define RCR2_VAL_ALLSTOP (0x00u)
|
||||
#define RCR2_VAL_START (0x01u) // START = 1
|
||||
#define RCR2_VAL_RESET (0x02u) // RESET = 1
|
||||
#define RCR3_VAL (0x00u)
|
||||
#define RCR5_VAL_EXTAL (0x01u) // RCKSEL = connect EXTAL
|
||||
#define RCR5_VAL_RTCX1 (0x00u) // RCKSEL = disconnect EXTAL
|
||||
#define RFRH_VAL_13333 (0x8003u) // 13.3333MHz (= 64Hz * 0x32DCD)
|
||||
#define RFRL_VAL_13333 (0x2DCDu) //
|
||||
#define RFRH_VAL_MAX (0x0007u) // MAX value (= 128Hz * 0x7FFFF)
|
||||
#define RFRL_VAL_MAX (0xFFFFu) //
|
||||
|
||||
#define MASK_00_03_POS (0x000Fu)
|
||||
#define MASK_04_07_POS (0x00F0u)
|
||||
#define MASK_08_11_POS (0x0F00u)
|
||||
#define MASK_12_15_POS (0xF000u)
|
||||
#define MASK_16_20_POS (0x000F0000u)
|
||||
#define SHIFT_1_HBYTE (4u)
|
||||
#define SHIFT_2_HBYTE (8u)
|
||||
#define SHIFT_3_HBYTE (12u)
|
||||
#define SHIFT_1BYTE (8u)
|
||||
#define SHIFT_2BYTE (16u)
|
||||
|
||||
#define TIME_ERROR_VAL (0xFFFFFFFFu)
|
||||
|
||||
static int rtc_dec8_to_hex(uint8_t dec_val, uint8_t offset, int *hex_val);
|
||||
static int rtc_dec16_to_hex(uint16_t dec_val, uint16_t offset, int *hex_val);
|
||||
static uint8_t rtc_hex8_to_dec(uint8_t hex_val);
|
||||
static uint16_t rtc_hex16_to_dec(uint16_t hex_val);
|
||||
|
||||
|
||||
/*
|
||||
* Setup the RTC based on a time structure.
|
||||
* The rtc_init function should be executed first.
|
||||
* [in]
|
||||
* None.
|
||||
* [out]
|
||||
* None.
|
||||
*/
|
||||
void rtc_init(void) {
|
||||
volatile uint8_t dummy_read;
|
||||
|
||||
// Set control register
|
||||
RTC.RCR2 = RCR2_VAL_ALLSTOP;
|
||||
RTC.RCR1 = RCR1_VAL_ON;
|
||||
RTC.RCR3 = RCR3_VAL;
|
||||
RTC.RCR5 = RCR5_VAL_EXTAL;
|
||||
RTC.RFRH = RFRH_VAL_13333;
|
||||
RTC.RFRL = RFRL_VAL_13333;
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RCR2;
|
||||
dummy_read = RTC.RCR2;
|
||||
|
||||
RTC.RCR2 = RCR2_VAL_RESET; // RESET = 1
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RCR2;
|
||||
dummy_read = RTC.RCR2;
|
||||
|
||||
// Set timer and alarm. Default value :01-01-1970 00:00:00
|
||||
RTC.RSECCNT = 0;
|
||||
RTC.RMINCNT = 0;
|
||||
RTC.RHRCNT = 0;
|
||||
RTC.RWKCNT = 0;
|
||||
RTC.RDAYCNT = 1;
|
||||
RTC.RMONCNT = 1;
|
||||
RTC.RYRCNT = 0x1970;
|
||||
RTC.RSECAR = 0;
|
||||
RTC.RMINAR = 0;
|
||||
RTC.RHRAR = 0;
|
||||
RTC.RWKAR = 0;
|
||||
RTC.RDAYAR = 1;
|
||||
RTC.RMONAR = 1;
|
||||
RTC.RYRAR = 0x1970;
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RYRCNT;
|
||||
dummy_read = RTC.RYRCNT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Release the RTC based on a time structure.
|
||||
* [in]
|
||||
* None.
|
||||
* [out]
|
||||
* None.
|
||||
*/
|
||||
void rtc_free(void) {
|
||||
volatile uint8_t dummy_read;
|
||||
|
||||
// Set control register
|
||||
RTC.RCR2 = RCR2_VAL_ALLSTOP;
|
||||
RTC.RCR1 = RCR1_VAL_OFF;
|
||||
RTC.RCR3 = RCR3_VAL;
|
||||
RTC.RCR5 = RCR5_VAL_RTCX1;
|
||||
RTC.RFRH = RFRH_VAL_MAX;
|
||||
RTC.RFRL = RFRL_VAL_MAX;
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RCR2;
|
||||
dummy_read = RTC.RCR2;
|
||||
RTC.RCR2 = RCR2_VAL_RESET; // RESET = 1
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RCR2;
|
||||
dummy_read = RTC.RCR2;
|
||||
|
||||
// Set timer and alarm. Default value :01-01-1970 00:00:00
|
||||
RTC.RSECCNT = 0;
|
||||
RTC.RMINCNT = 0;
|
||||
RTC.RHRCNT = 0;
|
||||
RTC.RWKCNT = 0;
|
||||
RTC.RDAYCNT = 1;
|
||||
RTC.RMONCNT = 1;
|
||||
RTC.RYRCNT = 0x1970;
|
||||
RTC.RSECAR = 0;
|
||||
RTC.RMINAR = 0;
|
||||
RTC.RHRAR = 0;
|
||||
RTC.RWKAR = 0;
|
||||
RTC.RDAYAR = 1;
|
||||
RTC.RMONAR = 1;
|
||||
RTC.RYRAR = 0x1970;
|
||||
|
||||
// Dummy read
|
||||
dummy_read = RTC.RYRCNT;
|
||||
dummy_read = RTC.RYRCNT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check the RTC has been enabled.
|
||||
* Clock Control Register RTC.RCR1(bit3): 0 = Disabled, 1 = Enabled.
|
||||
* [in]
|
||||
* None.
|
||||
* [out]
|
||||
* 0:Disabled, 1:Enabled.
|
||||
*/
|
||||
int rtc_isenabled(void) {
|
||||
int ret_val = 0;
|
||||
|
||||
if ((RTC.RCR1 & RCR1_VAL_ON) != 0) { // RTC ON ?
|
||||
ret_val = 1;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RTC read function.
|
||||
* [in]
|
||||
* None.
|
||||
* [out]
|
||||
* UNIX timestamp value.
|
||||
*/
|
||||
time_t rtc_read(void) {
|
||||
|
||||
struct tm timeinfo;
|
||||
int err = 0;
|
||||
uint8_t tmp_regdata;
|
||||
time_t t;
|
||||
|
||||
if (rtc_isenabled() != 0) {
|
||||
RTC.RCR1 &= ~0x10u; // CIE = 0
|
||||
do {
|
||||
// before reading process
|
||||
tmp_regdata = RTC.RCR1;
|
||||
tmp_regdata &= ~0x80u; // CF = 0
|
||||
tmp_regdata |= 0x01u; // AF = 1
|
||||
RTC.RCR1 = tmp_regdata;
|
||||
|
||||
// Read RTC register
|
||||
err = rtc_dec8_to_hex(RTC.RSECCNT , 0 , &timeinfo.tm_sec);
|
||||
err += rtc_dec8_to_hex(RTC.RMINCNT , 0 , &timeinfo.tm_min);
|
||||
err += rtc_dec8_to_hex(RTC.RHRCNT , 0 , &timeinfo.tm_hour);
|
||||
err += rtc_dec8_to_hex(RTC.RDAYCNT , 0 , &timeinfo.tm_mday);
|
||||
err += rtc_dec8_to_hex(RTC.RMONCNT , 1 , &timeinfo.tm_mon);
|
||||
err += rtc_dec16_to_hex(RTC.RYRCNT , 1900 , &timeinfo.tm_year);
|
||||
} while ((RTC.RCR1 & 0x80u) != 0);
|
||||
} else {
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
// Convert to timestamp
|
||||
t = mktime(&timeinfo);
|
||||
} else {
|
||||
// Error
|
||||
t = TIME_ERROR_VAL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dec(8bit) to Hex function for RTC.
|
||||
* [in]
|
||||
* dec_val:Decimal value (from 0x00 to 0x99).
|
||||
* offset:Subtract offset from dec_val.
|
||||
* hex_val:Pointer of output hexadecimal value.
|
||||
* [out]
|
||||
* 0:Success
|
||||
* 1:Error
|
||||
*/
|
||||
static int rtc_dec8_to_hex(uint8_t dec_val, uint8_t offset, int *hex_val) {
|
||||
int err = 0;
|
||||
uint8_t ret_val;
|
||||
|
||||
if (hex_val != NULL) {
|
||||
if (((dec_val & MASK_04_07_POS) >= (0x0A << SHIFT_1_HBYTE)) ||
|
||||
((dec_val & MASK_00_03_POS) >= 0x0A)) {
|
||||
err = 1;
|
||||
} else {
|
||||
ret_val = ((dec_val & MASK_04_07_POS) >> SHIFT_1_HBYTE) * 10 +
|
||||
(dec_val & MASK_00_03_POS);
|
||||
if (ret_val < offset) {
|
||||
err = 1;
|
||||
} else {
|
||||
*hex_val = ret_val - offset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = 1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dec(16bit) to Hex function for RTC
|
||||
* [in]
|
||||
* dec_val:Decimal value (from 0x0000 to 0x9999).
|
||||
* offset:Subtract offset from dec_val.
|
||||
* hex_val:Pointer of output hexadecimal value.
|
||||
* [out]
|
||||
* 0:Success
|
||||
* 1:Error
|
||||
*/
|
||||
static int rtc_dec16_to_hex(uint16_t dec_val, uint16_t offset, int *hex_val) {
|
||||
int err = 0;
|
||||
uint16_t ret_val;
|
||||
|
||||
if (hex_val != NULL) {
|
||||
if (((dec_val & MASK_12_15_POS) >= (0x0A << SHIFT_3_HBYTE)) ||
|
||||
((dec_val & MASK_08_11_POS) >= (0x0A << SHIFT_2_HBYTE)) ||
|
||||
((dec_val & MASK_04_07_POS) >= (0x0A << SHIFT_1_HBYTE)) ||
|
||||
((dec_val & MASK_00_03_POS) >= 0x0A)) {
|
||||
err = 1;
|
||||
*hex_val = 0;
|
||||
} else {
|
||||
ret_val = (((dec_val & MASK_12_15_POS)) >> SHIFT_3_HBYTE) * 1000 +
|
||||
(((dec_val & MASK_08_11_POS)) >> SHIFT_2_HBYTE) * 100 +
|
||||
(((dec_val & MASK_04_07_POS)) >> SHIFT_1_HBYTE) * 10 +
|
||||
(dec_val & MASK_00_03_POS);
|
||||
if (ret_val < offset) {
|
||||
err = 1;
|
||||
} else {
|
||||
*hex_val = ret_val - offset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = 1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTC write function
|
||||
* [in]
|
||||
* t:UNIX timestamp value
|
||||
* [out]
|
||||
* None.
|
||||
*/
|
||||
void rtc_write(time_t t) {
|
||||
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
volatile uint16_t dummy_read;
|
||||
|
||||
if (rtc_isenabled() != 0) {
|
||||
RTC.RCR2 = RCR2_VAL_ALLSTOP;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
RTC.RCR2 = RCR2_VAL_RESET; // RESET = 1
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
|
||||
RTC.RSECCNT = rtc_hex8_to_dec(timeinfo->tm_sec);
|
||||
RTC.RMINCNT = rtc_hex8_to_dec(timeinfo->tm_min);
|
||||
RTC.RHRCNT = rtc_hex8_to_dec(timeinfo->tm_hour);
|
||||
RTC.RDAYCNT = rtc_hex8_to_dec(timeinfo->tm_mday);
|
||||
RTC.RMONCNT = rtc_hex8_to_dec(timeinfo->tm_mon + 1);
|
||||
RTC.RYRCNT = rtc_hex16_to_dec(timeinfo->tm_year + 1900);
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
|
||||
RTC.RCR2 = RCR2_VAL_START; // START = 1
|
||||
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* HEX to Dec(8bit) function for RTC.
|
||||
* [in]
|
||||
* hex_val:Hexadecimal value.
|
||||
* [out]
|
||||
* decimal value:From 0x00 to 0x99.
|
||||
*/
|
||||
static uint8_t rtc_hex8_to_dec(uint8_t hex_val) {
|
||||
uint32_t calc_data;
|
||||
|
||||
calc_data = hex_val / 10 * 0x10;
|
||||
calc_data += hex_val % 10;
|
||||
|
||||
if (calc_data > 0x99) {
|
||||
calc_data = 0;
|
||||
}
|
||||
|
||||
return (uint8_t)calc_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* HEX to Dec(16bit) function for RTC.
|
||||
* [in]
|
||||
* hex_val:Hexadecimal value.
|
||||
* [out]
|
||||
* decimal value:From 0x0000 to 0x9999.
|
||||
*/
|
||||
static uint16_t rtc_hex16_to_dec(uint16_t hex_val) {
|
||||
uint32_t calc_data;
|
||||
calc_data = hex_val / 1000 * 0x1000;
|
||||
calc_data += ((hex_val / 100) % 10) * 0x100;
|
||||
calc_data += ((hex_val / 10) % 10) * 0x10;
|
||||
calc_data += hex_val % 10;
|
||||
|
||||
if (calc_data > 0x9999) {
|
||||
calc_data = 0;
|
||||
}
|
||||
return (uint16_t)calc_data;
|
||||
|
||||
}
|
||||
|
||||
#endif /* DEVICE_RTC */
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -30,6 +30,8 @@
|
|||
/******************************************************************************
|
||||
* INITIALIZATION
|
||||
******************************************************************************/
|
||||
#define PCLK (66666666) // Define the peripheral clock P1 frequency.
|
||||
|
||||
#define UART_NUM 8
|
||||
#define IRQ_NUM 2
|
||||
|
||||
|
@ -52,35 +54,54 @@ static void uart7_rx_irq(void);
|
|||
|
||||
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{P6_3 , UART2, 7},
|
||||
{P2_14 , UART0, 6},
|
||||
{P5_0 , UART4, 5},
|
||||
{P5_3 , UART3, 5},
|
||||
{P5_6 , UART6, 5},
|
||||
{P2_5 , UART1, 6},
|
||||
{P6_3 , UART2, 7},
|
||||
{P5_3 , UART3, 5},
|
||||
{P8_8 , UART3, 7},
|
||||
{P5_0 , UART4, 5},
|
||||
{P8_14 , UART4, 7},
|
||||
{P8_13 , UART5, 5},
|
||||
{P7_4 , UART7, 4},
|
||||
{P11_10, UART5, 3},
|
||||
{P6_6 , UART5, 5},
|
||||
{P5_6 , UART6, 5},
|
||||
{P11_1 , UART6, 4},
|
||||
{P7_4 , UART7, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
{P6_2 , UART2, 7},
|
||||
{P2_15 , UART0, 6},
|
||||
{P5_1 , UART4, 5},
|
||||
{P5_4 , UART3, 5},
|
||||
{P5_7 , UART6, 5},
|
||||
{P2_6 , UART1, 6},
|
||||
{P6_2 , UART2, 7},
|
||||
{P5_4 , UART3, 5},
|
||||
{P8_9 , UART3, 7},
|
||||
{P5_1 , UART4, 5},
|
||||
{P8_15 , UART4, 7},
|
||||
{P8_11 , UART5, 5},
|
||||
{P7_5 , UART7, 4},
|
||||
{P11_11, UART5, 3},
|
||||
{P6_7 , UART5, 5},
|
||||
{P5_7 , UART6, 5},
|
||||
{P11_2 , UART6, 4},
|
||||
{P7_5 , UART7, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_CTS[] = {
|
||||
{P2_3 , UART1, 6},
|
||||
{P11_7 , UART5, 3},
|
||||
{P7_6 , UART7, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
static const PinMap PinMap_UART_RTS[] = {
|
||||
{P2_7 , UART1, 6},
|
||||
{P11_8 , UART5, 3},
|
||||
{P7_7 , UART7, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const struct st_scif *SCIF[] = SCIF_ADDRESS_LIST;
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
|
@ -141,7 +162,7 @@ static __IO uint16_t *SCFSR_MATCH[] = {
|
|||
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
volatile uint8_t dummy ;
|
||||
volatile uint8_t dummy ;
|
||||
int is_stdio_uart = 0;
|
||||
// determine the UART to use
|
||||
uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
|
||||
|
@ -153,14 +174,30 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
obj->uart = (struct st_scif *)SCIF[uart];
|
||||
// enable power
|
||||
switch (uart) {
|
||||
case UART0: CPG.STBCR4 &= ~(1 << 7); break;
|
||||
case UART1: CPG.STBCR4 &= ~(1 << 6); break;
|
||||
case UART2: CPG.STBCR4 &= ~(1 << 5); break;
|
||||
case UART3: CPG.STBCR4 &= ~(1 << 4); break;
|
||||
case UART4: CPG.STBCR4 &= ~(1 << 3); break;
|
||||
case UART5: CPG.STBCR4 &= ~(1 << 2); break;
|
||||
case UART6: CPG.STBCR4 &= ~(1 << 1); break;
|
||||
case UART7: CPG.STBCR4 &= ~(1 << 0); break;
|
||||
case UART0:
|
||||
CPG.STBCR4 &= ~(1 << 7);
|
||||
break;
|
||||
case UART1:
|
||||
CPG.STBCR4 &= ~(1 << 6);
|
||||
break;
|
||||
case UART2:
|
||||
CPG.STBCR4 &= ~(1 << 5);
|
||||
break;
|
||||
case UART3:
|
||||
CPG.STBCR4 &= ~(1 << 4);
|
||||
break;
|
||||
case UART4:
|
||||
CPG.STBCR4 &= ~(1 << 3);
|
||||
break;
|
||||
case UART5:
|
||||
CPG.STBCR4 &= ~(1 << 2);
|
||||
break;
|
||||
case UART6:
|
||||
CPG.STBCR4 &= ~(1 << 1);
|
||||
break;
|
||||
case UART7:
|
||||
CPG.STBCR4 &= ~(1 << 0);
|
||||
break;
|
||||
}
|
||||
dummy = CPG.STBCR4;
|
||||
|
||||
|
@ -181,7 +218,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
/* ORER bit clear */
|
||||
obj->uart->SCLSR = 0;
|
||||
|
||||
/* ---- Serial extension mode register (SCEMR) setting ----
|
||||
/* ---- 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;
|
||||
|
@ -193,26 +230,49 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
/* ---- FIFO control register (SCFCR) setting ---- */
|
||||
obj->uart->SCFCR = 0x0030u;
|
||||
|
||||
/* ---- Serial port register (SCSPTR) setting ----
|
||||
/* ---- 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->SCSPTR = 0x0003u; // SPB2IO = 1, SPB2DT = 1
|
||||
|
||||
obj->uart->SCSCR = 0x00F0;
|
||||
|
||||
/* ---- Line status register (SCLSR) setting ----
|
||||
b0 ORER - Overrun error detect : clear */
|
||||
|
||||
if (obj->uart->SCLSR & 0x0001) {
|
||||
obj->uart->SCLSR = 0u; // ORER clear
|
||||
}
|
||||
|
||||
// pinout the chosen uart
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
|
||||
switch (uart) {
|
||||
case UART0: obj->index = 0; break;
|
||||
case UART1: obj->index = 1; break;
|
||||
case UART2: obj->index = 2; break;
|
||||
case UART3: obj->index = 3; break;
|
||||
case UART4: obj->index = 4; break;
|
||||
case UART5: obj->index = 5; break;
|
||||
case UART6: obj->index = 6; break;
|
||||
case UART7: obj->index = 7; break;
|
||||
case UART0:
|
||||
obj->index = 0;
|
||||
break;
|
||||
case UART1:
|
||||
obj->index = 1;
|
||||
break;
|
||||
case UART2:
|
||||
obj->index = 2;
|
||||
break;
|
||||
case UART3:
|
||||
obj->index = 3;
|
||||
break;
|
||||
case UART4:
|
||||
obj->index = 4;
|
||||
break;
|
||||
case UART5:
|
||||
obj->index = 5;
|
||||
break;
|
||||
case UART6:
|
||||
obj->index = 6;
|
||||
break;
|
||||
case UART7:
|
||||
obj->index = 7;
|
||||
break;
|
||||
}
|
||||
uart_data[obj->index].sw_rts.pin = NC;
|
||||
uart_data[obj->index].sw_cts.pin = NC;
|
||||
|
@ -232,13 +292,52 @@ void serial_free(serial_t *obj) {
|
|||
// serial_baud
|
||||
// set the baud rate, taking in to account the current SystemFrequency
|
||||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
uint16_t DL;
|
||||
|
||||
uint32_t PCLK = 66666666;
|
||||
obj->uart->SCSMR &= ~0x0003;
|
||||
|
||||
uint16_t DL = (PCLK / (32 * baudrate)) -1;
|
||||
|
||||
// set LCR[DLAB] to enable writing to divider registers
|
||||
obj->uart->SCBRR = DL;
|
||||
if (baudrate > 32552) {
|
||||
obj->uart->SCEMR = 0x0081; // BGDM = 1, ABCS = 1
|
||||
DL = PCLK / (8 * baudrate);
|
||||
if (DL > 0) {
|
||||
DL--;
|
||||
}
|
||||
obj->uart->SCBRR = (uint8_t)DL;
|
||||
} else if (baudrate > 16276) {
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (16 * baudrate) - 1;
|
||||
} else if (baudrate > 8138) {
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (32 * baudrate) - 1;
|
||||
} else if (baudrate > 4169) {
|
||||
obj->uart->SCSMR |= 0x0001;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (64 * baudrate) - 1;
|
||||
} else if (baudrate > 2034) {
|
||||
obj->uart->SCSMR |= 0x0001;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (128 * baudrate) - 1;
|
||||
} else if (baudrate > 1017) {
|
||||
obj->uart->SCSMR |= 0x0002;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (256 * baudrate) - 1;
|
||||
} else if (baudrate > 508) {
|
||||
obj->uart->SCSMR |= 0x0002;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (512 * baudrate) - 1;
|
||||
} else if (baudrate > 254) {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (1024 * baudrate) - 1;
|
||||
} else if (baudrate > 127) {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (2048 * baudrate) - 1;
|
||||
} else {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = 0xFFu;
|
||||
}
|
||||
}
|
||||
|
||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||
|
@ -246,9 +345,9 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
int parity_select;
|
||||
|
||||
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((data_bits > 4) && (data_bits < 9)); // 5: 5 data bits ... 3: 8 data bits
|
||||
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
|
||||
(parity == ParityForced1) || (parity == ParityForced0));
|
||||
(parity == ParityForced1) || (parity == ParityForced0));
|
||||
|
||||
stop_bits = (stop_bits == 1)? 0:
|
||||
(stop_bits == 2)? 1:
|
||||
|
@ -259,28 +358,30 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
0; // must not to be
|
||||
|
||||
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;
|
||||
case ParityNone:
|
||||
parity_enable = 0;
|
||||
parity_select = 0;
|
||||
break;
|
||||
case ParityOdd:
|
||||
parity_enable = 1;
|
||||
parity_select = 1;
|
||||
break;
|
||||
case ParityEven:
|
||||
parity_enable = 1;
|
||||
parity_select = 0;
|
||||
break;
|
||||
case ParityForced1:
|
||||
case ParityForced0:
|
||||
default:
|
||||
parity_enable = 0;
|
||||
parity_select = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
obj->uart->SCSMR = data_bits << 6
|
||||
| parity_enable << 5
|
||||
| parity_select << 4
|
||||
| stop_bits << 3;
|
||||
| parity_enable << 5
|
||||
| parity_select << 4
|
||||
| stop_bits << 3;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -312,23 +413,55 @@ static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) {
|
|||
}
|
||||
|
||||
/* TX handler */
|
||||
static void uart0_tx_irq(void) {uart_tx_irq(SCIFTXI0_IRQn, 0);}
|
||||
static void uart1_tx_irq(void) {uart_tx_irq(SCIFTXI1_IRQn, 1);}
|
||||
static void uart2_tx_irq(void) {uart_tx_irq(SCIFTXI2_IRQn, 2);}
|
||||
static void uart3_tx_irq(void) {uart_tx_irq(SCIFTXI3_IRQn, 3);}
|
||||
static void uart4_tx_irq(void) {uart_tx_irq(SCIFTXI4_IRQn, 4);}
|
||||
static void uart5_tx_irq(void) {uart_tx_irq(SCIFTXI5_IRQn, 5);}
|
||||
static void uart6_tx_irq(void) {uart_tx_irq(SCIFTXI6_IRQn, 6);}
|
||||
static void uart7_tx_irq(void) {uart_tx_irq(SCIFTXI7_IRQn, 7);}
|
||||
static void uart0_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI0_IRQn, 0);
|
||||
}
|
||||
static void uart1_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI1_IRQn, 1);
|
||||
}
|
||||
static void uart2_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI2_IRQn, 2);
|
||||
}
|
||||
static void uart3_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI3_IRQn, 3);
|
||||
}
|
||||
static void uart4_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI4_IRQn, 4);
|
||||
}
|
||||
static void uart5_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI5_IRQn, 5);
|
||||
}
|
||||
static void uart6_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI6_IRQn, 6);
|
||||
}
|
||||
static void uart7_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI7_IRQn, 7);
|
||||
}
|
||||
/* RX handler */
|
||||
static void uart0_rx_irq(void) {uart_rx_irq(SCIFRXI0_IRQn, 0);}
|
||||
static void uart1_rx_irq(void) {uart_rx_irq(SCIFRXI1_IRQn, 1);}
|
||||
static void uart2_rx_irq(void) {uart_rx_irq(SCIFRXI2_IRQn, 2);}
|
||||
static void uart3_rx_irq(void) {uart_rx_irq(SCIFRXI3_IRQn, 3);}
|
||||
static void uart4_rx_irq(void) {uart_rx_irq(SCIFRXI4_IRQn, 4);}
|
||||
static void uart5_rx_irq(void) {uart_rx_irq(SCIFRXI5_IRQn, 5);}
|
||||
static void uart6_rx_irq(void) {uart_rx_irq(SCIFRXI6_IRQn, 6);}
|
||||
static void uart7_rx_irq(void) {uart_rx_irq(SCIFRXI7_IRQn, 7);}
|
||||
static void uart0_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI0_IRQn, 0);
|
||||
}
|
||||
static void uart1_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI1_IRQn, 1);
|
||||
}
|
||||
static void uart2_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI2_IRQn, 2);
|
||||
}
|
||||
static void uart3_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI3_IRQn, 3);
|
||||
}
|
||||
static void uart4_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI4_IRQn, 4);
|
||||
}
|
||||
static void uart5_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI5_IRQn, 5);
|
||||
}
|
||||
static void uart6_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI6_IRQn, 6);
|
||||
}
|
||||
static void uart7_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI7_IRQn, 7);
|
||||
}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
|
@ -369,42 +502,79 @@ static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
|
|||
* READ/WRITE
|
||||
******************************************************************************/
|
||||
int serial_getc(serial_t *obj) {
|
||||
uint16_t dummy_read;
|
||||
uint16_t err_read;
|
||||
int data;
|
||||
int was_masked;
|
||||
|
||||
was_masked = __disable_irq();
|
||||
if (obj->uart->SCFSR & 0x93) {
|
||||
dummy_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (dummy_read & ~0x93);
|
||||
err_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (err_read & ~0x93);
|
||||
}
|
||||
obj->uart->SCSCR |= 0x0040; // Set RIE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
if (obj->uart->SCLSR & 0x0001) {
|
||||
obj->uart->SCLSR = 0u; // ORER clear
|
||||
}
|
||||
|
||||
while (!serial_readable(obj));
|
||||
data = obj->uart->SCFRDR & 0xff;
|
||||
obj->uart->SCFSR &= 0xfffc; // Clear DR,RDF
|
||||
|
||||
was_masked = __disable_irq();
|
||||
err_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (err_read & 0xfffD); // Clear RDF
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
if (err_read & 0x80) {
|
||||
data = -1; //err
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void serial_putc(serial_t *obj, int c) {
|
||||
uint16_t dummy_read;
|
||||
|
||||
int was_masked;
|
||||
|
||||
was_masked = __disable_irq();
|
||||
obj->uart->SCSCR |= 0x0080; // Set TIE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
while (!serial_writable(obj));
|
||||
obj->uart->SCFTDR = c;
|
||||
was_masked = __disable_irq();
|
||||
dummy_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (dummy_read & 0xff9f); // Clear TEND/TDFE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
uart_data[obj->index].count++;
|
||||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
return obj->uart->SCFSR & 0x02; // RDF
|
||||
return ((obj->uart->SCFSR & 0x02) != 0); // RDF
|
||||
}
|
||||
|
||||
int serial_writable(serial_t *obj) {
|
||||
return obj->uart->SCFSR & 0x20; // TDFE
|
||||
return ((obj->uart->SCFSR & 0x20) != 0); // TDFE
|
||||
}
|
||||
|
||||
void serial_clear(serial_t *obj) {
|
||||
obj->uart->SCFCR = 0x06;
|
||||
obj->uart->SCFCR = 0x06;
|
||||
int was_masked;
|
||||
was_masked = __disable_irq();
|
||||
|
||||
obj->uart->SCFCR |= 0x06; // TFRST = 1, RFRST = 1
|
||||
obj->uart->SCFCR &= ~0x06; // TFRST = 0, RFRST = 0
|
||||
obj->uart->SCFSR &= ~0x0093u; // ER, BRK, RDF, DR = 0
|
||||
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void serial_pinout_tx(PinName tx) {
|
||||
|
@ -412,12 +582,49 @@ void serial_pinout_tx(PinName tx) {
|
|||
}
|
||||
|
||||
void serial_break_set(serial_t *obj) {
|
||||
int was_masked;
|
||||
was_masked = __disable_irq();
|
||||
// TxD Output(L)
|
||||
obj->uart->SCSPTR &= ~0x0001u; // SPB2DT = 0
|
||||
obj->uart->SCSCR &= ~0x0020u; // TE = 0 (Output disable)
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void serial_break_clear(serial_t *obj) {
|
||||
int was_masked;
|
||||
was_masked = __disable_irq();
|
||||
obj->uart->SCSCR |= 0x0020u; // TE = 1 (Output enable)
|
||||
obj->uart->SCSPTR |= 0x0001u; // SPB2DT = 1
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
|
||||
// determine the UART to use
|
||||
int was_masked;
|
||||
|
||||
serial_flow_irq_set(obj, 0);
|
||||
|
||||
if (type == FlowControlRTSCTS) {
|
||||
was_masked = __disable_irq();
|
||||
obj->uart->SCFCR = 0x0008u; // CTS/RTS enable
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
pinmap_pinout(rxflow, PinMap_UART_RTS);
|
||||
pinmap_pinout(txflow, PinMap_UART_CTS);
|
||||
} else {
|
||||
was_masked = __disable_irq();
|
||||
obj->uart->SCFCR = 0x0000u; // CTS/RTS diable
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -61,9 +61,12 @@ void us_ticker_init(void) {
|
|||
GIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read() {
|
||||
uint64_t us_ticker_read64() {
|
||||
uint32_t val;
|
||||
uint64_t val64;
|
||||
volatile uint64_t val64;
|
||||
int check_irq_masked;
|
||||
|
||||
check_irq_masked = __disable_irq();
|
||||
|
||||
if (!us_ticker_inited)
|
||||
us_ticker_init();
|
||||
|
@ -77,14 +80,50 @@ uint32_t us_ticker_read() {
|
|||
val64 = ((uint64_t)wrap_arround << 32) + val;
|
||||
|
||||
/* clock to us */
|
||||
val = (uint32_t)(val64 / count_clock);
|
||||
return val;
|
||||
val64 = val64 / count_clock;
|
||||
|
||||
if (!check_irq_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
return val64;
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read() {
|
||||
return (uint32_t)us_ticker_read64();
|
||||
}
|
||||
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp) {
|
||||
// set match value
|
||||
timestamp = (timestamp_t)(timestamp * count_clock);
|
||||
OSTM1CMP = (uint32_t)(timestamp & 0xffffffff);
|
||||
volatile uint64_t set_cmp_val = 0;
|
||||
uint64_t timestamp_tmp;
|
||||
int64_t timestamp_req;
|
||||
int64_t timestamp_comp;
|
||||
uint64_t timestamp_now = us_ticker_read64();
|
||||
|
||||
/* calc compare mach timestamp */
|
||||
set_cmp_val = (timestamp_now & 0xFFFFFFFF00000000) + timestamp;
|
||||
|
||||
timestamp_tmp = (uint64_t)timestamp;
|
||||
timestamp_req = (int64_t)timestamp_tmp;
|
||||
|
||||
timestamp_tmp = (uint64_t)(timestamp_now & 0x00000000FFFFFFFF);
|
||||
timestamp_comp = (int64_t)timestamp_tmp;
|
||||
|
||||
if (timestamp_req <= timestamp_comp + 1) {
|
||||
if (((timestamp_req - timestamp_comp) <= 1) && ((timestamp_req - timestamp_comp) >= -10)) {
|
||||
/* This event was in the past */
|
||||
us_ticker_irq_handler();
|
||||
return;
|
||||
} else {
|
||||
/* This event is wrap arround */
|
||||
set_cmp_val += 0x100000000;
|
||||
}
|
||||
}
|
||||
|
||||
/* calc compare mach timestamp */
|
||||
set_cmp_val = set_cmp_val * count_clock;
|
||||
OSTM1CMP = (uint32_t)(set_cmp_val & 0xffffffff);
|
||||
GIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue