Merge branch 'master' of git://github.com/dbestm/mbed into dbestm-master

Conflicts:
	libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/device.h
	libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/i2c_api.c
pull/299/head
Bogdan Marinescu 2014-05-07 13:12:08 +01:00
commit f01970e8df
7 changed files with 179 additions and 21 deletions

View File

@ -42,10 +42,10 @@
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0 // Not yet supported #define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1 #define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0 // Not yet supported #define DEVICE_SPISLAVE 1
#define DEVICE_RTC 1 #define DEVICE_RTC 1

View File

@ -181,7 +181,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout; int timeout;
int count; int count;
i2c_start(obj); i2c_start(obj);
// Send slave address for write // Send slave address for write
@ -245,7 +245,7 @@ int i2c_byte_write(i2c_t *obj, int data) {
I2C_SendData(i2c, (uint8_t)data); I2C_SendData(i2c, (uint8_t)data);
// Wait until the byte is transmitted // Wait until the byte is transmitted
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) && while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) &&
(I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) { (I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) {
timeout--; timeout--;
@ -295,7 +295,46 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) { int i2c_slave_receive(i2c_t *obj) {
return (0); int retValue = NoData;
uint32_t event;
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
event = I2C_GetLastEvent( i2c );
if(event != 0)
{
switch(event){
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
retValue = WriteAddressed;
break;
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
retValue = ReadAddressed;
break;
case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
retValue = WriteGeneral;
break;
default:
retValue = NoData;
break;
}
// clear ADDR
if((retValue == WriteAddressed) || (retValue == ReadAddressed)){
// read SR to clear ADDR flag
i2c->SR1;
i2c->SR2;
}
// clear stopf
if(I2C_GetFlagStatus(i2c, I2C_FLAG_STOPF) == SET) {
// read SR1 and write CR1 to clear STOP flag
i2c->SR1;
I2C_Cmd(i2c, ENABLE);
}
// clear AF
if(I2C_GetFlagStatus(i2c, I2C_FLAG_AF) == SET) {
I2C_ClearFlag(i2c, I2C_FLAG_AF);
}
}
return(retValue);
} }
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {

View File

@ -125,7 +125,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
} else { // Slave } else { // Slave
pinmap_pinout(ssel, PinMap_SPI_SSEL); pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->mode = SPI_Mode_Slave; obj->mode = SPI_Mode_Slave;
obj->nss = SPI_NSS_Soft; obj->nss = SPI_NSS_Hard;
} }
init_spi(obj); init_spi(obj);

View File

@ -42,10 +42,10 @@
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0 // Not supported yet #define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1 #define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0 // Not supported yet #define DEVICE_SPISLAVE 1
#define DEVICE_RTC 1 #define DEVICE_RTC 1

View File

@ -93,6 +93,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// I2C configuration // I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default i2c_frequency(obj, 100000); // 100 kHz per default
// I2C master by default
obj->slave = 0;
} }
void i2c_frequency(i2c_t *obj, int hz) { void i2c_frequency(i2c_t *obj, int hz) {
@ -109,6 +112,10 @@ void i2c_frequency(i2c_t *obj, int hz) {
I2cHandle.Init.OwnAddress1 = 0; I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0; I2cHandle.Init.OwnAddress2 = 0;
HAL_I2C_Init(&I2cHandle); HAL_I2C_Init(&I2cHandle);
if(obj->slave) {
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
} }
else { else {
error("I2C error: frequency setting failed (max 400kHz)."); error("I2C error: frequency setting failed (max 400kHz).");
@ -233,7 +240,7 @@ void i2c_reset(i2c_t *obj) {
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg; uint16_t tmpreg = 0;
// Get the old register value // Get the old register value
tmpreg = i2c->OAR1; tmpreg = i2c->OAR1;
@ -246,7 +253,12 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
} }
void i2c_slave_mode(i2c_t *obj, int enable_slave) { void i2c_slave_mode(i2c_t *obj, int enable_slave) {
// Nothing to do I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
if(enable_slave) {
obj->slave = 1;
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
} }
// See I2CSlave.h // See I2CSlave.h
@ -256,34 +268,140 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) { int i2c_slave_receive(i2c_t *obj) {
// TO BE DONE int retValue = NoData;
return(0);
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return(retValue);
} }
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {
uint32_t Timeout;
int size = 0;
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Reception process with 5 seconds timeout while(length > 0)
if (HAL_I2C_Slave_Receive(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) { {
return 0; // Error /* Wait until RXNE flag is set */
// Wait until the byte is received
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
}
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
if((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)){
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
}
} }
return length; /* Wait until STOP flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
}
/* Clear STOP flag */
__HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
}
return size;
} }
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int i2c_slave_write(i2c_t *obj, const char *data, int length) {
uint32_t Timeout;
int size = 0;
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Transmission process with 5 seconds timeout while(length > 0)
if (HAL_I2C_Slave_Transmit(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) { {
return 0; // Error /* Wait until TXE flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
}
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
if((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0))
{
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
}
}
/* Wait until AF flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
}
/* Clear AF flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return 0;
}
} }
return length; I2cHandle.State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(&I2cHandle);
return size;
} }

View File

@ -80,6 +80,7 @@ struct spi_s {
struct i2c_s { struct i2c_s {
I2CName i2c; I2CName i2c;
uint32_t slave;
}; };
struct pwmout_s { struct pwmout_s {

View File

@ -256,7 +256,7 @@ int spi_master_write(spi_t *obj, int value) {
} }
int spi_slave_receive(spi_t *obj) { int spi_slave_receive(spi_t *obj) {
return (!ssp_busy(obj)) ? (1) : (0); return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
}; };
int spi_slave_read(spi_t *obj) { int spi_slave_read(spi_t *obj) {