Merge pull request #802 from masaohamanaka/master

Targets: RZ_A1H - Fix some drivers bugs and modify some settings of OS and
pull/806/head^2
Martin Kojtal 2014-12-19 08:53:10 +00:00
commit 078c36b1c5
8 changed files with 558 additions and 422 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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