![Jim Mussared](/assets/img/avatar_default.png)
Minor change to remove support for using numeric IDs for machine.Pin. This was previously based on the index of the pin in the board csv, but this is different (and incompatible) with other ports. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
216 lines
7.4 KiB
C
216 lines
7.4 KiB
C
/*
|
|
* This file is part of the MicroPython project, http://micropython.org/
|
|
*
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2020 Philipp Ebensberger
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include "py/runtime.h"
|
|
#include "extmod/modmachine.h"
|
|
#include "pin.h"
|
|
|
|
|
|
void pin_init(void) {
|
|
return;
|
|
}
|
|
|
|
uint32_t pin_get_mode(const machine_pin_obj_t *pin) {
|
|
uint32_t pin_mode = PIN_MODE_ALT;
|
|
uint32_t config_register = *((volatile uint32_t *)pin->configRegister);
|
|
uint8_t af_mode = pin_get_af(pin);
|
|
|
|
if (af_mode == PIN_AF_MODE_ALT5) {
|
|
bool open_drain_enabled = (config_register & IOMUXC_SW_PAD_CTL_PAD_ODE_MASK) >> IOMUXC_SW_PAD_CTL_PAD_ODE_SHIFT;
|
|
|
|
if (open_drain_enabled) {
|
|
pin_mode = PIN_MODE_OPEN_DRAIN;
|
|
} else {
|
|
// Check pin direction
|
|
if ((pin->gpio->GDIR & (1U << pin->pin)) >> pin->pin) {
|
|
pin_mode = PIN_MODE_OUT;
|
|
} else {
|
|
pin_mode = PIN_MODE_IN;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pin_mode;
|
|
}
|
|
|
|
uint32_t pin_get_af(const machine_pin_obj_t *pin) {
|
|
uint32_t mux_register = *((volatile uint32_t *)pin->muxRegister);
|
|
|
|
// Read configured AF-Mode of pin
|
|
return (uint32_t)(mux_register & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK) >> IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT;
|
|
}
|
|
|
|
uint32_t pin_generate_config(const uint32_t pull, const uint32_t mode, const uint32_t drive, uint32_t config_register) {
|
|
uint32_t pad_config = 0x0UL;
|
|
|
|
#if defined MIMXRT117x_SERIES
|
|
|
|
// Set Pull-up
|
|
if ((config_register >= 0x400E8350 && config_register <= 0x400E83dc) || // GPIO_AD_xx
|
|
(config_register >= 0x40C08040 && config_register <= 0x40C0807C)) { // GPIO_LPSR_xx
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Set slew rate; there is a discrepancy between doc and header file
|
|
if (pull != PIN_PULL_DISABLED) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull Enabled
|
|
IOMUXC_SW_PAD_CTL_PAD_PUS(pull != PIN_PULL_DOWN_100K); // Up or DOWn
|
|
}
|
|
} else { // GPIO_SD_Bx_xx
|
|
if (pull == PIN_PULL_DISABLED) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b11);
|
|
} else if (pull == PIN_PULL_DOWN_100K) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b10);
|
|
} else {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PULL(0b01);
|
|
}
|
|
}
|
|
// Set open Drain; different for LPSR GPIO!
|
|
if (config_register >= 0x40C08040 && config_register <= 0x40C0807C) { // GPIO_LPSR_xx
|
|
if (mode == PIN_MODE_OPEN_DRAIN) {
|
|
pad_config |= 1 << 5; // Open Drain Enabled, no Macro provided
|
|
}
|
|
} else {
|
|
if (mode == PIN_MODE_OPEN_DRAIN) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled
|
|
}
|
|
}
|
|
// Set drive strength
|
|
if (mode != PIN_MODE_IN) {
|
|
if (!IS_GPIO_DRIVE(drive)) {
|
|
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive);
|
|
}
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive >= PIN_DRIVE_4);
|
|
}
|
|
|
|
#else
|
|
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Slow Slew Rate
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_SPEED(0b01); // medium(100MHz)
|
|
|
|
if (mode == PIN_MODE_OPEN_DRAIN) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled
|
|
} else {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b0); // Open Drain Disabled
|
|
}
|
|
|
|
if (pull == PIN_PULL_DISABLED) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(0); // Pull/Keeper Disabled
|
|
} else if (pull == PIN_PULL_HOLD) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
|
|
IOMUXC_SW_PAD_CTL_PAD_PUE(0); // Keeper selected
|
|
} else {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled
|
|
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull selected
|
|
IOMUXC_SW_PAD_CTL_PAD_PUS(pull);
|
|
}
|
|
|
|
if (mode == PIN_MODE_IN) {
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(0b000) | // output driver disabled
|
|
IOMUXC_SW_PAD_CTL_PAD_HYS(1U); // Hysteresis enabled
|
|
} else {
|
|
|
|
if (!IS_GPIO_DRIVE(drive)) {
|
|
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive);
|
|
}
|
|
|
|
pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive) |
|
|
IOMUXC_SW_PAD_CTL_PAD_HYS(0U); // Hysteresis disabled
|
|
}
|
|
|
|
#endif
|
|
|
|
return pad_config;
|
|
}
|
|
|
|
const machine_pin_obj_t *pin_find(mp_obj_t user_obj) {
|
|
const machine_pin_obj_t *pin_obj;
|
|
|
|
// If a pin was provided, then use it
|
|
if (mp_obj_is_type(user_obj, &machine_pin_type)) {
|
|
pin_obj = user_obj;
|
|
return pin_obj;
|
|
}
|
|
|
|
// See if the pin name matches a board pin
|
|
pin_obj = pin_find_named_pin(&machine_pin_board_pins_locals_dict, user_obj);
|
|
if (pin_obj) {
|
|
return pin_obj;
|
|
}
|
|
|
|
// See if the pin name matches a cpu pin
|
|
pin_obj = pin_find_named_pin(&machine_pin_cpu_pins_locals_dict, user_obj);
|
|
if (pin_obj) {
|
|
return pin_obj;
|
|
}
|
|
|
|
mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't exist"));
|
|
}
|
|
|
|
const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
|
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
|
mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP);
|
|
if (named_elem != NULL && named_elem->value != NULL) {
|
|
return named_elem->value;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn) {
|
|
const machine_pin_af_obj_t *af_obj = NULL;
|
|
|
|
for (int i = 0; i < pin->af_list_len; ++i) {
|
|
af_obj = &pin->af_list[i];
|
|
if (af_obj->af_mode == fn) {
|
|
return af_obj;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const machine_pin_af_obj_t *pin_find_af_by_base(const machine_pin_obj_t *pin, void *base_ptr[], size_t base_size) {
|
|
const machine_pin_af_obj_t *af_obj = NULL;
|
|
|
|
for (int i = 0; i < pin->af_list_len; ++i) {
|
|
af_obj = &pin->af_list[i];
|
|
for (int j = 0; j < base_size; ++j) {
|
|
if (af_obj->instance == base_ptr[j]) {
|
|
return af_obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx) {
|
|
// TODO: Implement pin_find_af_by_index function
|
|
return NULL;
|
|
}
|
|
|
|
const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name) {
|
|
// TODO: Implement pin_find_af_by_name function
|
|
return NULL;
|
|
}
|