Skip to content

Commit dd7f89e

Browse files
committed
Merge branch 'master' of https://github.com/stm32duino/Arduino_Core_STM32 into no_enums
2 parents 4922da8 + 740d316 commit dd7f89e

File tree

3 files changed

+183
-15
lines changed

3 files changed

+183
-15
lines changed

cores/arduino/stm32/twi.c

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575

7676
#define SLAVE_MODE_TRANSMIT 0
7777
#define SLAVE_MODE_RECEIVE 1
78+
#define SLAVE_MODE_LISTEN 2
79+
7880

7981
/**
8082
* @}
@@ -261,7 +263,12 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
261263
handle->Init.Timing = timing;
262264
#else
263265
handle->Init.ClockSpeed = timing;
264-
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
266+
/* Standard mode (sm) is up to 100kHz, then it's Fast mode (fm) */
267+
/* In fast mode duty cyble bit must be set in CCR register */
268+
if(timing > 100000)
269+
handle->Init.DutyCycle = I2C_DUTYCYCLE_16_9;
270+
else
271+
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
265272
#endif
266273
handle->Init.OwnAddress1 = ownAddress;
267274
handle->Init.OwnAddress2 = 0xFF;
@@ -283,6 +290,9 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
283290
HAL_I2C_Init(handle);
284291

285292
obj->isMaster = master;
293+
/* Initialize default values */
294+
obj->slaveRxNbData = 0;
295+
obj->slaveMode = SLAVE_MODE_LISTEN;
286296
}
287297

288298
/**
@@ -326,6 +336,12 @@ void i2c_setTiming(i2c_t *obj, uint32_t frequency)
326336
obj->handle.Init.Timing = f;
327337
#else
328338
obj->handle.Init.ClockSpeed = f;
339+
/* Standard mode (sm) is up to 100kHz, then it's Fast mode (fm) */
340+
/* In fast mode duty cyble bit must be set in CCR register */
341+
if(frequency > 100000)
342+
obj->handle.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
343+
else
344+
obj->handle.Init.DutyCycle = I2C_DUTYCYCLE_2;
329345
#endif
330346
/*
331347
else if(frequency <= 600000)
@@ -355,6 +371,11 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
355371
uint32_t tickstart = HAL_GetTick();
356372
uint32_t delta = 0;
357373

374+
/* When size is 0, this is usually an I2C scan / ping to check if device is there and ready */
375+
if (size == 0) {
376+
return i2c_IsDeviceReady(obj, dev_address, 1);
377+
}
378+
358379
do{
359380
if(HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK){
360381
ret = I2C_OK;
@@ -395,9 +416,10 @@ i2c_status_e i2c_slave_write_IT(i2c_t *obj, uint8_t *data, uint16_t size)
395416
// Check the communication status
396417
for(i = 0; i < size; i++) {
397418
obj->i2cTxRxBuffer[i] = *(data+i);
398-
obj->i2cTxRxBufferSize++;
399419
}
400420

421+
obj->i2cTxRxBufferSize = size;
422+
401423
return I2C_OK;
402424
}
403425

@@ -447,8 +469,19 @@ i2c_status_e i2c_IsDeviceReady(i2c_t *obj, uint8_t devAddr, uint32_t trials)
447469
{
448470
i2c_status_e ret = HAL_OK;
449471

450-
if(HAL_I2C_IsDeviceReady( &(obj->handle), devAddr, trials, I2C_TIMEOUT_TICK) != HAL_OK) {
451-
ret = I2C_BUSY;
472+
switch (HAL_I2C_IsDeviceReady( &(obj->handle), devAddr, trials, I2C_TIMEOUT_TICK)) {
473+
case HAL_OK:
474+
ret = HAL_OK;
475+
break;
476+
case HAL_TIMEOUT:
477+
ret = I2C_TIMEOUT;
478+
break;
479+
case HAL_BUSY:
480+
ret = I2C_BUSY;
481+
break;
482+
default:
483+
ret = I2C_TIMEOUT;
484+
break;
452485
}
453486

454487
return ret;
@@ -509,8 +542,6 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
509542

510543
if(AddrMatchCode == hi2c->Init.OwnAddress1) {
511544
if(TransferDirection == I2C_DIRECTION_RECEIVE) {
512-
513-
obj->i2cTxRxBufferSize = 0;
514545
obj->slaveMode = SLAVE_MODE_TRANSMIT;
515546

516547
if(obj->i2c_onSlaveTransmit != NULL) {
@@ -519,9 +550,12 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
519550
HAL_I2C_Slave_Sequential_Transmit_IT(hi2c, obj->i2cTxRxBuffer,
520551
obj->i2cTxRxBufferSize, I2C_LAST_FRAME);
521552
} else {
553+
obj->slaveRxNbData = 0;
522554
obj->slaveMode = SLAVE_MODE_RECEIVE;
523-
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, obj->i2cTxRxBuffer,
524-
I2C_TXRX_BUFFER_SIZE, I2C_LAST_FRAME);
555+
/* We don't know in advance how many bytes will be sent by master so
556+
* we'll fetch one by one until master ends the sequence */
557+
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, &(obj->i2cTxRxBuffer[obj->slaveRxNbData]),
558+
1, I2C_NEXT_FRAME);
525559
}
526560
}
527561
}
@@ -534,19 +568,56 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
534568
*/
535569
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
536570
{
537-
uint8_t nbData = 0;
538571
i2c_t *obj = get_i2c_obj(hi2c);
539572

573+
/* Previous master transaction now ended, so inform upper layer if needed
574+
* then prepare for listening to next request */
540575
if((obj->i2c_onSlaveReceive != NULL) &&
541576
(obj->slaveMode == SLAVE_MODE_RECEIVE)) {
542-
nbData = I2C_TXRX_BUFFER_SIZE - obj->handle.XferSize;
543-
if(nbData != 0) {
544-
obj->i2c_onSlaveReceive(obj->i2cTxRxBuffer, nbData);
577+
if(obj->slaveRxNbData != 0) {
578+
obj->i2c_onSlaveReceive(obj->i2cTxRxBuffer, obj->slaveRxNbData);
545579
}
546580
}
581+
obj->slaveMode = SLAVE_MODE_LISTEN;
582+
obj->slaveRxNbData = 0;
547583
HAL_I2C_EnableListen_IT(hi2c);
548584
}
549585

586+
/**
587+
* @brief Slave RX complete callback
588+
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
589+
* the configuration information for the specified I2C.
590+
* @retval None
591+
*/
592+
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
593+
{
594+
i2c_t *obj = get_i2c_obj(hi2c);
595+
/* One more byte was received, store it then prepare next */
596+
if(obj->slaveRxNbData < I2C_TXRX_BUFFER_SIZE) {
597+
obj->slaveRxNbData++;
598+
} else {
599+
printf("ERROR: I2C Slave RX overflow\n");
600+
}
601+
/* Restart interrupt mode for next Byte */
602+
if(obj->slaveMode == SLAVE_MODE_RECEIVE) {
603+
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, &(obj->i2cTxRxBuffer[obj->slaveRxNbData]),
604+
1, I2C_NEXT_FRAME);
605+
}
606+
}
607+
608+
/**
609+
* @brief Slave TX complete callback
610+
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
611+
* the configuration information for the specified I2C.
612+
* @retval None
613+
*/
614+
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
615+
{
616+
i2c_t *obj = get_i2c_obj(hi2c);
617+
/* Reset transmit buffer size */
618+
obj->i2cTxRxBufferSize = 0;
619+
}
620+
550621
/**
551622
* @brief I2C error callback.
552623
* @note In master mode, the callback is not used because the error is reported

cores/arduino/stm32/twi.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ struct i2c_s {
9191
#if !defined(STM32F0xx) && !defined(STM32L0xx)
9292
IRQn_Type irqER;
9393
#endif //!defined(STM32F0xx) && !defined(STM32L0xx)
94-
uint8_t slaveMode;
94+
volatile uint8_t slaveMode;
9595
uint8_t isMaster;
96+
volatile int slaveRxNbData; // Number of accumulated bytes received in Slave mode
9697
void (*i2c_onSlaveReceive)(uint8_t *, int);
9798
void (*i2c_onSlaveTransmit)(void);
98-
uint8_t i2cTxRxBuffer[I2C_TXRX_BUFFER_SIZE];
99-
uint8_t i2cTxRxBufferSize;
99+
volatile uint8_t i2cTxRxBuffer[I2C_TXRX_BUFFER_SIZE];
100+
volatile uint8_t i2cTxRxBufferSize;
100101
};
101102

102103
///@brief I2C state
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// --------------------------------------
2+
// i2c_scanner
3+
//
4+
// Version 1
5+
// This program (or code that looks like it)
6+
// can be found in many places.
7+
// For example on the Arduino.cc forum.
8+
// The original author is not know.
9+
// Version 2, Juni 2012, Using Arduino 1.0.1
10+
// Adapted to be as simple as possible by Arduino.cc user Krodal
11+
// Version 3, Feb 26 2013
12+
// V3 by louarnold
13+
// Version 4, March 3, 2013, Using Arduino 1.0.3
14+
// by Arduino.cc user Krodal.
15+
// Changes by louarnold removed.
16+
// Scanning addresses changed from 0...127 to 1...119,
17+
// according to the i2c scanner by Nick Gammon
18+
// http://www.gammon.com.au/forum/?id=10896
19+
// Version 5, March 28, 2013
20+
// As version 4, but address scans now to 127.
21+
// A sensor seems to use address 120.
22+
//
23+
// This sketch tests the standard 7-bit addresses
24+
// Devices with higher bit address might not be seen properly.
25+
//
26+
27+
28+
29+
// Example pinmap for Bluepill I2Cs (by Testato)
30+
//
31+
// I2C-1 standard pins: PB7(sda) PB6(scl)
32+
// Use it by "Wire" without pin declaration
33+
//
34+
// I2C-1 alternative pins: PB9(sda) PB8(scl)
35+
// Remap the first I2C before call begin()
36+
// Wire.setSDA(PB9);
37+
// Wire.setSCL(PB8);
38+
// Wire.begin();
39+
//
40+
// I2C-2: PB11(sda) PB10(scl)
41+
// Wire.setSDA(PB11);
42+
// Wire.setSCL(PB10);
43+
//
44+
// If you want to use the two I2Cs simultaneously, create a new instance for the second I2C
45+
// TwoWire Wire2(PB11,PB10);
46+
47+
48+
49+
#include <Wire.h>
50+
51+
52+
void setup() {
53+
54+
Serial.begin(9600);
55+
Wire.begin();
56+
Serial.println("\nI2C Scanner");
57+
}
58+
59+
60+
void loop() {
61+
byte error, address;
62+
int nDevices;
63+
64+
Serial.println("Scanning...");
65+
66+
nDevices = 0;
67+
for(address = 1; address < 127; address++) {
68+
// The i2c_scanner uses the return value of
69+
// the Write.endTransmisstion to see if
70+
// a device did acknowledge to the address.
71+
72+
Wire.beginTransmission(address);
73+
error = Wire.endTransmission();
74+
75+
if (error == 0) {
76+
Serial.print("I2C device found at address 0x");
77+
if (address < 16)
78+
Serial.print("0");
79+
Serial.println(address, HEX);
80+
81+
nDevices++;
82+
}
83+
else if (error == 4) {
84+
Serial.print("Unknown error at address 0x");
85+
if (address < 16)
86+
Serial.print("0");
87+
Serial.println(address, HEX);
88+
}
89+
}
90+
if (nDevices == 0)
91+
Serial.println("No I2C devices found");
92+
else
93+
Serial.println("done");
94+
95+
delay(5000); // wait 5 seconds for next scan
96+
}

0 commit comments

Comments
 (0)