35
35
#include "peripherals/broadcom/cpu.h"
36
36
#include "peripherals/broadcom/vcmailbox.h"
37
37
38
- #define NUM_I2C (2)
38
+ #if BCM_VERSION == 2711
39
+ #define NUM_I2C (8)
40
+ STATIC BSC0_Type * i2c [NUM_I2C ] = {BSC0 , BSC1 , NULL , BSC3 , BSC4 , BSC5 , BSC6 , NULL };
41
+ #else
42
+ #define NUM_I2C (3)
43
+ STATIC BSC0_Type * i2c [NUM_I2C ] = {BSC0 , BSC1 , NULL };
44
+ #endif
39
45
40
46
STATIC bool never_reset_i2c [NUM_I2C ];
41
- STATIC bool in_use_i2c [NUM_I2C ];
42
- STATIC BSC0_Type * i2c [2 ] = {BSC0 , BSC1 };
47
+ STATIC bool i2c_in_use [NUM_I2C ];
43
48
44
49
void reset_i2c (void ) {
45
- for (size_t i = 0 ; i < 2 ; i ++ ) {
50
+ // BSC2 is dedicated to the first HDMI output.
51
+ never_reset_i2c [2 ] = true;
52
+ i2c_in_use [2 ] = true;
53
+ #if BCM_VERSION == 2711
54
+ // BSC7 is dedicated to the second HDMI output.
55
+ never_reset_i2c [7 ] = true;
56
+ i2c_in_use [7 ] = true;
57
+ #endif
58
+ for (size_t i = 0 ; i < NUM_I2C ; i ++ ) {
46
59
if (never_reset_i2c [i ]) {
47
60
continue ;
48
61
}
49
- in_use_i2c [i ] = false;
62
+ i2c_in_use [i ] = false;
63
+ i2c [i ]-> C_b .I2CEN = false;
64
+ COMPLETE_MEMORY_READS ;
50
65
}
51
66
}
52
67
53
68
void common_hal_busio_i2c_construct (busio_i2c_obj_t * self ,
54
69
const mcu_pin_obj_t * scl , const mcu_pin_obj_t * sda , uint32_t frequency , uint32_t timeout ) {
55
70
size_t instance_index = NUM_I2C ;
56
- if ((scl == & pin_GPIO1 || scl == & pin_GPIO29 || scl == & pin_GPIO45 ) &&
57
- (sda == & pin_GPIO0 || sda == & pin_GPIO28 || sda == & pin_GPIO44 )) {
58
- instance_index = 0 ;
59
- } else if ((scl == & pin_GPIO44 || scl == & pin_GPIO3 ) &&
60
- (sda == & pin_GPIO43 || sda == & pin_GPIO2 )) {
61
- instance_index = 1 ;
71
+ uint8_t scl_alt = 0 ;
72
+ uint8_t sda_alt = 0 ;
73
+ for (scl_alt = 0 ; scl_alt < 6 ; scl_alt ++ ) {
74
+ if (scl -> functions [scl_alt ].type != PIN_FUNCTION_I2C ||
75
+ i2c_in_use [scl -> functions [scl_alt ].index ]) {
76
+ continue ;
77
+ }
78
+ for (sda_alt = 0 ; sda_alt < 6 ; sda_alt ++ ) {
79
+ if (sda -> functions [sda_alt ].type != PIN_FUNCTION_I2C ||
80
+ scl -> functions [scl_alt ].index != sda -> functions [sda_alt ].index ||
81
+ sda -> functions [sda_alt ].function != I2C_FUNCTION_SDA ) {
82
+ continue ;
83
+ }
84
+ instance_index = scl -> functions [scl_alt ].index ;
85
+ break ;
86
+ }
87
+ if (instance_index != NUM_I2C ) {
88
+ break ;
89
+ }
62
90
}
63
91
if (instance_index == NUM_I2C ) {
64
92
mp_raise_ValueError (translate ("Invalid pins" ));
65
93
}
66
- in_use_i2c [instance_index ] = true;
94
+ i2c_in_use [instance_index ] = true;
67
95
self -> index = instance_index ;
68
96
self -> peripheral = i2c [self -> index ];
69
97
self -> sda_pin = sda ;
@@ -73,8 +101,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
73
101
uint16_t clock_divider = source_clock / frequency ;
74
102
self -> peripheral -> DIV_b .CDIV = clock_divider ;
75
103
76
- gpio_set_function (sda -> number , GPIO_GPFSEL0_FSEL2_SDA1 );
77
- gpio_set_function (scl -> number , GPIO_GPFSEL0_FSEL3_SCL1 );
104
+ gpio_set_function (sda -> number , FSEL_VALUES [ sda_alt ] );
105
+ gpio_set_function (scl -> number , FSEL_VALUES [ scl_alt ] );
78
106
}
79
107
80
108
bool common_hal_busio_i2c_deinited (busio_i2c_obj_t * self ) {
@@ -86,6 +114,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
86
114
return ;
87
115
}
88
116
never_reset_i2c [self -> index ] = false;
117
+ i2c_in_use [self -> index ] = false;
89
118
90
119
common_hal_reset_pin (self -> sda_pin );
91
120
common_hal_reset_pin (self -> scl_pin );
@@ -95,7 +124,6 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
95
124
96
125
bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
97
126
uint8_t result = common_hal_busio_i2c_write (self , addr , NULL , 0 , true);
98
- // mp_printf(&mp_plat_print, "result %d %d\n", addr, result);
99
127
return result == 0 ;
100
128
}
101
129
0 commit comments