mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #802 from masaohamanaka/master
Targets: RZ_A1H - Fix some drivers bugs and modify some settings of OS andpull/806/head^2
commit
078c36b1c5
|
@ -28,6 +28,10 @@ typedef enum {
|
|||
UART1,
|
||||
UART2,
|
||||
UART3,
|
||||
UART4,
|
||||
UART5,
|
||||
UART6,
|
||||
UART7,
|
||||
} UARTName;
|
||||
|
||||
// PWMType & 1 == 1 then have to use PWDTR[12] == 1
|
||||
|
@ -93,7 +97,7 @@ typedef enum {
|
|||
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART P_SCIF2
|
||||
#define STDIO_UART UART2
|
||||
|
||||
// Default peripherals
|
||||
#define MBED_SPI0 p5, p6, p7, p8
|
||||
|
|
|
@ -269,7 +269,7 @@ void ethernetext_set_link_mode(int32_t link) {
|
|||
int ethernet_init() {
|
||||
ethernet_cfg_t ethcfg;
|
||||
|
||||
ethcfg.int_priority = 0;
|
||||
ethcfg.int_priority = 5;
|
||||
ethcfg.recv_cb = NULL;
|
||||
ethcfg.ether_mac = NULL;
|
||||
ethernetext_init(ðcfg);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "i2c_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
#include "r_typedefs.h"
|
||||
|
||||
#include "riic_iodefine.h"
|
||||
#include "RZ_A1_Init.h"
|
||||
|
@ -28,7 +28,29 @@ volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
|
|||
#define REG(N) \
|
||||
RIIC[obj->i2c]->RIICn##N
|
||||
|
||||
#define NACKF (1 << 4)
|
||||
/* RIICnCR1 */
|
||||
#define CR1_RST (1 << 6)
|
||||
#define CR1_ICE (1 << 7)
|
||||
|
||||
/* RIICnCR2 */
|
||||
#define CR2_ST (1 << 1)
|
||||
#define CR2_SP (1 << 3)
|
||||
#define CR2_NACKF (1 << 4)
|
||||
#define CR2_BBSY (1 << 7)
|
||||
|
||||
/* RIICnMR3 */
|
||||
#define MR3_ACKBT (1 << 3)
|
||||
#define MR3_ACKWP (1 << 4)
|
||||
#define MR3_WAIT (1 << 6)
|
||||
|
||||
/* RIICnSR2 */
|
||||
#define SR2_STOP (1 << 3)
|
||||
#define SR2_NACKF (1 << 4)
|
||||
#define SR2_RDRF (1 << 5)
|
||||
#define SR2_TEND (1 << 6)
|
||||
#define SR2_TDRE (1 << 7)
|
||||
|
||||
#define TIMEOUT_1S (3600000) /* Loop counter : Time-out is about 1s. By 3600000 loops, measured value is 969ms. */
|
||||
|
||||
static const PinMap PinMap_I2C_SDA[] = {
|
||||
{P1_1 , I2C_0, 1},
|
||||
|
@ -44,7 +66,8 @@ static const PinMap PinMap_I2C_SCL[] = {
|
|||
{NC , NC, 0}
|
||||
};
|
||||
|
||||
// Clear the Transmit data Empty TDRE
|
||||
|
||||
/* 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;
|
||||
|
@ -56,54 +79,70 @@ static inline int i2c_status(i2c_t *obj) {
|
|||
}
|
||||
|
||||
static inline void i2c_clear_TDRE(i2c_t *obj) {
|
||||
REG(SR2.UINT32) &= ~(1 << 7);
|
||||
REG(SR2.UINT32) &= ~SR2_TDRE;
|
||||
}
|
||||
|
||||
static inline void i2c_wait_RDRF(i2c_t *obj) {
|
||||
while (!(i2c_status(obj) & (1 << 5))) ;
|
||||
}
|
||||
|
||||
static void i2c_reg_reset(i2c_t *obj) {
|
||||
// full reset
|
||||
REG(CR1.UINT8[0]) &= ~(1 << 7); // CR1.ICE off
|
||||
REG(CR1.UINT8[0]) |= (1 << 6); // CR1.IICRST on
|
||||
REG(CR1.UINT8[0]) |= (1 << 7); // CR1.ICE on
|
||||
|
||||
REG(MR1.UINT8[0]) = 0x08; // P_phi /8 9bit (including Ack)
|
||||
REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
|
||||
|
||||
// set frequency
|
||||
REG(MR1.UINT8[0]) |= obj->pclk_bit;
|
||||
REG(BRL.UINT32) = obj->width;
|
||||
REG(BRH.UINT32) = obj->width;
|
||||
|
||||
REG(MR2.UINT8[0]) = 0x07;
|
||||
REG(MR3.UINT8[0]) = 0x00;
|
||||
|
||||
REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT
|
||||
REG(IER.UINT8[0]) = 0x00; // no interrupt
|
||||
|
||||
REG(CR1.UINT32) &= ~(1 << 6); // CR1.IICRST negate reset
|
||||
}
|
||||
|
||||
// Wait until the Trans Data Empty (TDRE) is set
|
||||
static int i2c_wait_TDRE(i2c_t *obj) {
|
||||
static inline int i2c_wait_RDRF(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
while (!(i2c_status(obj) & (1 << 7))) {
|
||||
|
||||
/* 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 > 100000) return -1;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int i2c_wait_TEND(i2c_t *obj) {
|
||||
static void i2c_reg_reset(i2c_t *obj) {
|
||||
/* full reset */
|
||||
REG(CR1.UINT8[0]) &= ~CR1_ICE; // CR1.ICE off
|
||||
REG(CR1.UINT8[0]) |= CR1_RST; // CR1.IICRST on
|
||||
REG(CR1.UINT8[0]) |= CR1_ICE; // CR1.ICE on
|
||||
|
||||
REG(MR1.UINT8[0]) = 0x08; // P_phi /x 9bit (including Ack)
|
||||
REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
|
||||
|
||||
/* set frequency */
|
||||
REG(MR1.UINT8[0]) |= obj->pclk_bit;
|
||||
REG(BRL.UINT8[0]) = obj->width_low;
|
||||
REG(BRH.UINT8[0]) = obj->width_hi;
|
||||
|
||||
REG(MR2.UINT8[0]) = 0x07;
|
||||
REG(MR3.UINT8[0]) = 0x00;
|
||||
|
||||
REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT
|
||||
REG(IER.UINT8[0]) = 0x00; // no interrupt
|
||||
|
||||
REG(CR1.UINT32) &= ~CR1_RST; // CR1.IICRST negate reset
|
||||
}
|
||||
|
||||
/* Wait until the Trans Data Empty (TDRE) is set */
|
||||
static int i2c_wait_TDRE(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
while (!(i2c_status(obj) & (1 << 6))) {
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_TDRE)) {
|
||||
timeout ++;
|
||||
if (timeout > 100000) return -1;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_wait_TEND(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_TEND)) {
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -111,21 +150,31 @@ static inline int i2c_wait_TEND(i2c_t *obj) {
|
|||
|
||||
|
||||
static int i2c_wait_STOP(i2c_t *obj) {
|
||||
volatile uint32_t work_reg;
|
||||
|
||||
/* wait SR2.STOP = 1 */
|
||||
work_reg = REG(SR2.UINT32);
|
||||
while ((work_reg & (1 << 3)) == 0) {
|
||||
work_reg = REG(SR2.UINT32);
|
||||
}
|
||||
/* SR2.NACKF = 0 */
|
||||
REG(SR2.UINT32) &= ~(1 << 4);
|
||||
/* SR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~(1 << 3);
|
||||
int timeout = 0;
|
||||
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_STOP)) {
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_set_NACKF_STOP(i2c_t *obj) {
|
||||
/* SR2.NACKF = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_NACKF;
|
||||
/* 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 inline void i2c_power_enable(i2c_t *obj) {
|
||||
volatile uint8_t dummy;
|
||||
|
@ -139,140 +188,193 @@ static inline void i2c_power_enable(i2c_t *obj) {
|
|||
}
|
||||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||
// determine the SPI to use
|
||||
/* determine the I2C to use */
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT((int)obj->i2c != NC);
|
||||
|
||||
// enable power
|
||||
/* enable power */
|
||||
i2c_power_enable(obj);
|
||||
|
||||
// set default frequency at 100k
|
||||
/* set default frequency at 100k */
|
||||
i2c_frequency(obj, 100000);
|
||||
|
||||
// full reset
|
||||
i2c_reg_reset(obj);
|
||||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check
|
||||
return 0xff;
|
||||
}
|
||||
REG(CR2.UINT8[0]) |= 0x02; // start
|
||||
int timeout = 0;
|
||||
|
||||
return 0x10;
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* Start Condition */
|
||||
REG(CR2.UINT8[0]) |= CR2_ST;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj) {
|
||||
/* SR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~(1 << 3);
|
||||
// write the stop bit
|
||||
REG(CR2.UINT32) |= (1 << 3);
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
/* Stop condition */
|
||||
REG(CR2.UINT32) |= CR2_SP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int i2c_do_write(i2c_t *obj, int value) {
|
||||
// write the data
|
||||
if (!(i2c_status(obj) & NACKF)) { // NACF=0
|
||||
i2c_wait_TDRE(obj);
|
||||
int timeout = 0;
|
||||
|
||||
if (!(i2c_status(obj) & SR2_NACKF)) {
|
||||
/* RIICnSR2.NACKF=0 */
|
||||
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
|
||||
while (!(i2c_status(obj) & SR2_TDRE)) {
|
||||
/* RIICnSR2.TDRE=0 */
|
||||
timeout ++;
|
||||
if (timeout >= TIMEOUT_1S) {
|
||||
return -1;
|
||||
}
|
||||
if (i2c_status(obj) & SR2_NACKF) {
|
||||
/* RIICnSR2.NACKF=1 */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* write the data */
|
||||
REG(DRT.UINT32) = value;
|
||||
} else {
|
||||
return 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return i2c_status(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline int i2c_do_read(i2c_t *obj, int last) {
|
||||
if (obj->dummy) {
|
||||
volatile int dummy = REG(DRR.UINT32);
|
||||
obj->dummy = 0;
|
||||
}
|
||||
|
||||
// wait for it to arrive
|
||||
i2c_wait_RDRF(obj);
|
||||
|
||||
if (last == 2) {
|
||||
/* this time is befor last byte read */
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
REG(MR3.UINT32) |= (1 << 6);
|
||||
/* Set MR3 WAIT bit is 1 */;
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
} else if (last == 1) {
|
||||
// send a NOT ACK
|
||||
REG(MR3.UINT32) |= (1 <<4);
|
||||
REG(MR3.UINT32) |= (1 <<3);
|
||||
REG(MR3.UINT32) &= ~(1 <<4);
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
} else {
|
||||
// send a ACK
|
||||
REG(MR3.UINT32) |= (1 <<4);
|
||||
REG(MR3.UINT32) &= ~(1 <<3);
|
||||
REG(MR3.UINT32) &= ~(1 <<4);
|
||||
/* send a ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
}
|
||||
|
||||
// return the data
|
||||
/* return the data */
|
||||
return (REG(DRR.UINT32) & 0xFF);
|
||||
}
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz) {
|
||||
int freq;
|
||||
int oldfreq = 0;
|
||||
int newfreq = 0;
|
||||
uint32_t pclk;
|
||||
uint32_t pclk_base;
|
||||
uint32_t tmp_width;
|
||||
uint32_t width = 0;
|
||||
uint8_t count;
|
||||
uint8_t pclk_bit = 0;
|
||||
float64_t pclk_val;
|
||||
float64_t wait_utime;
|
||||
volatile float64_t bps;
|
||||
volatile float64_t L_time; /* H Width period */
|
||||
volatile float64_t H_time; /* L Width period */
|
||||
uint32_t tmp_L_width;
|
||||
uint32_t tmp_H_width;
|
||||
uint32_t remainder;
|
||||
uint32_t wk_cks = 0;
|
||||
|
||||
/* set PCLK */
|
||||
if (false == RZ_A1_IsClockMode0()) {
|
||||
pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK;
|
||||
pclk_val = (float64_t)CM1_RENESAS_RZ_A1_P0_CLK;
|
||||
} else {
|
||||
pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK;
|
||||
pclk_val = (float64_t)CM0_RENESAS_RZ_A1_P0_CLK;
|
||||
}
|
||||
|
||||
/* Min 10kHz, Max 400kHz */
|
||||
if (hz < 10000) {
|
||||
freq = 10000;
|
||||
bps = 10000;
|
||||
} else if (hz > 400000) {
|
||||
freq = 400000;
|
||||
bps = 400000;
|
||||
} else {
|
||||
freq = hz;
|
||||
bps = (float64_t)hz;
|
||||
}
|
||||
|
||||
for (count = 0; count < 7; count++) {
|
||||
// IIC phi = P0 phi / rate
|
||||
pclk = pclk_base / (2 << count);
|
||||
// In case of "CLE = 1, NFE = 1, CKS != 000( IIC phi < P0 phi ), nf = 1"
|
||||
// freq = 1 / {[( BRH + 2 + 1 ) + ( BRL + 2 + 1 )] / pclk }
|
||||
// BRH is regarded as same value with BRL
|
||||
// 2( BRH + 3 ) / pclk = 1 / freq
|
||||
tmp_width = ((pclk / freq) / 2) - 3;
|
||||
// Carry in a decimal point
|
||||
tmp_width += 1;
|
||||
if ((tmp_width >= 0x00000001) && (tmp_width <= 0x0000001F)) {
|
||||
// Calculate theoretical value, and Choose max value of them
|
||||
newfreq = pclk / (tmp_width + 3) / 2;
|
||||
if (newfreq >= oldfreq) {
|
||||
oldfreq = newfreq;
|
||||
width = tmp_width;
|
||||
pclk_bit = (uint8_t)(0x10 * (count + 1));
|
||||
}
|
||||
/* Calculation L width time */
|
||||
L_time = (1 / (2 * bps)); /* Harf period of frequency */
|
||||
H_time = L_time;
|
||||
|
||||
/* Check I2C mode of Speed */
|
||||
if (bps > 100000) {
|
||||
/* Fast-mode */
|
||||
L_time -= 102E-9; /* Falling time of SCL clock. */
|
||||
H_time -= 138E-9; /* Rising time of SCL clock. */
|
||||
/* Check L wideth */
|
||||
if (L_time < 1.3E-6) {
|
||||
/* Wnen L width less than 1.3us */
|
||||
/* Subtract Rise up and down time for SCL from H/L width */
|
||||
L_time = 1.3E-6;
|
||||
H_time = (1 / bps) - L_time - 138E-9 - 102E-9;
|
||||
}
|
||||
}
|
||||
|
||||
if (width != 0) {
|
||||
// I2C Rate
|
||||
obj->pclk_bit = pclk_bit; // P_phi / xx
|
||||
obj->width = (width | 0x000000E0);
|
||||
} else {
|
||||
// Default
|
||||
obj->pclk_bit = 0x00; // P_phi / 1
|
||||
obj->width = 0x000000FF;
|
||||
tmp_L_width = (uint32_t)(L_time * pclk_val * 10);
|
||||
tmp_L_width >>= 1;
|
||||
wk_cks++;
|
||||
while (tmp_L_width >= 341) {
|
||||
tmp_L_width >>= 1;
|
||||
wk_cks++;
|
||||
}
|
||||
remainder = tmp_L_width % 10;
|
||||
tmp_L_width = ((tmp_L_width + 9) / 10) - 3; /* carry */
|
||||
|
||||
tmp_H_width = (uint32_t)(H_time * pclk_val * 10);
|
||||
tmp_H_width >>= wk_cks;
|
||||
if (remainder == 0) {
|
||||
tmp_H_width = ((tmp_H_width + 9) / 10) - 3; /* carry */
|
||||
} else {
|
||||
remainder += tmp_H_width % 10;
|
||||
tmp_H_width = (tmp_H_width / 10) - 3;
|
||||
if (remainder > 10) {
|
||||
tmp_H_width += 1; /* fine adjustment */
|
||||
}
|
||||
}
|
||||
/* timeout of BBSY bit is minimum low width by frequency */
|
||||
/* so timeout calculates "(low width) * 2" by frequency */
|
||||
wait_utime = (L_time * 2) * 1000000;
|
||||
/* 1 wait of BBSY bit is about 0.3us. if it's below 0.3us, wait count is set as 1. */
|
||||
if (wait_utime <= 0.3) {
|
||||
obj->bbsy_wait_cnt = 1;
|
||||
} else {
|
||||
obj->bbsy_wait_cnt = (int)(wait_utime / 0.3);
|
||||
}
|
||||
|
||||
|
||||
/* I2C Rate */
|
||||
obj->pclk_bit = (uint8_t)(0x10 * wk_cks); /* P_phi / xx */
|
||||
obj->width_low = (uint8_t)(tmp_L_width | 0x000000E0);
|
||||
obj->width_hi = (uint8_t)(tmp_H_width | 0x000000E0);
|
||||
|
||||
/* full reset */
|
||||
i2c_reg_reset(obj);
|
||||
}
|
||||
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
||||
|
@ -281,40 +383,41 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
int value;
|
||||
volatile uint32_t work_reg = 0;
|
||||
|
||||
// full reset
|
||||
i2c_reg_reset(obj);
|
||||
obj->dummy = 1;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if (status == 0xff) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
status = i2c_do_write(obj, (address | 0x01));
|
||||
if (status & 0x01) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
/* Send Slave address */
|
||||
status = i2c_read_address_write(obj, (address | 0x01));
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
/* wati RDRF */
|
||||
i2c_wait_RDRF(obj);
|
||||
status = i2c_wait_RDRF(obj);
|
||||
/* check ACK/NACK */
|
||||
if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
|
||||
if ((status != 0) || (REG(SR2.UINT32) & CR2_NACKF == 1)) {
|
||||
/* Slave sends NACK */
|
||||
i2c_stop(obj);
|
||||
// dummy read
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
i2c_wait_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
// Read in all except last byte
|
||||
/* Read in all except last byte */
|
||||
if (length > 2) {
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
for (count = 0; count < (length - 1); count++) {
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* Recieve the data */
|
||||
if (count == (length - 2)) {
|
||||
value = i2c_do_read(obj, 1);
|
||||
} else if ((length >= 3) && (count == (length - 3))) {
|
||||
|
@ -322,124 +425,113 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
} else {
|
||||
value = i2c_do_read(obj, 0);
|
||||
}
|
||||
status = i2c_status(obj);
|
||||
if (status & 0x10) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
return count;
|
||||
}
|
||||
data[count] = (char) value;
|
||||
data[count] = (char)value;
|
||||
}
|
||||
} else if (length == 2) {
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
REG(MR3.UINT32) |= (1 << 6);
|
||||
// dummy read
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
// wait for it to arrive
|
||||
i2c_wait_RDRF(obj);
|
||||
// send a NOT ACK
|
||||
REG(MR3.UINT32) |= (1 <<4);
|
||||
REG(MR3.UINT32) |= (1 <<3);
|
||||
REG(MR3.UINT32) &= ~(1 <<4);
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
data[count] = (char)REG(DRR.UINT32);
|
||||
count++;
|
||||
} else if (length == 1) {
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
REG(MR3.UINT32) |= (1 << 6);
|
||||
// send a NOT ACK
|
||||
REG(MR3.UINT32) |= (1 <<4);
|
||||
REG(MR3.UINT32) |= (1 <<3);
|
||||
REG(MR3.UINT32) &= ~(1 <<4);
|
||||
// dummy read
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
/* send a NOT ACK */
|
||||
REG(MR3.UINT32) |= MR3_ACKWP;
|
||||
REG(MR3.UINT32) |= MR3_ACKBT;
|
||||
REG(MR3.UINT32) &= ~MR3_ACKWP;
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
} else {
|
||||
// Do Nothing
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
// read in last byte
|
||||
i2c_wait_RDRF(obj);
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
/* RIICnSR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~(1 << 3);
|
||||
/* RIICnCR2.SP = 1 */
|
||||
REG(CR2.UINT32) |= (1 << 3);
|
||||
/* RIICnDRR read */
|
||||
value = REG(DRR.UINT32) & 0xFF;
|
||||
data[count] = (char) value;
|
||||
/* RIICnMR3.WAIT = 0 */
|
||||
REG(MR3.UINT32) &= ~(1 << 6);
|
||||
i2c_wait_STOP(obj);
|
||||
} else {
|
||||
/* RIICnDRR read */
|
||||
value = REG(DRR.UINT32) & 0xFF;
|
||||
data[count] = (char) value;
|
||||
/* wait for it to arrive */
|
||||
status = i2c_wait_RDRF(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* RIICnSR2.STOP = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_STOP;
|
||||
/* RIICnCR2.SP = 1 */
|
||||
REG(CR2.UINT32) |= CR2_SP;
|
||||
/* 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_NACKF_STOP(obj);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
||||
int i, status;
|
||||
|
||||
// full reset
|
||||
i2c_reg_reset(obj);
|
||||
int cnt;
|
||||
int status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if ((status == 0xff)) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
/**/
|
||||
status = REG(CR2.UINT32);
|
||||
status = REG(SR2.UINT32);
|
||||
/**/
|
||||
|
||||
/* Send Slave address */
|
||||
status = i2c_do_write(obj, address);
|
||||
if (status & 0x10) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
/**/
|
||||
status = REG(CR2.UINT32);
|
||||
status = REG(SR2.UINT32);
|
||||
/**/
|
||||
for (i=0; i<length; i++) {
|
||||
/**/
|
||||
status = REG(CR2.UINT32);
|
||||
status = REG(SR2.UINT32);
|
||||
/**/
|
||||
status = i2c_do_write(obj, data[i]);
|
||||
if(status & 0x10) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
return i;
|
||||
/* Send Write data */
|
||||
for (cnt=0; cnt<length; cnt++) {
|
||||
status = i2c_do_write(obj, data[cnt]);
|
||||
if(status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_wait_TEND(obj);
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
/* Wait send end */
|
||||
status = i2c_wait_TEND(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
i2c_stop(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void i2c_reset(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
obj->dummy = 1;
|
||||
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);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
return (i2c_do_read(obj, last) & 0xFF);
|
||||
}
|
||||
|
@ -447,7 +539,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
|
|||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
int ack;
|
||||
int status = i2c_do_write(obj, (data & 0xFF));
|
||||
if (status & NACKF) {
|
||||
if (status != 0) {
|
||||
ack = 0;
|
||||
} else {
|
||||
ack = 1;
|
||||
|
@ -496,7 +588,8 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
|
|||
|
||||
if(status & 0x10) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
}
|
||||
|
||||
//i2c_clear_TDRE(obj);
|
||||
|
@ -519,7 +612,8 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
|||
|
||||
if (!(status & 0x10)) {
|
||||
i2c_stop(obj);
|
||||
i2c_wait_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_NACKF_STOP(obj);
|
||||
}
|
||||
|
||||
i2c_clear_TDRE(obj);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "PeripheralNames.h"
|
||||
#include "PinNames.h"
|
||||
#include "gpio_object.h"
|
||||
#include "rspi_iodefine.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -31,11 +32,14 @@ struct i2c_s {
|
|||
uint32_t i2c;
|
||||
uint32_t dummy;
|
||||
uint8_t pclk_bit;
|
||||
uint32_t width;
|
||||
uint8_t width_low;
|
||||
uint8_t width_hi;
|
||||
int bbsy_wait_cnt;
|
||||
};
|
||||
|
||||
struct spi_s {
|
||||
uint32_t spi;
|
||||
struct st_rspi *spi;
|
||||
uint32_t bits;
|
||||
};
|
||||
|
||||
struct gpio_irq_s {
|
||||
|
@ -59,7 +63,6 @@ struct serial_s {
|
|||
|
||||
struct pwmout_s {
|
||||
uint32_t ch;
|
||||
int32_t period;
|
||||
PWMName pwm;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ static __IO uint16_t *PWM_MATCH[] = {
|
|||
|
||||
static uint16_t init_period_ch1 = 0;
|
||||
static uint16_t init_period_ch2 = 0;
|
||||
static int32_t period_ch1 = 1;
|
||||
static int32_t period_ch2 = 1;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
// determine the channel
|
||||
|
@ -207,6 +209,9 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
|
||||
// Counter Start
|
||||
PWMPWCR_2_BYTE_L |= 0x08;
|
||||
|
||||
// Save for future use
|
||||
period_ch2 = us;
|
||||
} else {
|
||||
wk_last_cycle = PWMPWCYR_1 & 0x03ff;
|
||||
PWMPWCR_1_BYTE_L = 0xc0 | wk_cks;
|
||||
|
@ -220,10 +225,10 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
|
||||
// Counter Start
|
||||
PWMPWCR_1_BYTE_L |= 0x08;
|
||||
}
|
||||
|
||||
// Save for future use
|
||||
obj->period = us;
|
||||
// Save for future use
|
||||
period_ch1 = us;
|
||||
}
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
|
@ -235,6 +240,17 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
|||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
float value = (float)us / (float)obj->period;
|
||||
float value = 0;
|
||||
|
||||
if (obj->ch == 2) {
|
||||
if (period_ch2 != 0) {
|
||||
value = (float)us / (float)period_ch2;
|
||||
}
|
||||
} else {
|
||||
if (period_ch1 != 0) {
|
||||
value = (float)us / (float)period_ch1;
|
||||
}
|
||||
}
|
||||
|
||||
pwmout_write(obj, value);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "gpio_api.h"
|
||||
|
||||
#include "scif_iodefine.h"
|
||||
typedef struct st_scif SCIF_TypeDef;
|
||||
#include "cpg_iodefine.h"
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -53,48 +52,36 @@ static void uart7_rx_irq(void);
|
|||
|
||||
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{P6_3 , P_SCIF2, 7},
|
||||
{P2_14 , P_SCIF0, 6},
|
||||
{P5_0 , P_SCIF4, 5},
|
||||
{P5_3 , P_SCIF3, 5},
|
||||
{P5_6 , P_SCIF6, 5},
|
||||
{P2_5 , P_SCIF1, 6},
|
||||
{P8_14 , P_SCIF4, 7},
|
||||
{P8_13 , P_SCIF5, 5},
|
||||
{P7_4 , P_SCIF7, 4},
|
||||
{P11_10, P_SCIF5, 3},
|
||||
{P6_6 , P_SCIF5, 5},
|
||||
{NC , NC , 0}
|
||||
{P6_3 , UART2, 7},
|
||||
{P2_14 , UART0, 6},
|
||||
{P5_0 , UART4, 5},
|
||||
{P5_3 , UART3, 5},
|
||||
{P5_6 , UART6, 5},
|
||||
{P2_5 , UART1, 6},
|
||||
{P8_14 , UART4, 7},
|
||||
{P8_13 , UART5, 5},
|
||||
{P7_4 , UART7, 4},
|
||||
{P11_10, UART5, 3},
|
||||
{P6_6 , UART5, 5},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
{P6_2 , P_SCIF2, 7},
|
||||
{P2_15 , P_SCIF0, 6},
|
||||
{P5_1 , P_SCIF4, 5},
|
||||
{P5_4 , P_SCIF3, 5},
|
||||
{P5_7 , P_SCIF6, 5},
|
||||
{P2_6 , P_SCIF1, 6},
|
||||
{P8_15 , P_SCIF4, 7},
|
||||
{P8_11 , P_SCIF5, 5},
|
||||
{P7_5 , P_SCIF7, 4},
|
||||
{P11_11, P_SCIF5, 3},
|
||||
{P6_7 , P_SCIF5, 5},
|
||||
{NC , NC , 0}
|
||||
{P6_2 , UART2, 7},
|
||||
{P2_15 , UART0, 6},
|
||||
{P5_1 , UART4, 5},
|
||||
{P5_4 , UART3, 5},
|
||||
{P5_7 , UART6, 5},
|
||||
{P2_6 , UART1, 6},
|
||||
{P8_15 , UART4, 7},
|
||||
{P8_11 , UART5, 5},
|
||||
{P7_5 , UART7, 4},
|
||||
{P11_11, UART5, 3},
|
||||
{P6_7 , UART5, 5},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/* [TODO] impliment hardware Flow Control, interrupt
|
||||
static const PinMap PinMap_UART_RTS[] = {
|
||||
{P7_7, (int)P_SCIF7, 4},
|
||||
{P2_7 , (int)P_SCIF1, 6},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_CTS[] = {
|
||||
{P7_6, (int)P_SCIF7, 4},
|
||||
{P2_3, (int)P_SCIF1, 6},
|
||||
{NC, NC, 0}
|
||||
};*/
|
||||
|
||||
static const struct st_scif *SCIF[] = SCIF_ADDRESS_LIST;
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
int stdio_uart_inited = 0;
|
||||
|
@ -154,27 +141,27 @@ static __IO uint16_t *SCFSR_MATCH[] = {
|
|||
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
volatile uint8_t dummy ;
|
||||
int is_stdio_uart = 0;
|
||||
|
||||
// determine the UART to use
|
||||
uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
|
||||
uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
|
||||
uint32_t uart = pinmap_merge(uart_tx, uart_rx);
|
||||
|
||||
MBED_ASSERT((int)uart != NC);
|
||||
|
||||
obj->uart = (SCIF_TypeDef *)uart;
|
||||
obj->uart = (struct st_scif *)SCIF[uart];
|
||||
// enable power
|
||||
switch (uart) {
|
||||
case P_SCIF0: CPG.STBCR4 &= ~(1 << 7); break;
|
||||
case P_SCIF1: CPG.STBCR4 &= ~(1 << 6); break;
|
||||
case P_SCIF2: CPG.STBCR4 &= ~(1 << 5); break;
|
||||
case P_SCIF3: CPG.STBCR4 &= ~(1 << 4); break;
|
||||
case P_SCIF4: CPG.STBCR4 &= ~(1 << 3); break;
|
||||
case P_SCIF5: CPG.STBCR4 &= ~(1 << 2); break;
|
||||
case P_SCIF6: CPG.STBCR4 &= ~(1 << 1); break;
|
||||
case P_SCIF7: CPG.STBCR4 &= ~(1 << 0); break;
|
||||
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;
|
||||
}
|
||||
volatile uint8_t dummy ;
|
||||
dummy = CPG.STBCR4;
|
||||
|
||||
/* ==== SCIF initial setting ==== */
|
||||
|
@ -205,7 +192,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
|
||||
/* ---- FIFO control register (SCFCR) setting ---- */
|
||||
obj->uart->SCFCR = 0x0030u;
|
||||
|
||||
|
||||
/* ---- Serial port register (SCSPTR) setting ----
|
||||
b1 SPB2IO - Serial port break output : disabled
|
||||
b0 SPB2DT - Serial port break data : High-level */
|
||||
|
@ -218,18 +205,17 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
|
||||
switch (uart) {
|
||||
case P_SCIF0: obj->index = 0; break;
|
||||
case P_SCIF1: obj->index = 1; break;
|
||||
case P_SCIF2: obj->index = 2; break;
|
||||
case P_SCIF3: obj->index = 3; break;
|
||||
case P_SCIF4: obj->index = 4; break;
|
||||
case P_SCIF5: obj->index = 5; break;
|
||||
case P_SCIF6: obj->index = 6; break;
|
||||
case P_SCIF7: 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;
|
||||
// serial_set_flow_control(obj, FlowControlNone, NC, NC);
|
||||
|
||||
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
|
||||
|
||||
|
@ -256,6 +242,9 @@ void serial_baud(serial_t *obj, int baudrate) {
|
|||
}
|
||||
|
||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||
int parity_enable;
|
||||
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((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
|
||||
|
@ -269,13 +258,22 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
(data_bits == 7)? 1:
|
||||
0; // must not to be
|
||||
|
||||
int parity_enable, parity_select;
|
||||
switch (parity) {
|
||||
case ParityNone: parity_enable = 0; parity_select = 0; break;
|
||||
case ParityOdd : parity_enable = 1; parity_select = 0; break;
|
||||
case ParityEven: parity_enable = 1; parity_select = 1; break;
|
||||
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;
|
||||
parity_enable = 0;
|
||||
parity_select = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -292,19 +290,19 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
static void uart_tx_irq(IRQn_Type irq_num, uint32_t index) {
|
||||
__IO uint16_t *dmy_rd_scscr;
|
||||
__IO uint16_t *dmy_rd_scfsr;
|
||||
|
||||
|
||||
dmy_rd_scscr = SCSCR_MATCH[index];
|
||||
*dmy_rd_scscr &= 0x007B; // Clear TIE and Write to bit15~8,2 is always 0
|
||||
dmy_rd_scfsr = SCFSR_MATCH[index];
|
||||
*dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0020); // Clear TDFE
|
||||
|
||||
|
||||
irq_handler(uart_data[index].serial_irq_id, TxIrq);
|
||||
}
|
||||
|
||||
static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) {
|
||||
__IO uint16_t *dmy_rd_scscr;
|
||||
__IO uint16_t *dmy_rd_scfsr;
|
||||
|
||||
|
||||
dmy_rd_scscr = SCSCR_MATCH[index];
|
||||
*dmy_rd_scscr &= 0x00B3; // Clear RIE,REIE and Write to bit15~8,2 is always 0
|
||||
dmy_rd_scfsr = SCFSR_MATCH[index];
|
||||
|
@ -356,8 +354,9 @@ static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enabl
|
|||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
if (RxIrq == irq)
|
||||
if (RxIrq == irq) {
|
||||
uart_data[obj->index].rx_irq_set_api = enable;
|
||||
}
|
||||
serial_irq_set_internal(obj, irq, enable);
|
||||
}
|
||||
|
||||
|
@ -371,16 +370,16 @@ static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
|
|||
******************************************************************************/
|
||||
int serial_getc(serial_t *obj) {
|
||||
uint16_t dummy_read;
|
||||
|
||||
int data;
|
||||
|
||||
if (obj->uart->SCFSR & 0x93) {
|
||||
dummy_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (dummy_read & ~0x93);
|
||||
}
|
||||
obj->uart->SCSCR |= 0x0040; // Set RIE
|
||||
while (!serial_readable(obj));
|
||||
int data = obj->uart->SCFRDR & 0xff;
|
||||
/* Clear DR,RDF */
|
||||
obj->uart->SCFSR &= 0xfffc;
|
||||
data = obj->uart->SCFRDR & 0xff;
|
||||
obj->uart->SCFSR &= 0xfffc; // Clear DR,RDF
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -413,11 +412,9 @@ void serial_pinout_tx(PinName tx) {
|
|||
}
|
||||
|
||||
void serial_break_set(serial_t *obj) {
|
||||
//obj->uart->LCR |= (1 << 6);
|
||||
}
|
||||
|
||||
void serial_break_clear(serial_t *obj) {
|
||||
//obj->uart->LCR &= ~(1 << 6);
|
||||
}
|
||||
|
||||
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
|
||||
|
|
|
@ -20,95 +20,91 @@
|
|||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
|
||||
#include "rspi_iodefine.h"
|
||||
#include "RZ_A1_Init.h"
|
||||
|
||||
static const PinMap PinMap_SPI_SCLK[] = {
|
||||
{P10_12, SPI_0, 4},
|
||||
{P11_12, SPI_1, 2},
|
||||
{P8_3, SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
{P8_3 , SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_SSEL[] = {
|
||||
{P10_13, SPI_0, 4},
|
||||
{P11_13, SPI_1, 2},
|
||||
{P8_4, SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
{P8_4 , SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MOSI[] = {
|
||||
{P10_14, SPI_0, 4},
|
||||
{P11_14, SPI_1, 2},
|
||||
{P8_5, SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
{P8_5 , SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MISO[] = {
|
||||
{P10_15, SPI_0, 4},
|
||||
{P11_15, SPI_1, 2},
|
||||
{P8_6, SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
{P8_6 , SPI_2, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
struct st_rspi *RSPI[] = RSPI_ADDRESS_LIST;
|
||||
static const struct st_rspi *RSPI[] = RSPI_ADDRESS_LIST;
|
||||
|
||||
static inline void spi_disable(spi_t *obj);
|
||||
static inline void spi_enable(spi_t *obj);
|
||||
static inline int spi_readable(spi_t *obj);
|
||||
static inline void spi_write(spi_t *obj, int value);
|
||||
static inline int spi_writable(spi_t *obj);
|
||||
static inline int spi_read(spi_t *obj);
|
||||
|
||||
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
|
||||
// determine the SPI to use
|
||||
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
|
||||
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
|
||||
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
|
||||
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
|
||||
//SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
|
||||
//SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
|
||||
obj->spi = spi_mosi; //pinmap_merge(spi_data, spi_cntl);
|
||||
MBED_ASSERT((int)obj->spi != NC);
|
||||
|
||||
// enable power and clocking
|
||||
volatile uint8_t dummy;
|
||||
switch ((int)obj->spi) {
|
||||
uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI);
|
||||
uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO);
|
||||
uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK);
|
||||
uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL);
|
||||
uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso);
|
||||
uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel);
|
||||
uint32_t spi = pinmap_merge(spi_data, spi_cntl);
|
||||
|
||||
MBED_ASSERT((int)spi != NC);
|
||||
|
||||
obj->spi = (struct st_rspi *)RSPI[spi];
|
||||
|
||||
// enable power and clocking
|
||||
switch (spi) {
|
||||
case SPI_0: CPGSTBCR10 &= ~(0x80); break;
|
||||
case SPI_1: CPGSTBCR10 &= ~(0x40); break;
|
||||
case SPI_2: CPGSTBCR10 &= ~(0x20); break;
|
||||
}
|
||||
dummy = CPGSTBCR10;
|
||||
|
||||
RSPI[obj->spi]->SPCR = 0x00; // CTRL to 0
|
||||
RSPI[obj->spi]->SPSCR = 0x00; // no sequential operation
|
||||
RSPI[obj->spi]->SSLP = 0x00; // SSL 'L' active
|
||||
RSPI[obj->spi]->SPDCR = 0x20; // byte access
|
||||
RSPI[obj->spi]->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
|
||||
RSPI[obj->spi]->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
|
||||
RSPI[obj->spi]->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
|
||||
RSPI[obj->spi]->SPPCR = 0x20; //
|
||||
|
||||
RSPI[obj->spi]->SPBFCR= 0xf0; // and set trigger count: read 1, write 1
|
||||
RSPI[obj->spi]->SPBFCR= 0x30; // and reset buffer
|
||||
obj->spi->SPCR = 0x00; // CTRL to 0
|
||||
obj->spi->SPSCR = 0x00; // no sequential operation
|
||||
obj->spi->SSLP = 0x00; // SSL 'L' active
|
||||
obj->spi->SPDCR = 0x20; // byte access
|
||||
obj->spi->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
|
||||
obj->spi->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
|
||||
obj->spi->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
|
||||
obj->spi->SPPCR = 0x20; // MOSI Idle fixed value equals 0
|
||||
obj->spi->SPBFCR = 0xf0; // and set trigger count: read 1, write 1
|
||||
obj->spi->SPBFCR = 0x30; // and reset buffer
|
||||
|
||||
// set default format and frequency
|
||||
if (ssel == NC) {
|
||||
if ((int)ssel == NC) {
|
||||
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
|
||||
} else {
|
||||
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
|
||||
}
|
||||
spi_frequency(obj, 1000000);
|
||||
|
||||
// enable the ssp channel
|
||||
spi_enable(obj);
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
if (ssel != NC) {
|
||||
if ((int)ssel != NC) {
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
}
|
||||
}
|
||||
|
@ -116,103 +112,130 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
void spi_free(spi_t *obj) {}
|
||||
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
spi_disable(obj);
|
||||
MBED_ASSERT(((bits >= 4) && (bits <= 16)) && (mode >= 0 && mode <= 3));
|
||||
int DSS; // DSS (data select size)
|
||||
int polarity = (mode & 0x2) ? 1 : 0;
|
||||
int phase = (mode & 0x1) ? 1 : 0;
|
||||
uint16_t tmp = 0;
|
||||
uint16_t mask = 0xf03;
|
||||
uint8_t splw;
|
||||
|
||||
int polarity = (mode & 0x2) ? 1 : 0;
|
||||
int phase = (mode & 0x1) ? 1 : 0;
|
||||
uint16_t tmp = 0, mask = 0xf03;
|
||||
|
||||
tmp |= phase;
|
||||
tmp |= polarity << 1;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
// Do Nothing
|
||||
break;
|
||||
default:
|
||||
error("SPI format error");
|
||||
return;
|
||||
}
|
||||
|
||||
int DSS; // DSS (data select size)
|
||||
switch (bits) {
|
||||
case 8:
|
||||
DSS = 0x7; break;
|
||||
DSS = 0x7;
|
||||
splw = 0x20;
|
||||
break;
|
||||
case 16:
|
||||
DSS = 0xf; break;
|
||||
DSS = 0xf;
|
||||
splw = 0x40;
|
||||
break;
|
||||
case 32:
|
||||
DSS = 0x2; break;
|
||||
DSS = 0x2;
|
||||
splw = 0x60;
|
||||
break;
|
||||
default:
|
||||
error("SPI module don't support other than 8/16/32bits");
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
tmp |= phase;
|
||||
tmp |= (polarity << 1);
|
||||
tmp |= (DSS << 8);
|
||||
obj->bits = bits;
|
||||
|
||||
// set it up
|
||||
RSPI[obj->spi]->SPCMD0 &= ~mask;
|
||||
RSPI[obj->spi]->SPCMD0 |= (mask & tmp);
|
||||
|
||||
spi_disable(obj);
|
||||
obj->spi->SPCMD0 &= ~mask;
|
||||
obj->spi->SPCMD0 |= (mask & tmp);
|
||||
obj->spi->SPDCR = splw;
|
||||
if (slave) {
|
||||
RSPI[obj->spi]->SPCR &=~(1 << 3);
|
||||
obj->spi->SPCR &=~(1 << 3); // MSTR to 0
|
||||
} else {
|
||||
RSPI[obj->spi]->SPCR |= (1 << 3);
|
||||
obj->spi->SPCR |= (1 << 3); // MSTR to 1
|
||||
}
|
||||
|
||||
spi_enable(obj);
|
||||
}
|
||||
|
||||
void spi_frequency(spi_t *obj, int hz) {
|
||||
spi_disable(obj);
|
||||
const int P1CLK = 66666666; // 66.6666MHz
|
||||
uint8_t div, brdv;
|
||||
uint16_t mask = 0x000c;
|
||||
uint32_t pclk_base;
|
||||
uint32_t div;
|
||||
uint32_t brdv = 0;
|
||||
uint16_t mask = 0x000c;
|
||||
|
||||
if (hz <= P1CLK/2 && hz >= P1CLK/255) {
|
||||
div = (P1CLK / hz / 2) -1;
|
||||
brdv = 0x0 << 2;
|
||||
} else if (hz >= P1CLK/255/2) {
|
||||
div = (P1CLK / hz / 2 /2) -1;
|
||||
brdv = 0x1 << 2;
|
||||
} else if (hz >= P1CLK/255/4) {
|
||||
div = (P1CLK / hz / 2 /4) -1;
|
||||
brdv = 0x2 << 2;
|
||||
} else if (hz >= P1CLK/255/8) {
|
||||
div = (P1CLK / hz / 2 /8) -1;
|
||||
brdv = 0x3 << 2;
|
||||
/* set PCLK */
|
||||
if (RZ_A1_IsClockMode0() == false) {
|
||||
pclk_base = CM1_RENESAS_RZ_A1_P1_CLK;
|
||||
} else {
|
||||
pclk_base = CM0_RENESAS_RZ_A1_P1_CLK;
|
||||
}
|
||||
|
||||
if ((hz < (pclk_base / 2 / 256 / 8)) || (hz > (pclk_base / 2))) {
|
||||
error("Couldn't setup requested SPI frequency");
|
||||
return;
|
||||
}
|
||||
|
||||
RSPI[obj->spi]->SPBR = div;
|
||||
div = (pclk_base / hz / 2);
|
||||
while (div > 256) {
|
||||
div >>= 1;
|
||||
brdv++;
|
||||
}
|
||||
div -= 1;
|
||||
brdv = (brdv << 2);
|
||||
|
||||
RSPI[obj->spi]->SPCMD0 &= ~mask;
|
||||
RSPI[obj->spi]->SPCMD0 |= (mask & brdv);
|
||||
|
||||
|
||||
spi_disable(obj);
|
||||
obj->spi->SPBR = div;
|
||||
obj->spi->SPCMD0 &= ~mask;
|
||||
obj->spi->SPCMD0 |= (mask & brdv);
|
||||
spi_enable(obj);
|
||||
}
|
||||
|
||||
static inline void spi_disable(spi_t *obj) {
|
||||
RSPI[obj->spi]->SPCR &= ~(1 << 6); // SPE to 0
|
||||
obj->spi->SPCR &= ~(1 << 6); // SPE to 0
|
||||
}
|
||||
|
||||
static inline void spi_enable(spi_t *obj) {
|
||||
RSPI[obj->spi]->SPCR |= (1 << 6); // SPE to 1
|
||||
obj->spi->SPCR |= (1 << 6); // SPE to 1
|
||||
}
|
||||
|
||||
static inline int spi_readable(spi_t *obj) {
|
||||
return RSPI[obj->spi]->SPSR & (1 << 7);
|
||||
return obj->spi->SPSR & (1 << 7); // SPRF
|
||||
}
|
||||
|
||||
static inline int spi_tend(spi_t *obj) {
|
||||
return RSPI[obj->spi]->SPSR & (1 << 6);
|
||||
}
|
||||
|
||||
static inline int spi_writable(spi_t *obj) {
|
||||
return RSPI[obj->spi]->SPSR & (1 << 5);
|
||||
return obj->spi->SPSR & (1 << 6); // TEND
|
||||
}
|
||||
|
||||
static inline void spi_write(spi_t *obj, int value) {
|
||||
while (!spi_writable(obj));
|
||||
RSPI[obj->spi]->SPDR.UINT8[0] = value;
|
||||
if (obj->bits == 8) {
|
||||
obj->spi->SPDR.UINT8[0] = (uint8_t)value;
|
||||
} else if (obj->bits == 16) {
|
||||
obj->spi->SPDR.UINT16[0] = (uint16_t)value;
|
||||
} else {
|
||||
obj->spi->SPDR.UINT32 = (uint32_t)value;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int spi_read(spi_t *obj) {
|
||||
//while (!spi_readable(obj));
|
||||
return RSPI[obj->spi]->SPDR.UINT8[0];
|
||||
int read_data;
|
||||
|
||||
if (obj->bits == 8) {
|
||||
read_data = obj->spi->SPDR.UINT8[0];
|
||||
} else if (obj->bits == 16) {
|
||||
read_data = obj->spi->SPDR.UINT16[0];
|
||||
} else {
|
||||
read_data = obj->spi->SPDR.UINT32;
|
||||
}
|
||||
|
||||
return read_data;
|
||||
}
|
||||
|
||||
int spi_master_write(spi_t *obj, int value) {
|
||||
|
@ -226,14 +249,13 @@ int spi_slave_receive(spi_t *obj) {
|
|||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
return RSPI[obj->spi]->SPDR.UINT8[0];
|
||||
return spi_read(obj);
|
||||
}
|
||||
|
||||
void spi_slave_write(spi_t *obj, int value) {
|
||||
while (spi_writable(obj) == 0) ;
|
||||
RSPI[obj->spi]->SPDR.UINT8[0] = value;
|
||||
spi_write(obj, value);
|
||||
}
|
||||
|
||||
int spi_busy(spi_t *obj) {
|
||||
return (RSPI[obj->spi]->SPSR & (1 << 6)) ? (0) : (1);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
// <1=> Privileged mode
|
||||
// <i> Default: Privileged mode
|
||||
#ifndef OS_RUNPRIV
|
||||
#define OS_RUNPRIV 0
|
||||
#define OS_RUNPRIV 1
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
@ -107,7 +107,11 @@
|
|||
// <i> Defines the timer clock value.
|
||||
// <i> Default: 12000000 (12MHz)
|
||||
#ifndef OS_CLOCK
|
||||
# if defined(TARGET_RZ_A1H)
|
||||
#define OS_CLOCK 12000000
|
||||
# else
|
||||
# error "no target defined"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// <o>Timer tick value [us] <1-1000000>
|
||||
|
@ -161,7 +165,7 @@
|
|||
// <i> Defines stack size for Timer thread.
|
||||
// <i> Default: 200
|
||||
#ifndef OS_TIMERSTKSZ
|
||||
#define OS_TIMERSTKSZ 400
|
||||
#define OS_TIMERSTKSZ WORDS_STACK_SIZE
|
||||
#endif
|
||||
|
||||
// <o>Timer Callback Queue size <1-32>
|
||||
|
@ -194,7 +198,7 @@
|
|||
// Define max. number system mutexes that are used to protect
|
||||
// the arm standard runtime library. For microlib they are not used.
|
||||
#ifndef OS_MUTEXCNT
|
||||
#define OS_MUTEXCNT 8
|
||||
#define OS_MUTEXCNT 12
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -216,10 +220,6 @@ void os_idle_demon (void) {
|
|||
|
||||
for (;;) {
|
||||
/* HERE: include optional user code to be executed when no thread runs.*/
|
||||
#if 0
|
||||
__DSB();
|
||||
__WFI();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue