Skip to content

[RZ_A1H]Fix bugs of I2C and Update a header file of Video driver. #1102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* File Name : lvds_iodefine.h
* $Rev: $
* $Date:: $
* Description : Definition of I/O Register (V1.00a)
* Description : Definition of I/O Register (V1.01a)
******************************************************************************/
#ifndef LVDS_IODEFINE_H
#define LVDS_IODEFINE_H
Expand All @@ -37,7 +37,8 @@ struct st_lvds
volatile uint8_t dummy608[24]; /* */
volatile uint32_t LCLKSELR; /* LCLKSELR */
volatile uint32_t LPLLSETR; /* LPLLSETR */
volatile uint32_t LPLLMONR; /* LPLLMONR */
volatile uint8_t dummy609[4]; /* */
volatile uint32_t LPHYACC; /* LPHYACC */
};


Expand All @@ -48,6 +49,6 @@ struct st_lvds
#define LVDSLVDSFCL LVDS.LVDSFCL
#define LVDSLCLKSELR LVDS.LCLKSELR
#define LVDSLPLLSETR LVDS.LPLLSETR
#define LVDSLPLLMONR LVDS.LPLLMONR
#define LVDSLPHYACC LVDS.LPHYACC
/* <-SEC M1.10.1 */
#endif
147 changes: 83 additions & 64 deletions libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
#define SR2_TEND (1 << 6)
#define SR2_TDRE (1 << 7)

#define WAIT_TIMEOUT (4200) /* Loop counter : Time-out is about 1ms. By 4200 loops, measured value is 1009ms. */
#define WAIT_TIMEOUT (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},
Expand Down Expand Up @@ -106,7 +106,7 @@ 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)) {
while ((i2c_status(obj) & SR2_RDRF) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
Expand All @@ -120,7 +120,7 @@ static int i2c_wait_TDRE(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_TDRE)) {
while ((i2c_status(obj) & SR2_TDRE) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
Expand All @@ -134,7 +134,7 @@ 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)) {
while ((i2c_status(obj) & SR2_TEND) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
Expand All @@ -149,7 +149,7 @@ 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)) {
while ((i2c_status(obj) & SR2_START) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
Expand All @@ -163,7 +163,7 @@ static int i2c_wait_STOP(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_STOP)) {
while ((i2c_status(obj) & SR2_STOP) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
Expand All @@ -173,6 +173,15 @@ static int i2c_wait_STOP(i2c_t *obj) {
return 0;
}

static int i2c_set_STOP(i2c_t *obj) {
/* SR2.STOP = 0 */
REG(SR2.UINT32) &= ~SR2_STOP;
/* Stop condition */
REG(CR2.UINT32) |= CR2_SP;

return 0;
}

static void i2c_set_SR2_NACKF_STOP(i2c_t *obj) {
/* SR2.NACKF = 0 */
REG(SR2.UINT32) &= ~SR2_NACKF;
Expand Down Expand Up @@ -235,7 +244,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
inline int i2c_start(i2c_t *obj) {
int timeout = 0;

while (REG(CR2.UINT32) & CR2_BBSY) {
while ((REG(CR2.UINT32) & CR2_BBSY) != 0) {
timeout ++;
if (timeout >= obj->bbsy_wait_cnt) {
break;
Expand All @@ -257,16 +266,15 @@ static inline int i2c_restart(i2c_t *obj) {
}

inline int i2c_stop(i2c_t *obj) {
/* SR2.STOP = 0 */
REG(SR2.UINT32) &= ~SR2_STOP;
/* Stop condition */
REG(CR2.UINT32) |= CR2_SP;

(void)i2c_set_STOP(obj);
(void)i2c_wait_STOP(obj);
i2c_set_SR2_NACKF_STOP(obj);

return 0;
}

static void i2c_set_err_noslave(i2c_t *obj) {
(void)i2c_stop(obj);
(void)i2c_set_STOP(obj);
(void)i2c_wait_STOP(obj);
i2c_set_SR2_NACKF_STOP(obj);
obj->last_stop_flag = 1;
Expand All @@ -275,25 +283,15 @@ static void i2c_set_err_noslave(i2c_t *obj) {
static inline int i2c_do_write(i2c_t *obj, int value) {
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 >= WAIT_TIMEOUT) {
return -1;
}
if (i2c_status(obj) & SR2_NACKF) {
/* RIICnSR2.NACKF=1 */
return -1;
}
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
while ((i2c_status(obj) & SR2_TDRE) == 0) {
timeout ++;
if (timeout >= WAIT_TIMEOUT) {
return -1;
}
/* write the data */
REG(DRT.UINT32) = value;
} else {
return -1;
}
/* write the data */
REG(DRT.UINT32) = value;

return 0;
}
Expand Down Expand Up @@ -440,9 +438,9 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
/* wait RDRF */
status = i2c_wait_RDRF(obj);
/* check ACK/NACK */
if ((status != 0) || (REG(SR2.UINT32) & SR2_NACKF == 1)) {
if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
/* Slave sends NACK */
i2c_stop(obj);
(void)i2c_set_STOP(obj);
/* dummy read */
value = REG(DRR.UINT32);
(void)i2c_wait_STOP(obj);
Expand Down Expand Up @@ -502,9 +500,9 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {

/* If not repeated start, send stop. */
if (stop) {
(void)i2c_stop(obj);
(void)i2c_set_STOP(obj);
/* RIICnDRR read */
value = REG(DRR.UINT32) & 0xFF;
value = (REG(DRR.UINT32) & 0xFF);
data[count] = (char)value;
/* RIICnMR3.WAIT = 0 */
REG(MR3.UINT32) &= ~MR3_WAIT;
Expand All @@ -513,7 +511,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
} else {
(void)i2c_restart(obj);
/* RIICnDRR read */
value = REG(DRR.UINT32) & 0xFF;
value = (REG(DRR.UINT32) & 0xFF);
data[count] = (char)value;
/* RIICnMR3.WAIT = 0 */
REG(MR3.UINT32) &= ~MR3_WAIT;
Expand Down Expand Up @@ -548,23 +546,32 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
i2c_set_err_noslave(obj);
return I2C_ERROR_NO_SLAVE;
}
/* Wait send end */
status = i2c_wait_TEND(obj);
if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
/* Slave sends NACK */
i2c_set_err_noslave(obj);
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);
return cnt;
} else {
/* Wait send end */
status = i2c_wait_TEND(obj);
if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
/* Slave sends NACK */
i2c_set_err_noslave(obj);
return I2C_ERROR_NO_SLAVE;
}
}
}
/* Wait send end */
status = i2c_wait_TEND(obj);
if (status != 0) {
i2c_set_err_noslave(obj);
return I2C_ERROR_NO_SLAVE;
}
/* If not repeated start, send stop. */
if (stop) {
(void)i2c_stop(obj);
(void)i2c_set_STOP(obj);
(void)i2c_wait_STOP(obj);
i2c_set_SR2_NACKF_STOP(obj);
} else {
Expand All @@ -579,34 +586,48 @@ 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_set_STOP(obj);
(void)i2c_wait_STOP(obj);
i2c_set_SR2_NACKF_STOP(obj);
}

int i2c_byte_read(i2c_t *obj, int last) {
int status;
int data;

data = i2c_do_read(obj, last);
/* wait for it to arrive */
status = i2c_wait_RDRF(obj);
if (status != 0) {
i2c_set_err_noslave(obj);
i2c_set_SR2_NACKF_STOP(obj);
return I2C_ERROR_NO_SLAVE;
}

return (i2c_do_read(obj, last));
return data;
}

int i2c_byte_write(i2c_t *obj, int data) {
int ack;
int ack = 0;
int status;
int timeout = 0;

status = i2c_do_write(obj, (data & 0xFF));
if (status != 0) {
i2c_set_err_noslave(obj);
ack = 0;
i2c_set_SR2_NACKF_STOP(obj);
} else {
ack = 1;
while (((i2c_status(obj) & SR2_RDRF) == 0) && ((i2c_status(obj) & SR2_TEND) == 0)) {
timeout++;
if (timeout >= WAIT_TIMEOUT) {
return ack;
}
}
/* check ACK/NACK */
if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
/* NACK */
i2c_set_SR2_NACKF_STOP(obj);
} else {
ack = 1;
}
}

return ack;
Expand All @@ -624,7 +645,7 @@ int i2c_slave_receive(i2c_t *obj) {
int status;
int retval;

status = REG(SR1.UINT8[0]) & SR1_AAS0;
status = (REG(SR1.UINT8[0]) & SR1_AAS0);
status |= (REG(CR2.UINT8[0]) & CR2_TRS) >> 4;

switch(status) {
Expand Down Expand Up @@ -659,10 +680,8 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
}
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 */
while (((i2c_status(obj) & SR2_STOP) != 0) || ((i2c_status(obj) & SR2_RDRF) == 0)) {
if ((i2c_status(obj) & SR2_STOP) != 0) {
break_flg = 1;
break;
}
Expand All @@ -683,7 +702,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
if (break_flg == 0) {
(void)i2c_wait_STOP(obj);
} else {
if (i2c_status(obj) & SR2_RDRF) {
if ((i2c_status(obj) & SR2_RDRF) != 0) {
if (count <= 1) {
/* fail safe */
/* dummy read */
Expand All @@ -709,15 +728,15 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {

while ((count < length) && (status == 0)) {
status = i2c_do_write(obj, data[count]);
count++;
}
if (status == 0) {
/* Wait send end */
status = i2c_wait_TEND(obj);
if (status != 0) {
i2c_set_err_noslave(obj);
return 0;
if(status == 0) {
/* Wait send end */
status = i2c_wait_TEND(obj);
if ((status != 0) || ((count < (length - 1)) && ((REG(SR2.UINT32) & SR2_NACKF) != 0))) {
/* NACK */
break;
}
}
count++;
}
/* dummy read */
(void)REG(DRR.UINT32);
Expand All @@ -728,5 +747,5 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
}

void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
REG(SAR0.UINT32) = address & 0xfffffffe;
REG(SAR0.UINT32) = (address & 0xfffffffe);
}