@@ -522,6 +522,14 @@ static void eventTask(ETSEvent *e)
522
522
}
523
523
}
524
524
525
+ // The state machine is converted from a 0...15 state to a 1-hot encoded state, and then
526
+ // compared to the logical-or of all states with the same branch. This removes the need
527
+ // for a large series of straight-line compares. The biggest win is when multiple states
528
+ // all have the same branch (onSdaChange), but for others there is some benefit, still.
529
+ #define S2M (x ) (1 <<(x))
530
+ // Shorthand for if the state is any of the or'd bitmask x
531
+ #define IFSTATE (x ) if (twip_state_mask & (x))
532
+
525
533
void ICACHE_RAM_ATTR onSclChange (void )
526
534
{
527
535
unsigned int sda;
@@ -532,151 +540,124 @@ void ICACHE_RAM_ATTR onSclChange(void)
532
540
533
541
twip_status = 0xF8 ; // reset TWI status
534
542
535
- switch (twip_state)
536
- {
537
- case TWIP_IDLE:
538
- case TWIP_WAIT_STOP:
539
- case TWIP_BUS_ERR:
543
+ int twip_state_mask = S2M (twip_state);
544
+ IFSTATE (S2M (TWIP_START)|S2M (TWIP_REP_START)|S2M (TWIP_SLA_W)|S2M (TWIP_READ)) {
545
+ if (!scl) {
540
546
// ignore
541
- break ;
547
+ } else {
548
+ bitCount--;
549
+ twi_data <<= 1 ;
550
+ twi_data |= sda;
542
551
543
- case TWIP_START:
544
- case TWIP_REP_START:
545
- case TWIP_SLA_W:
546
- case TWIP_READ:
547
- if (!scl) {
548
- // ignore
552
+ if (bitCount != 0 ) {
553
+ // continue
549
554
} else {
550
- bitCount--;
551
- twi_data <<= 1 ;
552
- twi_data |= sda;
553
-
554
- if (bitCount != 0 ) {
555
- // continue
555
+ twip_state = TWIP_SEND_ACK;
556
+ }
557
+ }
558
+ } else IFSTATE (S2M (TWIP_SEND_ACK)) {
559
+ if (scl) {
560
+ // ignore
561
+ } else {
562
+ if (twip_mode == TWIPM_IDLE) {
563
+ if ((twi_data & 0xFE ) != twi_addr) {
564
+ // ignore
556
565
} else {
557
- twip_state = TWIP_SEND_ACK ;
566
+ SDA_LOW () ;
558
567
}
559
- }
560
- break ;
561
-
562
- case TWIP_SEND_ACK:
563
- if (scl) {
564
- // ignore
565
568
} else {
566
- if (twip_mode == TWIPM_IDLE) {
567
- if ((twi_data & 0xFE ) != twi_addr) {
568
- // ignore
569
- } else {
570
- SDA_LOW ();
571
- }
569
+ if (!twi_ack) {
570
+ // ignore
572
571
} else {
573
- if (!twi_ack) {
574
- // ignore
575
- } else {
576
- SDA_LOW ();
577
- }
572
+ SDA_LOW ();
578
573
}
579
- twip_state = TWIP_WAIT_ACK;
580
574
}
581
- break ;
582
-
583
- case TWIP_WAIT_ACK:
584
- if (scl) {
585
- // ignore
586
- } else {
587
- if (twip_mode == TWIPM_IDLE) {
588
- if ((twi_data & 0xFE ) != twi_addr) {
589
- SDA_HIGH ();
590
- twip_state = TWIP_WAIT_STOP;
591
- } else {
592
- SCL_LOW (); // clock stretching
593
- SDA_HIGH ();
594
- twip_mode = TWIPM_ADDRESSED;
595
- if (!(twi_data & 0x01 )) {
596
- twip_status = TW_SR_SLA_ACK;
597
- twi_onTwipEvent (twip_status);
598
- bitCount = 8 ;
599
- twip_state = TWIP_SLA_W;
600
- } else {
601
- twip_status = TW_ST_SLA_ACK;
602
- twi_onTwipEvent (twip_status);
603
- twip_state = TWIP_SLA_R;
604
- }
605
- }
575
+ twip_state = TWIP_WAIT_ACK;
576
+ }
577
+ } else IFSTATE (S2M (TWIP_WAIT_ACK)) {
578
+ if (scl) {
579
+ // ignore
580
+ } else {
581
+ if (twip_mode == TWIPM_IDLE) {
582
+ if ((twi_data & 0xFE ) != twi_addr) {
583
+ SDA_HIGH ();
584
+ twip_state = TWIP_WAIT_STOP;
606
585
} else {
607
586
SCL_LOW (); // clock stretching
608
587
SDA_HIGH ();
609
- if (!twi_ack) {
610
- twip_status = TW_SR_DATA_NACK;
588
+ twip_mode = TWIPM_ADDRESSED;
589
+ if (!(twi_data & 0x01 )) {
590
+ twip_status = TW_SR_SLA_ACK;
611
591
twi_onTwipEvent (twip_status);
612
- twip_mode = TWIPM_WAIT ;
613
- twip_state = TWIP_WAIT_STOP ;
592
+ bitCount = 8 ;
593
+ twip_state = TWIP_SLA_W ;
614
594
} else {
615
- twip_status = TW_SR_DATA_ACK ;
595
+ twip_status = TW_ST_SLA_ACK ;
616
596
twi_onTwipEvent (twip_status);
617
- bitCount = 8 ;
618
- twip_state = TWIP_READ;
597
+ twip_state = TWIP_SLA_R;
619
598
}
620
599
}
621
- }
622
- break ;
623
-
624
- case TWIP_SLA_R:
625
- case TWIP_WRITE:
626
- if (scl) {
627
- // ignore
628
600
} else {
629
- bitCount--;
630
- (twi_data & 0x80 ) ? SDA_HIGH () : SDA_LOW ();
631
- twi_data <<= 1 ;
632
-
633
- if (bitCount != 0 ) {
634
- // continue
601
+ SCL_LOW (); // clock stretching
602
+ SDA_HIGH ();
603
+ if (!twi_ack) {
604
+ twip_status = TW_SR_DATA_NACK;
605
+ twi_onTwipEvent (twip_status);
606
+ twip_mode = TWIPM_WAIT;
607
+ twip_state = TWIP_WAIT_STOP;
635
608
} else {
636
- twip_state = TWIP_REC_ACK;
609
+ twip_status = TW_SR_DATA_ACK;
610
+ twi_onTwipEvent (twip_status);
611
+ bitCount = 8 ;
612
+ twip_state = TWIP_READ;
637
613
}
638
614
}
639
- break ;
640
-
641
- case TWIP_REC_ACK:
642
- if (scl) {
643
- // ignore
644
- } else {
645
- SDA_HIGH ();
646
- twip_state = TWIP_READ_ACK;
647
- }
648
- break ;
615
+ }
616
+ } else IFSTATE (S2M (TWIP_SLA_R)|S2M (TWIP_WRITE)) {
617
+ if (scl) {
618
+ // ignore
619
+ } else {
620
+ bitCount--;
621
+ (twi_data & 0x80 ) ? SDA_HIGH () : SDA_LOW ();
622
+ twi_data <<= 1 ;
649
623
650
- case TWIP_READ_ACK:
651
- if (!scl) {
652
- // ignore
624
+ if (bitCount != 0 ) {
625
+ // continue
653
626
} else {
654
- twi_ack_rec = !sda;
655
- twip_state = TWIP_RWAIT_ACK;
627
+ twip_state = TWIP_REC_ACK;
656
628
}
657
- break ;
658
-
659
- case TWIP_RWAIT_ACK:
660
- if (scl) {
661
- // ignore
629
+ }
630
+ } else IFSTATE (S2M (TWIP_REC_ACK)) {
631
+ if (scl) {
632
+ // ignore
633
+ } else {
634
+ SDA_HIGH ();
635
+ twip_state = TWIP_READ_ACK;
636
+ }
637
+ } else IFSTATE (S2M (TWIP_READ_ACK)) {
638
+ if (!scl) {
639
+ // ignore
640
+ } else {
641
+ twi_ack_rec = !sda;
642
+ twip_state = TWIP_RWAIT_ACK;
643
+ }
644
+ } else IFSTATE (S2M (TWIP_RWAIT_ACK)) {
645
+ if (scl) {
646
+ // ignore
647
+ } else {
648
+ SCL_LOW (); // clock stretching
649
+ if (twi_ack && twi_ack_rec) {
650
+ twip_status = TW_ST_DATA_ACK;
651
+ twi_onTwipEvent (twip_status);
652
+ twip_state = TWIP_WRITE;
662
653
} else {
663
- SCL_LOW (); // clock stretching
664
- if (twi_ack && twi_ack_rec) {
665
- twip_status = TW_ST_DATA_ACK;
666
- twi_onTwipEvent (twip_status);
667
- twip_state = TWIP_WRITE;
668
- } else {
669
- // we have no more data to send and/or the master doesn't want anymore
670
- twip_status = twi_ack_rec ? TW_ST_LAST_DATA : TW_ST_DATA_NACK;
671
- twi_onTwipEvent (twip_status);
672
- twip_mode = TWIPM_WAIT;
673
- twip_state = TWIP_WAIT_STOP;
674
- }
654
+ // we have no more data to send and/or the master doesn't want anymore
655
+ twip_status = twi_ack_rec ? TW_ST_LAST_DATA : TW_ST_DATA_NACK;
656
+ twi_onTwipEvent (twip_status);
657
+ twip_mode = TWIPM_WAIT;
658
+ twip_state = TWIP_WAIT_STOP;
675
659
}
676
- break ;
677
-
678
- default :
679
- break ;
660
+ }
680
661
}
681
662
}
682
663
@@ -687,9 +668,9 @@ void ICACHE_RAM_ATTR onSdaChange(void)
687
668
sda = SDA_READ ();
688
669
scl = SCL_READ ();
689
670
690
- if (scl) /* !DATA */ switch (twip_state)
691
- {
692
- case TWIP_IDLE:
671
+ int twip_state_mask = S2M (twip_state);
672
+ if (scl) { /* !DATA */
673
+ IFSTATE ( S2M ( TWIP_IDLE)) {
693
674
if (sda) {
694
675
// STOP - ignore
695
676
} else {
@@ -698,27 +679,14 @@ void ICACHE_RAM_ATTR onSdaChange(void)
698
679
twip_state = TWIP_START;
699
680
ets_timer_arm_new (&timer, twi_timeout_ms, false , true ); // Once, ms
700
681
}
701
- break ;
702
-
703
- case TWIP_START:
704
- case TWIP_REP_START:
705
- case TWIP_SEND_ACK:
706
- case TWIP_WAIT_ACK:
707
- case TWIP_SLA_R:
708
- case TWIP_REC_ACK:
709
- case TWIP_READ_ACK:
710
- case TWIP_RWAIT_ACK:
711
- case TWIP_WRITE:
682
+ } 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)) {
712
683
// START or STOP
713
684
SDA_HIGH (); // Should not be necessary
714
685
twip_status = TW_BUS_ERROR;
715
686
twi_onTwipEvent (twip_status);
716
687
twip_mode = TWIPM_WAIT;
717
688
twip_state = TWIP_BUS_ERR;
718
- break ;
719
-
720
- case TWIP_WAIT_STOP:
721
- case TWIP_BUS_ERR:
689
+ } else IFSTATE (S2M (TWIP_WAIT_STOP)|S2M (TWIP_BUS_ERR)) {
722
690
if (sda) {
723
691
// STOP
724
692
SCL_LOW (); // clock stretching
@@ -736,10 +704,7 @@ void ICACHE_RAM_ATTR onSdaChange(void)
736
704
ets_timer_arm_new (&timer, twi_timeout_ms, false , true ); // Once, ms
737
705
}
738
706
}
739
- break ;
740
-
741
- case TWIP_SLA_W:
742
- case TWIP_READ:
707
+ } else IFSTATE (S2M (TWIP_SLA_W)|S2M (TWIP_READ)) {
743
708
// START or STOP
744
709
if (bitCount != 7 ) {
745
710
// inside byte transfer - error
@@ -765,10 +730,7 @@ void ICACHE_RAM_ATTR onSdaChange(void)
765
730
twip_mode = TWIPM_IDLE;
766
731
}
767
732
}
768
- break ;
769
-
770
- default :
771
- break ;
733
+ }
772
734
}
773
735
}
774
736
0 commit comments