Skip to content

Commit c9ceea2

Browse files
committed
use a macro for timeout handling
1 parent bea2530 commit c9ceea2

3 files changed

Lines changed: 61 additions & 24 deletions

File tree

docs/api/I2C.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,35 @@ Errorcode | Meaning: Waiting for...
4444
5 |Waiting for ACK/NACK while addressing slave in receiver mode (MR)
4545
6 |Waiting for ACK/NACK while receiving data from the slave
4646
7 |Waiting for successful completion of the Stop bit
47+
48+
49+
## AVR error codes
50+
51+
Status Codes| for Master Transmitter Mode
52+
--- |---
53+
0x08 |A START condition has been transmitted
54+
0x10 |A repeated START condition has been transmitted
55+
0x18 |SLA+W has been transmitted; ACK has been received
56+
0x20 |SLA+W has been transmitted; NOT ACK has been received
57+
0x28 |Data byte has been transmitted; ACK has been received
58+
0x30 |Data byte has been transmitted; NOT ACK has been received
59+
0x38 |Arbitration lost in SLA+W or data bytes
60+
61+
Status Codes| for Master Receiver Mode
62+
--- |---
63+
0x08 |A START condition has been transmitted
64+
0x10 |A repeated START condition has been transmitted
65+
0x38 |Arbitration lost in SLA+R or NOT ACK bit
66+
0x40 |SLA+R has been transmitted; ACK has been received
67+
0x48 |SLA+R has been transmitted; NOT ACK has been received
68+
0x50 |Data byte has been received; ACK has been returned
69+
0x58 |Data byte has been received; NOT ACK has been returned
70+
71+
72+
Status Codes| independed of mode
73+
--- |---
74+
0xF8 |No relevant state information available; TWINT = “0”
75+
0x00 |Bus error due to an illegal START or STOP condition
76+
77+
Es braucht also SR1 und SR2
78+
0x20 ist nicht abzubilden.

sduino/hardware/sduino/stm8/libraries/I2C/I2C.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ static uint8_t stop(void);
8686
static void lockUp(void);
8787

8888

89+
#define TIMEOUT_WAIT_WHILE(CONDITION,ERROR) \
90+
while (CONDITION) /* wait for the required condition */ \
91+
{ \
92+
if(!timeOutDelay){continue;} \
93+
if((millis() - startingTime) >= timeOutDelay) \
94+
{ \
95+
lockUp(); \
96+
return(ERROR); /* return the appropriate error code */ \
97+
} \
98+
}
99+
100+
89101
////////////// Public Methods ////////////////////////////////////////
90102

91103

@@ -129,12 +141,10 @@ void I2C_end()
129141
}
130142
#endif
131143

132-
#if 1
133144
void I2C_timeOut(uint16_t _timeOut)
134145
{
135146
timeOutDelay = _timeOut;
136147
}
137-
#endif
138148

139149
#if 0
140150
void I2C_setSpeed(uint8_t _fast)
@@ -184,7 +194,6 @@ void I2C_pullup(uint8_t activate)
184194
}
185195
#endif
186196

187-
#if 1
188197
void I2C_scan()
189198
{
190199
uint16_t tempTime = timeOutDelay;
@@ -227,7 +236,6 @@ void I2C_scan()
227236
if(!totalDevicesFound){Serial_println_s("No devices found");}
228237
timeOutDelay = tempTime;
229238
}
230-
#endif
231239

232240
uint8_t I2C_available()
233241
{
@@ -586,6 +594,12 @@ uint8_t I2C_read_sn(uint8_t address, uint8_t registerAddress, uint8_t numberByte
586594

587595
/////////////// Private Methods ////////////////////////////////////////
588596

597+
/**
598+
* send a start sequence
599+
*
600+
* in contrast to the AVR version it does not wait for start to finish for
601+
* the STM8. The timeout is handled in sendAddress().
602+
*/
589603
static uint8_t start(void)
590604
{
591605
#if 0
@@ -613,7 +627,7 @@ static uint8_t start(void)
613627
}
614628
return(TWI_STATUS);
615629
#else
616-
I2C->CR2 |= I2C_CR2_START; // I2C_GenerateSTART(enable);
630+
I2C->CR2 |= I2C_CR2_START; // send start sequence
617631
return 0;
618632
#endif
619633
}
@@ -708,15 +722,8 @@ uint8_t sendByte(uint8_t i2cData)
708722
unsigned long startingTime = millis(); // FIXME: uint16_t could be used
709723

710724
/* Test on EV8 */
711-
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
712-
{
713-
if(!timeOutDelay){continue;}
714-
if((millis() - startingTime) >= timeOutDelay)
715-
{
716-
lockUp();
717-
return(3); // no ACK received on data transmission
718-
}
719-
}
725+
TIMEOUT_WAIT_WHILE(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING), 3);
726+
// error 3: no ACK received on data transmission
720727

721728
I2C->DR = i2cData;
722729
return 0;
@@ -730,7 +737,6 @@ static uint8_t receiveByte(uint8_t ack)
730737
if(ack)
731738
{
732739
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
733-
734740
}
735741
else
736742
{
@@ -776,19 +782,15 @@ static uint8_t stop(void)
776782
}
777783
#else
778784
unsigned long startingTime = millis(); // FIXME: uint16_t could be used
785+
779786
/* Test on EV8_2 */
780-
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
781-
{
782-
if(!timeOutDelay){continue;}
783-
if((millis() - startingTime) >= timeOutDelay)
784-
{
785-
lockUp();
786-
return(3); // no ACK received on data transmission
787-
}
788-
}
787+
TIMEOUT_WAIT_WHILE(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED), 3);
788+
// error 3: no ACK received on data transmission
789789

790790
/* Generate a STOP condition */
791791
I2C->CR2 |= I2C_CR2_STOP;
792+
793+
TIMEOUT_WAIT_WHILE(!(I2C->SR1 & I2C_SR1_STOPF), 7);
792794
#endif
793795
return(0);
794796
}

sduino/hardware/sduino/stm8/libraries/I2C/I2C.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#define I2C_h
7070

7171

72+
/* TWI status codes for AVR
7273
#define START 0x08
7374
#define REPEATED_START 0x10
7475
#define MT_SLA_ACK 0x18
@@ -81,6 +82,8 @@
8182
#define MR_DATA_NACK 0x58
8283
#define LOST_ARBTRTN 0x38
8384
#define TWI_STATUS (TWSR & 0xF8)
85+
*/
86+
#define LOST_ARBTRTN 0x38
8487
#define SLA_W(address) (address << 1)
8588
#define SLA_R(address) ((address << 1) + 0x01)
8689
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

0 commit comments

Comments
 (0)