Merge pull request #875 from masaohamanaka/master

RZ_A1H - Add some function and fix some bugs.
pull/879/head
Martin Kojtal 2015-02-02 11:24:46 +00:00
commit c53fab9e3c
9 changed files with 993 additions and 266 deletions

View File

@ -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
}

View File

@ -44,7 +44,7 @@
#define DEVICE_CAN 0
#define DEVICE_RTC 0
#define DEVICE_RTC 1
#define DEVICE_ETHERNET 1

View File

@ -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);

View File

@ -16,6 +16,8 @@
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#include "mbed_assert.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -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;
}

View File

@ -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 {

View File

@ -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 */

View File

@ -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();
}
}
}

View File

@ -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);
}