Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add full pin mux info and use it for I2C #5648

Merged
merged 2 commits into from
Dec 2, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ports/broadcom/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
34 changes: 34 additions & 0 deletions ports/broadcom/broadcom_peripherals_config.h
Original file line number Diff line number Diff line change
@@ -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;
56 changes: 42 additions & 14 deletions ports/broadcom/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
tannewt marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down
101 changes: 30 additions & 71 deletions ports/broadcom/common-hal/microcontroller/Pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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)
69 changes: 1 addition & 68 deletions ports/broadcom/common-hal/microcontroller/Pin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions ports/broadcom/common-hal/microcontroller/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);