Add full pin mux info and use it for I2C

All I2C peripherals should be usable now. This also adds pin
in-use tracking and resetting.

Part of #5629
This commit is contained in:
Scott Shawcroft 2021-12-01 16:14:37 -08:00
parent b83e09858f
commit 2433c9572c
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
7 changed files with 111 additions and 154 deletions

View File

@ -63,6 +63,7 @@ SRC_C += bindings/videocore/__init__.c \
lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c \
peripherals/broadcom/caches.c \
peripherals/broadcom/gen/interrupt_handlers.c \
peripherals/broadcom/gen/pins.c \
peripherals/broadcom/gpio.c \
peripherals/broadcom/interrupts.c \
peripherals/broadcom/mmu.c \

View File

@ -0,0 +1,34 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "py/obj.h"
extern const mp_obj_type_t mcu_pin_type;
#define PIN_PREFIX_VALUES { &mcu_pin_type },
#define PIN_PREFIX_FIELDS mp_obj_base_t base;

View File

@ -35,35 +35,63 @@
#include "peripherals/broadcom/cpu.h"
#include "peripherals/broadcom/vcmailbox.h"
#define NUM_I2C (2)
#if BCM_VERSION == 2711
#define NUM_I2C (8)
STATIC BSC0_Type *i2c[NUM_I2C] = {BSC0, BSC1, NULL, BSC3, BSC4, BSC5, BSC6, NULL};
#else
#define NUM_I2C (3)
STATIC BSC0_Type *i2c[NUM_I2C] = {BSC0, BSC1, NULL};
#endif
STATIC bool never_reset_i2c[NUM_I2C];
STATIC bool in_use_i2c[NUM_I2C];
STATIC BSC0_Type *i2c[2] = {BSC0, BSC1};
STATIC bool i2c_in_use[NUM_I2C];
void reset_i2c(void) {
// BSC2 is dedicated to the first HDMI output.
never_reset_i2c[2] = true;
i2c_in_use[2] = true;
#if BCM_VERSION == 2711
// BSC7 is dedicated to the second HDMI output.
never_reset_i2c[7] = true;
i2c_in_use[7] = true;
#endif
for (size_t i = 0; i < 2; i++) {
if (never_reset_i2c[i]) {
continue;
}
in_use_i2c[i] = false;
i2c_in_use[i] = false;
i2c[i]->C_b.I2CEN = false;
COMPLETE_MEMORY_READS;
}
}
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
size_t instance_index = NUM_I2C;
if ((scl == &pin_GPIO1 || scl == &pin_GPIO29 || scl == &pin_GPIO45) &&
(sda == &pin_GPIO0 || sda == &pin_GPIO28 || sda == &pin_GPIO44)) {
instance_index = 0;
} else if ((scl == &pin_GPIO44 || scl == &pin_GPIO3) &&
(sda == &pin_GPIO43 || sda == &pin_GPIO2)) {
instance_index = 1;
uint8_t scl_alt = 0;
uint8_t sda_alt = 0;
for (scl_alt = 0; scl_alt < 6; scl_alt++) {
if (scl->functions[scl_alt].type != PIN_FUNCTION_I2C ||
i2c_in_use[scl->functions[scl_alt].index]) {
continue;
}
for (sda_alt = 0; sda_alt < 6; sda_alt++) {
if (sda->functions[sda_alt].type != PIN_FUNCTION_I2C ||
scl->functions[scl_alt].index != sda->functions[sda_alt].index ||
sda->functions[sda_alt].function != I2C_FUNCTION_SDA) {
continue;
}
instance_index = scl->functions[scl_alt].index;
break;
}
if (instance_index != NUM_I2C) {
break;
}
}
if (instance_index == NUM_I2C) {
mp_raise_ValueError(translate("Invalid pins"));
}
in_use_i2c[instance_index] = true;
i2c_in_use[instance_index] = true;
self->index = instance_index;
self->peripheral = i2c[self->index];
self->sda_pin = sda;
@ -73,8 +101,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
uint16_t clock_divider = source_clock / frequency;
self->peripheral->DIV_b.CDIV = clock_divider;
gpio_set_function(sda->number, GPIO_GPFSEL0_FSEL2_SDA1);
gpio_set_function(scl->number, GPIO_GPFSEL0_FSEL3_SCL1);
gpio_set_function(sda->number, FSEL_VALUES[sda_alt]);
gpio_set_function(scl->number, FSEL_VALUES[scl_alt]);
}
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) {
return;
}
never_reset_i2c[self->index] = false;
i2c_in_use[self->index] = false;
common_hal_reset_pin(self->sda_pin);
common_hal_reset_pin(self->scl_pin);
@ -95,7 +124,6 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
uint8_t result = common_hal_busio_i2c_write(self, addr, NULL, 0, true);
// mp_printf(&mp_plat_print, "result %d %d\n", addr, result);
return result == 0;
}

View File

@ -28,14 +28,41 @@
#include "peripherals/broadcom/gpio.h"
STATIC bool pin_in_use[BCM_PIN_COUNT];
STATIC bool never_reset_pin[BCM_PIN_COUNT];
void reset_all_pins(void) {
for (size_t i = 0; i < BCM_PIN_COUNT; i++) {
if (never_reset_pin[i]) {
continue;
}
reset_pin_number(i);
}
}
void never_reset_pin_number(uint8_t pin_number) {
never_reset_pin[pin_number] = true;
}
void reset_pin_number(uint8_t pin_number) {
gpio_set_function(pin_number, 0);
gpio_set_function(pin_number, GPIO_FUNCTION_INPUT);
pin_in_use[pin_number] = false;
never_reset_pin[pin_number] = false;
// Set the pull to match the datasheet.
BP_PULL_Enum pull = BP_PULL_NONE;
if (pin_number < 9 ||
(33 < pin_number && pin_number < 37) ||
pin_number > 45) {
pull = BP_PULL_UP;
} else if (pin_number != 28 &&
pin_number != 29 &&
pin_number != 44 &&
pin_number != 45) {
// Most pins are pulled low so we only exclude the four pins that aren't
// pulled at all.
pull = BP_PULL_DOWN;
}
gpio_set_pull(pin_number, pull);
}
void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) {
@ -47,11 +74,11 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) {
}
void claim_pin(const mcu_pin_obj_t *pin) {
// Nothing to do because all changes will set the GPIO settings.
pin_in_use[pin->number] = true;
}
bool pin_number_is_free(uint8_t pin_number) {
return true;
return !pin_in_use[pin_number];
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
@ -69,71 +96,3 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
reset_pin_number(pin_no);
}
#define PIN(num) \
const mcu_pin_obj_t pin_GPIO##num = { \
{ &mcu_pin_type }, \
.number = num \
};
PIN(0)
PIN(1)
PIN(2)
PIN(3)
PIN(4)
PIN(5)
PIN(6)
PIN(7)
PIN(8)
PIN(9)
PIN(10)
PIN(11)
PIN(12)
PIN(13)
PIN(14)
PIN(15)
PIN(16)
PIN(17)
PIN(18)
PIN(19)
PIN(20)
PIN(21)
PIN(22)
PIN(23)
PIN(24)
PIN(25)
PIN(26)
PIN(27)
PIN(28)
PIN(29)
PIN(30)
PIN(31)
PIN(32)
PIN(33)
PIN(34)
PIN(35)
PIN(36)
PIN(37)
PIN(38)
PIN(39)
PIN(40)
PIN(41)
PIN(42)
PIN(43)
PIN(44)
PIN(45)
PIN(46)
PIN(47)
PIN(48)
PIN(49)
PIN(50)
PIN(51)
PIN(52)
PIN(53)
PIN(54)
PIN(55)
PIN(56)
PIN(57)

View File

@ -32,74 +32,7 @@
#include <py/obj.h>
typedef struct {
mp_obj_base_t base;
uint8_t number;
} mcu_pin_obj_t;
extern const mcu_pin_obj_t pin_GPIO0;
extern const mcu_pin_obj_t pin_GPIO1;
extern const mcu_pin_obj_t pin_GPIO2;
extern const mcu_pin_obj_t pin_GPIO3;
extern const mcu_pin_obj_t pin_GPIO4;
extern const mcu_pin_obj_t pin_GPIO5;
extern const mcu_pin_obj_t pin_GPIO6;
extern const mcu_pin_obj_t pin_GPIO7;
extern const mcu_pin_obj_t pin_GPIO8;
extern const mcu_pin_obj_t pin_GPIO9;
extern const mcu_pin_obj_t pin_GPIO10;
extern const mcu_pin_obj_t pin_GPIO11;
extern const mcu_pin_obj_t pin_GPIO12;
extern const mcu_pin_obj_t pin_GPIO13;
extern const mcu_pin_obj_t pin_GPIO14;
extern const mcu_pin_obj_t pin_GPIO15;
extern const mcu_pin_obj_t pin_GPIO16;
extern const mcu_pin_obj_t pin_GPIO17;
extern const mcu_pin_obj_t pin_GPIO18;
extern const mcu_pin_obj_t pin_GPIO19;
extern const mcu_pin_obj_t pin_GPIO20;
extern const mcu_pin_obj_t pin_GPIO21;
extern const mcu_pin_obj_t pin_GPIO22;
extern const mcu_pin_obj_t pin_GPIO23;
extern const mcu_pin_obj_t pin_GPIO24;
extern const mcu_pin_obj_t pin_GPIO25;
extern const mcu_pin_obj_t pin_GPIO26;
extern const mcu_pin_obj_t pin_GPIO27;
extern const mcu_pin_obj_t pin_GPIO28;
extern const mcu_pin_obj_t pin_GPIO29;
extern const mcu_pin_obj_t pin_GPIO30;
extern const mcu_pin_obj_t pin_GPIO31;
extern const mcu_pin_obj_t pin_GPIO32;
extern const mcu_pin_obj_t pin_GPIO33;
extern const mcu_pin_obj_t pin_GPIO34;
extern const mcu_pin_obj_t pin_GPIO35;
extern const mcu_pin_obj_t pin_GPIO36;
extern const mcu_pin_obj_t pin_GPIO37;
extern const mcu_pin_obj_t pin_GPIO38;
extern const mcu_pin_obj_t pin_GPIO39;
extern const mcu_pin_obj_t pin_GPIO40;
extern const mcu_pin_obj_t pin_GPIO41;
extern const mcu_pin_obj_t pin_GPIO42;
extern const mcu_pin_obj_t pin_GPIO43;
extern const mcu_pin_obj_t pin_GPIO44;
extern const mcu_pin_obj_t pin_GPIO45;
extern const mcu_pin_obj_t pin_GPIO46;
extern const mcu_pin_obj_t pin_GPIO47;
extern const mcu_pin_obj_t pin_GPIO48;
extern const mcu_pin_obj_t pin_GPIO49;
extern const mcu_pin_obj_t pin_GPIO50;
extern const mcu_pin_obj_t pin_GPIO51;
extern const mcu_pin_obj_t pin_GPIO52;
extern const mcu_pin_obj_t pin_GPIO53;
extern const mcu_pin_obj_t pin_GPIO54;
extern const mcu_pin_obj_t pin_GPIO55;
extern const mcu_pin_obj_t pin_GPIO56;
extern const mcu_pin_obj_t pin_GPIO57;
#include "peripherals/broadcom/pins.h"
void reset_all_pins(void);
// reset_pin_number takes the pin number instead of the pointer so that objects don't

View File

@ -187,9 +187,11 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
PIN(51)
PIN(52)
PIN(53)
#if BCM_VERSION == 2711
PIN(54)
PIN(55)
PIN(56)
PIN(57)
#endif
};
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);

@ -1 +1 @@
Subproject commit 8057af2d614c27a1e103d5f4300428f341da6bcb
Subproject commit 2e7b56bbe941311e54fba66f0b32336bfea4388d