Skip to content

Commit 03f7fcd

Browse files
committed
[NUCLEO_F401RE] add I2C slave and SPI slave
1 parent 54ec228 commit 03f7fcd

File tree

4 files changed

+134
-15
lines changed

4 files changed

+134
-15
lines changed

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242
#define DEVICE_SERIAL 1
4343

4444
#define DEVICE_I2C 1
45-
#define DEVICE_I2CSLAVE 0 // Not supported yet
45+
#define DEVICE_I2CSLAVE 1
4646

4747
#define DEVICE_SPI 1
48-
#define DEVICE_SPISLAVE 0 // Not supported yet
48+
#define DEVICE_SPISLAVE 1
4949

5050
#define DEVICE_RTC 1
5151

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/i2c_api.c

Lines changed: 130 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
9393

9494
// I2C configuration
9595
i2c_frequency(obj, 100000); // 100 kHz per default
96+
97+
// I2C master by default
98+
obj->slave = 0;
9699
}
97100

98101
void i2c_frequency(i2c_t *obj, int hz) {
@@ -109,6 +112,10 @@ void i2c_frequency(i2c_t *obj, int hz) {
109112
I2cHandle.Init.OwnAddress1 = 0;
110113
I2cHandle.Init.OwnAddress2 = 0;
111114
HAL_I2C_Init(&I2cHandle);
115+
if(obj->slave) {
116+
/* Enable Address Acknowledge */
117+
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
118+
}
112119
}
113120
else {
114121
error("I2C error: frequency setting failed (max 400kHz).");
@@ -233,7 +240,7 @@ void i2c_reset(i2c_t *obj) {
233240

234241
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
235242
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
236-
uint16_t tmpreg;
243+
uint16_t tmpreg = 0;
237244

238245
// Get the old register value
239246
tmpreg = i2c->OAR1;
@@ -246,7 +253,12 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
246253
}
247254

248255
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
249-
// Nothing to do
256+
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
257+
if(enable_slave) {
258+
obj->slave = 1;
259+
/* Enable Address Acknowledge */
260+
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
261+
}
250262
}
251263

252264
// See I2CSlave.h
@@ -256,34 +268,140 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
256268
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
257269

258270
int i2c_slave_receive(i2c_t *obj) {
259-
// TO BE DONE
260-
return(0);
271+
int retValue = NoData;
272+
273+
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
274+
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
275+
if(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
276+
retValue = ReadAddressed;
277+
else
278+
retValue = WriteAddressed;
279+
280+
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
281+
}
282+
}
283+
284+
return(retValue);
261285
}
262286

263287
int i2c_slave_read(i2c_t *obj, char *data, int length) {
288+
uint32_t Timeout;
289+
int size = 0;
264290
if (length == 0) return 0;
265291

266292
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
267293

268-
// Reception process with 5 seconds timeout
269-
if (HAL_I2C_Slave_Receive(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) {
270-
return 0; // Error
294+
while(length > 0)
295+
{
296+
/* Wait until RXNE flag is set */
297+
// Wait until the byte is received
298+
Timeout = FLAG_TIMEOUT;
299+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
300+
Timeout--;
301+
if (Timeout == 0) {
302+
return 0;
303+
}
304+
}
305+
306+
/* Read data from DR */
307+
(*data++) = I2cHandle.Instance->DR;
308+
length--;
309+
size++;
310+
311+
if((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)){
312+
/* Read data from DR */
313+
(*data++) = I2cHandle.Instance->DR;
314+
length--;
315+
size++;
316+
}
271317
}
272318

273-
return length;
319+
/* Wait until STOP flag is set */
320+
Timeout = FLAG_TIMEOUT;
321+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
322+
Timeout--;
323+
if (Timeout == 0) {
324+
return 0;
325+
}
326+
}
327+
328+
/* Clear STOP flag */
329+
__HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
330+
331+
/* Wait until BUSY flag is reset */
332+
Timeout = FLAG_TIMEOUT;
333+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
334+
Timeout--;
335+
if (Timeout == 0) {
336+
return 0;
337+
}
338+
}
339+
340+
return size;
274341
}
275342

276343
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
344+
uint32_t Timeout;
345+
int size = 0;
277346
if (length == 0) return 0;
278347

279348
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
280349

281-
// Transmission process with 5 seconds timeout
282-
if (HAL_I2C_Slave_Transmit(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) {
283-
return 0; // Error
350+
while(length > 0)
351+
{
352+
/* Wait until TXE flag is set */
353+
Timeout = FLAG_TIMEOUT;
354+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
355+
Timeout--;
356+
if (Timeout == 0) {
357+
return 0;
358+
}
359+
}
360+
361+
362+
/* Write data to DR */
363+
I2cHandle.Instance->DR = (*data++);
364+
length--;
365+
size++;
366+
367+
if((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0))
368+
{
369+
/* Write data to DR */
370+
I2cHandle.Instance->DR = (*data++);
371+
length--;
372+
size++;
373+
}
284374
}
375+
376+
/* Wait until AF flag is set */
377+
Timeout = FLAG_TIMEOUT;
378+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
379+
Timeout--;
380+
if (Timeout == 0) {
381+
return 0;
382+
}
383+
}
285384

286-
return length;
385+
386+
/* Clear AF flag */
387+
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
388+
389+
390+
/* Wait until BUSY flag is reset */
391+
Timeout = FLAG_TIMEOUT;
392+
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
393+
Timeout--;
394+
if (Timeout == 0) {
395+
return 0;
396+
}
397+
}
398+
399+
I2cHandle.State = HAL_I2C_STATE_READY;
400+
401+
/* Process Unlocked */
402+
__HAL_UNLOCK(&I2cHandle);
403+
404+
return size;
287405
}
288406

289407

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct spi_s {
8080

8181
struct i2c_s {
8282
I2CName i2c;
83+
uint32_t slave;
8384
};
8485

8586
struct pwmout_s {

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/spi_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ int spi_master_write(spi_t *obj, int value) {
256256
}
257257

258258
int spi_slave_receive(spi_t *obj) {
259-
return (!ssp_busy(obj)) ? (1) : (0);
259+
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
260260
};
261261

262262
int spi_slave_read(spi_t *obj) {

0 commit comments

Comments
 (0)