@@ -40,8 +40,8 @@ extern "C" {
40
40
{
41
41
GPEC = (1 << twi_sda);
42
42
}
43
- static inline __attribute__ ((always_inline)) bool SDA_READ(const int twi_sda)
44
- {
43
+ static inline __attribute__ ((always_inline)) bool SDA_READ(const int twi_sda)
44
+ {
45
45
return (GPI & (1 << twi_sda)) != 0 ;
46
46
}
47
47
static inline __attribute__ ((always_inline)) void SCL_LOW(const int twi_scl)
@@ -52,8 +52,8 @@ extern "C" {
52
52
{
53
53
GPEC = (1 << twi_scl);
54
54
}
55
- static inline __attribute__ ((always_inline)) bool SCL_READ(const int twi_scl)
56
- {
55
+ static inline __attribute__ ((always_inline)) bool SCL_READ(const int twi_scl)
56
+ {
57
57
return (GPI & (1 << twi_scl)) != 0 ;
58
58
}
59
59
@@ -63,7 +63,7 @@ class Twi
63
63
{
64
64
private:
65
65
unsigned int preferred_si2c_clock = 100000 ;
66
- unsigned char twi_dcount = 18 ;
66
+ uint32_t twi_dcount = 18 ;
67
67
unsigned char twi_sda = 0 ;
68
68
unsigned char twi_scl = 0 ;
69
69
unsigned char twi_addr = 0 ;
@@ -112,7 +112,7 @@ class Twi
112
112
bool _slaveEnabled = false ;
113
113
114
114
// Internal use functions
115
- void ICACHE_RAM_ATTR busywait (unsigned char v);
115
+ void ICACHE_RAM_ATTR busywait (unsigned int v);
116
116
bool write_start (void );
117
117
bool write_stop (void );
118
118
bool write_bit (bool bit);
@@ -148,7 +148,6 @@ class Twi
148
148
void attachSlaveRxEvent (void (*function)(uint8_t *, size_t ));
149
149
void attachSlaveTxEvent (void (*function)(void ));
150
150
void ICACHE_RAM_ATTR reply (uint8_t ack);
151
- void ICACHE_RAM_ATTR stop (void );
152
151
void ICACHE_RAM_ATTR releaseBus (void );
153
152
void enableSlave ();
154
153
};
@@ -161,65 +160,25 @@ static Twi twi;
161
160
162
161
void Twi::setClock (unsigned int freq)
163
162
{
163
+ if (freq < 1000 ) // minimum freq 1000Hz to minimize slave timeouts and WDT resets
164
+ freq = 1000 ;
165
+
164
166
preferred_si2c_clock = freq;
167
+
165
168
#if F_CPU == FCPU80
166
- if (freq <= 50000 )
167
- {
168
- twi_dcount = 38 ; // about 50KHz
169
- }
170
- else if (freq <= 100000 )
171
- {
172
- twi_dcount = 19 ; // about 100KHz
173
- }
174
- else if (freq <= 200000 )
175
- {
176
- twi_dcount = 8 ; // about 200KHz
177
- }
178
- else if (freq <= 300000 )
179
- {
180
- twi_dcount = 3 ; // about 300KHz
181
- }
182
- else if (freq <= 400000 )
183
- {
184
- twi_dcount = 1 ; // about 400KHz
185
- }
186
- else
187
- {
188
- twi_dcount = 1 ; // about 400KHz
189
- }
169
+
170
+ if (freq > 400000 )
171
+ freq = 400000 ;
172
+ twi_dcount = (500000000 / freq); // half-cycle period in ns
173
+ twi_dcount = (1000 *(twi_dcount - 1120 )) / 62500 ; // (half cycle - overhead) / busywait loop time
174
+
190
175
#else
191
- if (freq <= 50000 )
192
- {
193
- twi_dcount = 64 ; // about 50KHz
194
- }
195
- else if (freq <= 100000 )
196
- {
197
- twi_dcount = 32 ; // about 100KHz
198
- }
199
- else if (freq <= 200000 )
200
- {
201
- twi_dcount = 14 ; // about 200KHz
202
- }
203
- else if (freq <= 300000 )
204
- {
205
- twi_dcount = 8 ; // about 300KHz
206
- }
207
- else if (freq <= 400000 )
208
- {
209
- twi_dcount = 5 ; // about 400KHz
210
- }
211
- else if (freq <= 500000 )
212
- {
213
- twi_dcount = 3 ; // about 500KHz
214
- }
215
- else if (freq <= 600000 )
216
- {
217
- twi_dcount = 2 ; // about 600KHz
218
- }
219
- else
220
- {
221
- twi_dcount = 1 ; // about 700KHz
222
- }
176
+
177
+ if (freq > 800000 )
178
+ freq = 800000 ;
179
+ twi_dcount = (500000000 / freq); // half-cycle period in ns
180
+ twi_dcount = (1000 *(twi_dcount - 560 )) / 31250 ; // (half cycle - overhead) / busywait loop time
181
+
223
182
#endif
224
183
}
225
184
@@ -262,18 +221,13 @@ void Twi::enableSlave()
262
221
}
263
222
}
264
223
265
- void ICACHE_RAM_ATTR Twi::busywait (unsigned char v)
224
+ void ICACHE_RAM_ATTR Twi::busywait (unsigned int v)
266
225
{
267
226
unsigned int i;
268
- #pragma GCC diagnostic push
269
- #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
270
- unsigned int reg;
271
- for (i = 0 ; i < v; i++)
227
+ for (i = 0 ; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz
272
228
{
273
- reg = GPI;
229
+ asm ( " nop " ); // minimum element to keep GCC from optimizing this function out.
274
230
}
275
- (void )reg;
276
- #pragma GCC diagnostic pop
277
231
}
278
232
279
233
bool Twi::write_start (void )
@@ -518,35 +472,24 @@ void ICACHE_RAM_ATTR Twi::reply(uint8_t ack)
518
472
if (ack)
519
473
{
520
474
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
521
- SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
522
- twi_ack = 1 ; // _BV(TWEA)
475
+ SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
476
+ twi_ack = 1 ; // _BV(TWEA)
523
477
}
524
478
else
525
479
{
526
480
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
527
- SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
528
- twi_ack = 0 ; // ~_BV(TWEA)
481
+ SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
482
+ twi_ack = 0 ; // ~_BV(TWEA)
529
483
}
530
484
}
531
485
532
- void ICACHE_RAM_ATTR Twi::stop (void )
533
- {
534
- // send stop condition
535
- // TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
536
- SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
537
- twi_ack = 1 ; // _BV(TWEA)
538
- busywait (5 ); // Maybe this should be here
539
- SDA_HIGH (twi.twi_sda ); // _BV(TWSTO)
540
- // update twi state
541
- twi_state = TWI_READY;
542
- }
543
486
544
487
void ICACHE_RAM_ATTR Twi::releaseBus (void )
545
488
{
546
489
// release bus
547
490
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
548
- SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
549
- twi_ack = 1 ; // _BV(TWEA)
491
+ SCL_HIGH (twi.twi_scl ); // _BV(TWINT)
492
+ twi_ack = 1 ; // _BV(TWEA)
550
493
SDA_HIGH (twi.twi_sda );
551
494
552
495
// update twi state
@@ -657,7 +600,6 @@ void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status)
657
600
break ;
658
601
case TW_BUS_ERROR: // bus error, illegal stop/start
659
602
twi_error = TW_BUS_ERROR;
660
- stop ();
661
603
break ;
662
604
}
663
605
}
@@ -718,11 +660,11 @@ void ICACHE_RAM_ATTR Twi::onSclChange(void)
718
660
unsigned int scl;
719
661
720
662
// Store bool return in int to reduce final code size.
721
-
663
+
722
664
sda = SDA_READ (twi.twi_sda );
723
665
scl = SCL_READ (twi.twi_scl );
724
666
725
- twi.twip_status = 0xF8 ; // reset TWI status
667
+ twi.twip_status = 0xF8 ; // reset TWI status
726
668
727
669
int twip_state_mask = S2M (twi.twip_state );
728
670
IFSTATE (S2M (TWIP_START) | S2M (TWIP_REP_START) | S2M (TWIP_SLA_W) | S2M (TWIP_READ))
@@ -797,7 +739,7 @@ void ICACHE_RAM_ATTR Twi::onSclChange(void)
797
739
}
798
740
else
799
741
{
800
- SCL_LOW (twi.twi_scl ); // clock stretching
742
+ SCL_LOW (twi.twi_scl ); // clock stretching
801
743
SDA_HIGH (twi.twi_sda );
802
744
twi.twip_mode = TWIPM_ADDRESSED;
803
745
if (!(twi.twi_data & 0x01 ))
@@ -815,7 +757,7 @@ void ICACHE_RAM_ATTR Twi::onSclChange(void)
815
757
}
816
758
else
817
759
{
818
- SCL_LOW (twi.twi_scl ); // clock stretching
760
+ SCL_LOW (twi.twi_scl ); // clock stretching
819
761
SDA_HIGH (twi.twi_sda );
820
762
if (!twi.twi_ack )
821
763
{
@@ -893,7 +835,7 @@ void ICACHE_RAM_ATTR Twi::onSclChange(void)
893
835
}
894
836
else
895
837
{
896
- SCL_LOW (twi.twi_scl ); // clock stretching
838
+ SCL_LOW (twi.twi_scl ); // clock stretching
897
839
if (twi.twi_ack && twi.twi_ack_rec )
898
840
{
899
841
twi.onTwipEvent (TW_ST_DATA_ACK);
@@ -939,7 +881,7 @@ void ICACHE_RAM_ATTR Twi::onSdaChange(void)
939
881
else IFSTATE (S2M (TWIP_START) | S2M (TWIP_REP_START) | S2M (TWIP_SEND_ACK) | S2M (TWIP_WAIT_ACK) | S2M (TWIP_SLA_R) | S2M (TWIP_REC_ACK) | S2M (TWIP_READ_ACK) | S2M (TWIP_RWAIT_ACK) | S2M (TWIP_WRITE))
940
882
{
941
883
// START or STOP
942
- SDA_HIGH (twi.twi_sda ); // Should not be necessary
884
+ SDA_HIGH (twi.twi_sda ); // Should not be necessary
943
885
twi.onTwipEvent (TW_BUS_ERROR);
944
886
twi.twip_mode = TWIPM_WAIT;
945
887
twi.twip_state = TWIP_BUS_ERR;
@@ -949,7 +891,7 @@ void ICACHE_RAM_ATTR Twi::onSdaChange(void)
949
891
if (sda)
950
892
{
951
893
// STOP
952
- SCL_LOW (twi.twi_scl ); // clock stretching
894
+ SCL_LOW (twi.twi_scl ); // generates a low SCL pulse after STOP
953
895
ets_timer_disarm (&twi.timer );
954
896
twi.twip_state = TWIP_IDLE;
955
897
twi.twip_mode = TWIPM_IDLE;
@@ -983,7 +925,7 @@ void ICACHE_RAM_ATTR Twi::onSdaChange(void)
983
925
else
984
926
{
985
927
// during first bit in byte transfer - ok
986
- SCL_LOW (twi.twi_scl ); // clock stretching
928
+ SCL_LOW (twi.twi_scl ); // clock stretching
987
929
twi.onTwipEvent (TW_SR_STOP);
988
930
if (sda)
989
931
{
@@ -1018,11 +960,6 @@ extern "C" {
1018
960
return twi.setAddress (a);
1019
961
}
1020
962
1021
- void twi_stop (void )
1022
- {
1023
- twi.stop ();
1024
- }
1025
-
1026
963
void twi_setClock (unsigned int freq)
1027
964
{
1028
965
twi.setClock (freq);
0 commit comments