Repeated initialization protection, cleanup

This commit is contained in:
Hierophect 2019-09-20 14:33:37 -04:00
parent 18c5be8835
commit ef15ebe8c7
6 changed files with 84 additions and 166 deletions

View File

@ -24,6 +24,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdbool.h>
#include "shared-bindings/busio/I2C.h"
#include "py/mperrno.h"
@ -34,8 +35,22 @@
#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
STATIC bool reserved_i2c[3];
void i2c_reset(void) {
//TODO: implement something better than eratta workaround.
//Note: I2Cs are also forcibly reset in construct, due to silicon error
#ifdef I2C1
reserved_i2c[0] = false;
__HAL_RCC_I2C1_CLK_DISABLE();
#endif
#ifdef I2C2
reserved_i2c[1] = false;
__HAL_RCC_I2C2_CLK_DISABLE();
#endif
#ifdef I2C3
reserved_i2c[3] = false;
__HAL_RCC_I2C3_CLK_DISABLE();
#endif
}
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
@ -47,12 +62,12 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
uint8_t sda_len = sizeof(mcu_i2c_sda_list)/sizeof(*mcu_i2c_sda_list);
uint8_t scl_len = sizeof(mcu_i2c_scl_list)/sizeof(*mcu_i2c_scl_list);
for(uint i=0; i<sda_len;i++) {
if (mcu_i2c_sda_list[i]->pin == sda) {
if (mcu_i2c_sda_list[i].pin == sda) {
for(uint j=0; j<scl_len;j++) {
if ((mcu_i2c_scl_list[j]->pin == scl)
&& (mcu_i2c_scl_list[j]->i2c_index == mcu_i2c_sda_list[i]->i2c_index)) {
self->scl = mcu_i2c_scl_list[j];
self->sda = mcu_i2c_sda_list[i];
if ((mcu_i2c_scl_list[j].pin == scl)
&& (mcu_i2c_scl_list[j].i2c_index == mcu_i2c_sda_list[i].i2c_index)) {
self->scl = &mcu_i2c_scl_list[j];
self->sda = &mcu_i2c_sda_list[i];
break;
}
}
@ -66,6 +81,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
mp_raise_RuntimeError(translate("Invalid I2C pin selection"));
}
if(reserved_i2c[self->sda->i2c_index-1]) {
mp_raise_RuntimeError(translate("Hardware busy, try alternative pins"));
}
//Start GPIO for each pin
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = pin_mask(sda->number);
@ -84,7 +103,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
//Fix for HAL error caused by soft reboot GPIO init SDA pin voltage drop. See Eratta.
//Must be in this exact spot or I2C will get stuck in infinite loop.
//TODO: delet
//TODO: See git issue #2172
#ifdef I2C1
__HAL_RCC_I2C1_FORCE_RESET();
HAL_Delay(2);
@ -101,14 +120,24 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
__HAL_RCC_I2C3_RELEASE_RESET();
#endif
//Keep separate so above hack can be cleanly replaced
#ifdef I2C1
if(I2Cx==I2C1) __HAL_RCC_I2C1_CLK_ENABLE();
if(I2Cx==I2C1) {
reserved_i2c[0] = true;
__HAL_RCC_I2C1_CLK_ENABLE();
}
#endif
#ifdef I2C2
if(I2Cx==I2C2) __HAL_RCC_I2C2_CLK_ENABLE();
if(I2Cx==I2C2) {
reserved_i2c[1] = true;
__HAL_RCC_I2C2_CLK_ENABLE();
}
#endif
#ifdef I2C3
if(I2Cx==I2C3) __HAL_RCC_I2C3_CLK_ENABLE();
if(I2Cx==I2C3) {
reserved_i2c[2] = true;
__HAL_RCC_I2C3_CLK_ENABLE();
}
#endif
self->handle.Instance = I2Cx;
@ -122,9 +151,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
self->handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if(HAL_I2C_Init(&(self->handle)) != HAL_OK) {
mp_raise_RuntimeError(translate("I2C Init Error"));
} else {
//TODO: remove post testing
mp_printf(&mp_plat_print, "I2C INIT OK\n");
}
claim_pin(sda);
claim_pin(scl);
@ -139,16 +165,25 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
return;
}
#ifdef I2C1
if(self->handle.Instance==I2C1) __HAL_RCC_I2C1_CLK_DISABLE();
if(self->handle.Instance==I2C1) {
reserved_i2c[0] = 0;
__HAL_RCC_I2C1_CLK_DISABLE();
}
#endif
#ifdef I2C2
if(self->handle.Instance==I2C2) __HAL_RCC_I2C2_CLK_DISABLE();
if(self->handle.Instance==I2C2) {
reserved_i2c[1] = 0;
__HAL_RCC_I2C2_CLK_DISABLE();
}
#endif
#ifdef I2C3
if(self->handle.Instance==I2C3) __HAL_RCC_I2C3_CLK_DISABLE();
if(self->handle.Instance==I2C3) {
reserved_i2c[3] = 0;
__HAL_RCC_I2C3_CLK_DISABLE();
}
#endif
HAL_GPIO_DeInit(pin_port(self->sda->pin->port), pin_mask(self->sda->pin->number));
HAL_GPIO_DeInit(pin_port(self->scl->pin->port), pin_mask(self->scl->pin->number));
reset_pin_number(self->sda->pin->port,self->sda->pin->number);
reset_pin_number(self->scl->pin->port,self->scl->pin->number);
self->sda = mp_const_none;
self->scl = mp_const_none;
}

View File

@ -33,51 +33,6 @@
#include "stm32f4xx_hal.h"
#include "stm32f4/pins.h"
// #define PA 0
// #define PB 1
// #define PC 2
// #define PD 3
// #define PE 4
// #define PF 5
// #define PG 6
// #define PH 7
// #define PI 8
// #define PJ 9
// #define PK 10
// I2C
// Numerical Version
/*
typedef struct {
mp_obj_base_t base;
uint8_t i2c_index:3; // Index of the I2C unit
uint8_t alt_index:4; // Alt index is arbitrary, it just lists additional pin options
uint8_t sda_pin_port:4;
uint8_t sda_pin_number:4;
uint8_t scl_pin_port:4;
uint8_t scl_pin_number:4;
} mcu_i2c_periph_obj_t;
#define SDA(port, number) \
.sda_pin_port = port, \
.sda_pin_number = number,
#define SCL(port, number) \
.scl_pin_port = port, \
.scl_pin_number = number
#define I2C(index, alt, sda, scl) \
{ \
{ &prefix_fields }, \
.i2c_index = index, \
.alt_index = alt, \
sda \
scl \
}
*/
// Address Version
typedef struct {
uint8_t i2c_index:4; // Index of the I2C unit (1 to 3)

View File

@ -29,46 +29,24 @@
#include "stm32f4/pins.h"
#include "stm32f4/periph.h"
//const mcu_i2c_periph_obj_t periph_I2C1_0 = I2C(1, 0, SDA(PB,7), SCL(PB,6));
//const mcu_i2c_periph_obj_t periph_I2C1_1 = I2C(1, 1, SDA(PB,9), SCL(PB,8));
//const mcu_i2c_periph_obj_t periph_I2C2 = I2C(1, NO_ALT, SDA(PB,11), SCL(PB,10));
//const mcu_i2c_periph_obj_t periph_I2C3 = I2C(1, NO_ALT, SDA(PB,9), SCL(PB,8));
// I2C
I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
//SDA Pins
const mcu_i2c_sda_obj_t per_SDA_1B07 = I2C_SDA(1, 4, &pin_PB07);
const mcu_i2c_sda_obj_t per_SDA_1B09 = I2C_SDA(1, 4, &pin_PB09);
// const mcu_i2c_sda_obj_t per_SDA_2B11 = I2C_SDA(2, 4, &pin_PB11); //not on LQFP100
const mcu_i2c_sda_obj_t per_SDA_2B09 = I2C_SDA(2, 9, &pin_PB09);
const mcu_i2c_sda_obj_t per_SDA_2B03 = I2C_SDA(2, 9, &pin_PB03);
const mcu_i2c_sda_obj_t per_SDA_3C09 = I2C_SDA(3, 4, &pin_PC09);
const mcu_i2c_sda_obj_t per_SDA_3B04 = I2C_SDA(3, 9, &pin_PB04);
const mcu_i2c_sda_obj_t per_SDA_3B08 = I2C_SDA(3, 9, &pin_PB08);
//SCL Pins
const mcu_i2c_scl_obj_t per_SCL_1B06 = I2C_SCL(1, 4, &pin_PB06);
const mcu_i2c_scl_obj_t per_SCL_1B08 = I2C_SCL(1, 4, &pin_PB08);
const mcu_i2c_scl_obj_t per_SCL_2B10 = I2C_SCL(2, 4, &pin_PB10);
const mcu_i2c_scl_obj_t per_SCL_3B08 = I2C_SCL(3, 4, &pin_PA08);
const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[7] = {
&per_SDA_1B07,
&per_SDA_1B09,
&per_SDA_2B09,
&per_SDA_2B03,
&per_SDA_3C09,
&per_SDA_3B04,
&per_SDA_3B08
const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7] = {
I2C_SDA(1, 4, &pin_PB07),
I2C_SDA(1, 4, &pin_PB09),
I2C_SDA(2, 9, &pin_PB09),
I2C_SDA(2, 9, &pin_PB03),
I2C_SDA(3, 4, &pin_PC09),
I2C_SDA(3, 9, &pin_PB04),
I2C_SDA(3, 9, &pin_PB08)
};
const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4] = {
&per_SCL_1B06,
&per_SCL_1B08,
&per_SCL_2B10,
&per_SCL_3B08
const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
I2C_SCL(1, 4, &pin_PB06),
I2C_SCL(1, 4, &pin_PB08),
I2C_SCL(2, 4, &pin_PB10),
I2C_SCL(3, 4, &pin_PA08)
};
//SPI, UART, Etc

View File

@ -30,21 +30,7 @@
//I2C
extern I2C_TypeDef * mcu_i2c_banks[3];
extern const mcu_i2c_sda_obj_t per_SDA_1B07;
extern const mcu_i2c_sda_obj_t per_SDA_1B09;
//extern const mcu_i2c_sda_obj_t per_SDA_2B11;
extern const mcu_i2c_sda_obj_t per_SDA_2B09;
extern const mcu_i2c_sda_obj_t per_SDA_2B03;
extern const mcu_i2c_sda_obj_t per_SDA_3C09;
extern const mcu_i2c_sda_obj_t per_SDA_3B04;
extern const mcu_i2c_sda_obj_t per_SDA_3B08;
extern const mcu_i2c_scl_obj_t per_SCL_1B06;
extern const mcu_i2c_scl_obj_t per_SCL_1B08;
extern const mcu_i2c_scl_obj_t per_SCL_2B10;
extern const mcu_i2c_scl_obj_t per_SCL_3B08;
extern const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[7];
extern const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4];
extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7];
extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H

View File

@ -29,47 +29,25 @@
#include "stm32f4/pins.h"
#include "stm32f4/periph.h"
//const mcu_i2c_periph_obj_t periph_I2C1_0 = I2C(1, 0, SDA(PB,7), SCL(PB,6));
//const mcu_i2c_periph_obj_t periph_I2C1_1 = I2C(1, 1, SDA(PB,9), SCL(PB,8));
//const mcu_i2c_periph_obj_t periph_I2C2 = I2C(1, NO_ALT, SDA(PB,11), SCL(PB,10));
//const mcu_i2c_periph_obj_t periph_I2C3 = I2C(1, NO_ALT, SDA(PB,9), SCL(PB,8));
// I2C
I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
//SDA Pins
const mcu_i2c_sda_obj_t per_SDA_1B07 = I2C_SDA(1, 4, &pin_PB07);
const mcu_i2c_sda_obj_t per_SDA_1B09 = I2C_SDA(1, 4, &pin_PB09);
const mcu_i2c_sda_obj_t per_SDA_2B11 = I2C_SDA(2, 4, &pin_PB11); //not on LQFP100
const mcu_i2c_sda_obj_t per_SDA_2B09 = I2C_SDA(2, 9, &pin_PB09);
const mcu_i2c_sda_obj_t per_SDA_2B03 = I2C_SDA(2, 9, &pin_PB03);
const mcu_i2c_sda_obj_t per_SDA_3C09 = I2C_SDA(3, 4, &pin_PC09);
const mcu_i2c_sda_obj_t per_SDA_3B04 = I2C_SDA(3, 9, &pin_PB04);
const mcu_i2c_sda_obj_t per_SDA_3B08 = I2C_SDA(3, 9, &pin_PB08);
//SCL Pins
const mcu_i2c_scl_obj_t per_SCL_1B06 = I2C_SCL(1, 4, &pin_PB06);
const mcu_i2c_scl_obj_t per_SCL_1B08 = I2C_SCL(1, 4, &pin_PB08);
const mcu_i2c_scl_obj_t per_SCL_2B10 = I2C_SCL(2, 4, &pin_PB10);
const mcu_i2c_scl_obj_t per_SCL_3B08 = I2C_SCL(3, 4, &pin_PA08);
const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[8] = {
&per_SDA_1B07,
&per_SDA_1B09,
&per_SDA_2B11,
&per_SDA_2B09,
&per_SDA_2B03,
&per_SDA_3C09,
&per_SDA_3B04,
&per_SDA_3B08
const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8] = {
I2C_SDA(1, 4, &pin_PB07),
I2C_SDA(1, 4, &pin_PB09),
I2C_SDA(2, 4, &pin_PB11), //not on LQFP100
I2C_SDA(2, 9, &pin_PB09),
I2C_SDA(2, 9, &pin_PB03),
I2C_SDA(3, 4, &pin_PC09),
I2C_SDA(3, 9, &pin_PB04),
I2C_SDA(3, 9, &pin_PB08)
};
const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4] = {
&per_SCL_1B06,
&per_SCL_1B08,
&per_SCL_2B10,
&per_SCL_3B08
const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
I2C_SCL(1, 4, &pin_PB06),
I2C_SCL(1, 4, &pin_PB08),
I2C_SCL(2, 4, &pin_PB10),
I2C_SCL(3, 4, &pin_PA08)
};
//SPI, UART, Etc

View File

@ -30,22 +30,8 @@
//I2C
extern I2C_TypeDef * mcu_i2c_banks[3];
extern const mcu_i2c_sda_obj_t per_SDA_1B07;
extern const mcu_i2c_sda_obj_t per_SDA_1B09;
extern const mcu_i2c_sda_obj_t per_SDA_2B11;
extern const mcu_i2c_sda_obj_t per_SDA_2B09;
extern const mcu_i2c_sda_obj_t per_SDA_2B03;
extern const mcu_i2c_sda_obj_t per_SDA_3C09;
extern const mcu_i2c_sda_obj_t per_SDA_3B04;
extern const mcu_i2c_sda_obj_t per_SDA_3B08;
extern const mcu_i2c_scl_obj_t per_SCL_1B06;
extern const mcu_i2c_scl_obj_t per_SCL_1B08;
extern const mcu_i2c_scl_obj_t per_SCL_2B10;
extern const mcu_i2c_scl_obj_t per_SCL_3B08;
extern const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[8];
extern const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4];
extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8];
extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H