@@ -241,12 +241,19 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
241
241
#if DEVICE_I2CSLAVE
242
242
// I2C master by default
243
243
obj_s -> slave = 0 ;
244
+ obj_s -> pending_slave_tx_master_rx = 0 ;
245
+ obj_s -> pending_slave_rx_maxter_tx = 0 ;
244
246
#endif
245
247
246
248
#if DEVICE_I2C_ASYNCH
247
249
// I2C Xfer operation init
248
250
obj_s -> XferOperation = I2C_FIRST_AND_LAST_FRAME ;
249
251
#endif
252
+
253
+ /* Activate default IRQ handlers for sync mode
254
+ * which would be overwritten in async mode
255
+ */
256
+ i2c_irq_set (obj , 1 );
250
257
}
251
258
252
259
void i2c_frequency (i2c_t * obj , int hz )
@@ -273,12 +280,6 @@ void i2c_frequency(i2c_t *obj, int hz)
273
280
handle -> Init .OwnAddress2 = 0 ;
274
281
HAL_I2C_Init (handle );
275
282
276
- #if DEVICE_I2CSLAVE
277
- if (obj_s -> slave ) {
278
- /* Enable Address Acknowledge */
279
- handle -> Instance -> CR1 |= I2C_CR1_ACK ;
280
- }
281
- #endif
282
283
}
283
284
284
285
i2c_t * get_i2c_obj (I2C_HandleTypeDef * hi2c ){
@@ -529,25 +530,25 @@ void i2c_reset(i2c_t *obj) {
529
530
void i2c_slave_address (i2c_t * obj , int idx , uint32_t address , uint32_t mask ) {
530
531
struct i2c_s * obj_s = I2C_S (obj );
531
532
I2C_HandleTypeDef * handle = & (obj_s -> handle );
532
- I2C_TypeDef * i2c = (I2C_TypeDef * )obj_s -> i2c ;
533
533
534
534
// I2C configuration
535
535
handle -> Init .OwnAddress1 = address ;
536
536
HAL_I2C_Init (handle );
537
+
538
+ HAL_I2C_EnableListen_IT (handle );
537
539
}
538
540
539
541
void i2c_slave_mode (i2c_t * obj , int enable_slave ) {
540
542
541
543
struct i2c_s * obj_s = I2C_S (obj );
542
- I2C_TypeDef * i2c = ( I2C_TypeDef * ) obj_s -> i2c ;
544
+ I2C_HandleTypeDef * handle = & ( obj_s -> handle ) ;
543
545
544
546
if (enable_slave ) {
545
547
obj_s -> slave = 1 ;
546
-
547
- /* Enable Address Acknowledge */
548
- i2c -> CR1 |= I2C_CR1_ACK ;
548
+ HAL_I2C_EnableListen_IT (handle );
549
549
} else {
550
550
obj_s -> slave = 0 ;
551
+ HAL_I2C_DisableListen_IT (handle );
551
552
}
552
553
}
553
554
@@ -557,145 +558,96 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
557
558
#define WriteGeneral 2 // the master is writing to all slave
558
559
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
559
560
560
- int i2c_slave_receive (i2c_t * obj ) {
561
561
562
+ void HAL_I2C_AddrCallback (I2C_HandleTypeDef * hi2c , uint8_t TransferDirection , uint16_t AddrMatchCode ) {
563
+ /* Get object ptr based on handler ptr */
564
+ i2c_t * obj = get_i2c_obj (hi2c );
562
565
struct i2c_s * obj_s = I2C_S (obj );
563
- I2C_HandleTypeDef * handle = & (obj_s -> handle );
564
-
565
- int retValue = NoData ;
566
566
567
- /* Reading BUSY flag before ADDR flag could clear ADDR */
568
- int addr = __HAL_I2C_GET_FLAG (handle , I2C_FLAG_ADDR );
569
-
570
- if (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY ) == 1 ) {
571
- if (addr == 1 ) {
572
- if (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_TRA ) == 1 ) {
573
- retValue = ReadAddressed ;
574
- } else {
575
- retValue = WriteAddressed ;
576
- }
577
- __HAL_I2C_CLEAR_ADDRFLAG (handle );
578
- }
567
+ /* Transfer direction in HAL is from Master point of view */
568
+ if (TransferDirection == I2C_DIRECTION_RECEIVE ) {
569
+ obj_s -> pending_slave_tx_master_rx = 1 ;
579
570
}
580
571
581
- return (retValue );
572
+ if (TransferDirection == I2C_DIRECTION_TRANSMIT ) {
573
+ obj_s -> pending_slave_rx_maxter_tx = 1 ;
574
+ }
582
575
}
583
576
584
- int i2c_slave_read (i2c_t * obj , char * data , int length ) {
585
-
577
+ void HAL_I2C_SlaveTxCpltCallback (I2C_HandleTypeDef * I2cHandle ){
578
+ /* Get object ptr based on handler ptr */
579
+ i2c_t * obj = get_i2c_obj (I2cHandle );
586
580
struct i2c_s * obj_s = I2C_S (obj );
587
- I2C_HandleTypeDef * handle = & (obj_s -> handle );
588
-
589
- uint32_t Timeout ;
590
- int size = 0 ;
591
-
592
- while (length > 0 ) {
581
+ obj_s -> pending_slave_tx_master_rx = 0 ;
582
+ }
593
583
594
- /* Wait until RXNE flag is set */
595
- // Wait until the byte is received
596
- Timeout = FLAG_TIMEOUT ;
597
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_RXNE ) == RESET ) {
598
- Timeout -- ;
599
- if (Timeout == 0 ) {
600
- return -1 ;
601
- }
602
- }
584
+ void HAL_I2C_SlaveRxCpltCallback (I2C_HandleTypeDef * I2cHandle ){
585
+ /* Get object ptr based on handler ptr */
586
+ i2c_t * obj = get_i2c_obj (I2cHandle );
587
+ struct i2c_s * obj_s = I2C_S (obj );
588
+ obj_s -> pending_slave_rx_maxter_tx = 0 ;
589
+ }
603
590
604
- /* Read data from DR */
605
- (* data ++ ) = handle -> Instance -> DR ;
606
- length -- ;
607
- size ++ ;
591
+ void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
592
+ {
593
+ /* restart listening for master requests */
594
+ HAL_I2C_EnableListen_IT (hi2c );
595
+ }
608
596
609
- if ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BTF ) == SET ) && (length != 0 )) {
610
- /* Read data from DR */
611
- (* data ++ ) = handle -> Instance -> DR ;
612
- length -- ;
613
- size ++ ;
614
- }
615
- }
597
+ int i2c_slave_receive (i2c_t * obj ) {
616
598
617
- /* Wait until STOP flag is set */
618
- Timeout = FLAG_TIMEOUT ;
619
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_STOPF ) == RESET ) {
620
- Timeout -- ;
621
- if (Timeout == 0 ) {
622
- return -1 ;
623
- }
624
- }
599
+ struct i2c_s * obj_s = I2C_S (obj );
600
+ int retValue = NoData ;
625
601
626
- /* Clear STOP flag */
627
- __HAL_I2C_CLEAR_STOPFLAG (handle );
602
+ if (obj_s -> pending_slave_rx_maxter_tx ) {
603
+ retValue = WriteAddressed ;
604
+ }
628
605
629
- /* Wait until BUSY flag is reset */
630
- Timeout = FLAG_TIMEOUT ;
631
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY ) == SET ) {
632
- Timeout -- ;
633
- if (Timeout == 0 ) {
634
- return -1 ;
635
- }
636
- }
606
+ if (obj_s -> pending_slave_tx_master_rx ) {
607
+ retValue = ReadAddressed ;
608
+ }
637
609
638
- return size ;
610
+ return ( retValue ) ;
639
611
}
640
612
641
- int i2c_slave_write (i2c_t * obj , const char * data , int length ) {
642
-
643
- uint32_t Timeout ;
644
- int size = 0 ;
613
+ int i2c_slave_read (i2c_t * obj , char * data , int length ) {
645
614
struct i2c_s * obj_s = I2C_S (obj );
646
615
I2C_HandleTypeDef * handle = & (obj_s -> handle );
616
+ int count = 0 ;
617
+ int ret = 0 ;
647
618
648
- while (length > 0 ) {
649
- /* Wait until TXE flag is set */
650
- Timeout = FLAG_TIMEOUT ;
651
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_TXE ) == RESET ) {
652
- Timeout -- ;
653
- if (Timeout == 0 ) {
654
- return -1 ;
655
- }
656
- }
657
-
658
- /* Write data to DR */
659
- handle -> Instance -> DR = (* data ++ );
660
- length -- ;
661
- size ++ ;
619
+ /* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
620
+ ret = HAL_I2C_Slave_Sequential_Receive_IT (handle , (uint8_t * ) data , length , I2C_NEXT_FRAME );
662
621
663
- if ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BTF ) == SET ) && (length != 0 )) {
664
- /* Write data to DR */
665
- handle -> Instance -> DR = (* data ++ );
666
- length -- ;
667
- size ++ ;
668
- }
622
+ if (ret != HAL_OK ) {
623
+ count = 0 ;
624
+ } else {
625
+ count = length ;
669
626
}
670
627
671
- /* Wait until AF flag is set */
672
- Timeout = FLAG_TIMEOUT ;
673
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_AF ) == RESET ) {
674
- Timeout -- ;
675
- if (Timeout == 0 ) {
676
- return -1 ;
677
- }
678
- }
628
+ while (obj_s -> pending_slave_rx_maxter_tx );
679
629
680
- /* Clear AF flag */
681
- __HAL_I2C_CLEAR_FLAG ( handle , I2C_FLAG_AF );
630
+ return count ;
631
+ }
682
632
633
+ int i2c_slave_write (i2c_t * obj , const char * data , int length ) {
634
+ struct i2c_s * obj_s = I2C_S (obj );
635
+ I2C_HandleTypeDef * handle = & (obj_s -> handle );
636
+ int count = 0 ;
637
+ int ret = 0 ;
683
638
684
- /* Wait until BUSY flag is reset */
685
- Timeout = FLAG_TIMEOUT ;
686
- while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY ) == SET ) {
687
- Timeout -- ;
688
- if (Timeout == 0 ) {
689
- return -1 ;
690
- }
691
- }
639
+ /* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
640
+ ret = HAL_I2C_Slave_Sequential_Transmit_IT (handle , (uint8_t * ) data , length , I2C_NEXT_FRAME );
692
641
693
- handle -> State = HAL_I2C_STATE_READY ;
642
+ if (ret != HAL_OK ) {
643
+ count = 0 ;
644
+ } else {
645
+ count = length ;
646
+ }
694
647
695
- /* Process Unlocked */
696
- __HAL_UNLOCK (handle );
648
+ while (obj_s -> pending_slave_tx_master_rx );
697
649
698
- return size ;
650
+ return count ;
699
651
}
700
652
701
653
#endif // DEVICE_I2CSLAVE
0 commit comments