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

GPIO mode mappings are wrong. Never get remapped to the SPL definitions. Needs rework #119

Open
bmourit opened this issue Jan 29, 2024 · 3 comments

Comments

@bmourit
Copy link
Contributor

bmourit commented Jan 29, 2024

Looking through the GPIO mapping and functions, it appears we have tried to abstract the functions away from the hardware registers, but haven't properly mapped back to them. Rather, we are calling the SPL gpio_init function from pin_function, but passing it variables that are still mapped to the abstraction when it is expecting the actual hardware defined bits. It seems that setting/changing GPIO modes won't be working correctly as is.

Since we don't have a HAL library that we are working with here, we really shouldn't abstract away much at all. There are two different GPIO mode APIs used in the SPL (depending on the specific chip) that need to be sorted, but we can either use the SPL header definitions directly here, or alternatively use switch methods in pin_function (and any place else) to remap these bits back to the proper SPL register definitions. This will have to happen anywhere we call SPL functions, so if there are too many cases - we might want to find a better way??

@bmourit bmourit changed the title GPIO mappings are wrong. Never get remapped to the SPL definitions. Needs complete overhaul. GPIO mappings are wrong. Never get remapped to the SPL definitions. Needs rework Jan 29, 2024
@bmourit
Copy link
Contributor Author

bmourit commented Jan 29, 2024

For example: In pin_function

uint32_t mode   = GD_PIN_MODE_GET(function);
    uint32_t remap  = GD_PIN_REMAP_GET(function);
    uint32_t speed  = GD_PIN_SPEED_GET(function);
    uint32_t port   = GD_PORT_GET(pin);
    uint32_t gd_pin = 1 << GD_PIN_GET(pin);

    uint32_t gpio = gpio_clock_enable(port);

#if defined(GD32F30x) || defined(GD32F10x)|| defined(GD32E50X)
    gpio_init(gpio, GD_GPIO_MODE[mode], GD_GPIO_SPEED[speed], gd_pin);

for mode from GD_PIN_MODE_GET we get our bit packed gpio info and extract the mode, and then GD_GPIO_MODE turns that into one of the following

const int GD_GPIO_MODE[] = {
    GPIO_MODE_INPUT,             /* 0 */
    GPIO_MODE_OUTPUT,            /* 1 */
    GPIO_MODE_AF,                /* 2 */
    GPIO_MODE_ANALOG,            /* 3 */
};

Which is a const int. But gpio_init expects this to be one of the following:

/* GPIO mode definitions */
#define GPIO_MODE_AIN                    ((uint8_t)0x00U)          /*!< analog input mode */
#define GPIO_MODE_IN_FLOATING            ((uint8_t)0x04U)         /*!< floating input mode */
#define GPIO_MODE_OUT_PP                 ((uint8_t)0x10U)          /*!< GPIO output with push-pull */
#define GPIO_MODE_OUT_OD                 ((uint8_t)0x14U)          /*!< GPIO output with open-drain */
#define GPIO_MODE_AF_PP                  ((uint8_t)0x18U)          /*!< AFIO output with push-pull */
#define GPIO_MODE_AF_OD                  ((uint8_t)0x1CU)          /*!< AFIO output with open-drain */
#define GPIO_MODE_IPD                    ((uint8_t)0x28U)         /*!< pull-down input mode */
#define GPIO_MODE_IPU                    ((uint8_t)0x48U)         /*!< pull-up input mode */

For one API, or:

#define CTL_CLTR(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
#define GPIO_MODE_INPUT            CTL_CLTR(0)           /*!< input mode */
#define GPIO_MODE_OUTPUT           CTL_CLTR(1)           /*!< output mode */
#define GPIO_MODE_AF               CTL_CLTR(2)           /*!< alternate function mode */
#define GPIO_MODE_ANALOG           CTL_CLTR(3)           /*!< analog mode */

For the other API.

But we never map our int to one of these, and instead we are passing the plain int as the mode.

Same thing for speed. We should just use the SPL defines here directly to remap these back, similar to how it was done in gpio_clock_enable, no?

@bmourit bmourit changed the title GPIO mappings are wrong. Never get remapped to the SPL definitions. Needs rework GPIO mode mappings are wrong. Never get remapped to the SPL definitions. Needs rework Jan 29, 2024
@maxgerhardt
Copy link
Member

Agreeing very much. This legacy thing that was carried over from the initial core needs to be reworked. I'm a bit skeptical though that it can be done completely without a PeripheralPins.h/.c, after all, the different chips all have different available pins, but using the pure GD32 SPL would expose them all equally, even ones not existing in the package.

@bmourit
Copy link
Contributor Author

bmourit commented Jan 30, 2024

Yes. I could hack something together, but I'm looking for some advice on the best/cleanest/preferred way for it to be done. I'm not sure the answer. While I'm at it, if there is consistency with the chip lines (which is doubtful - but maybe), I may redo the defines to avoid directly ifdef-ing individual chips and do something along the lines of an API V1.0/API V2.0 define instead. It would clean up the code a little, but is a relatively minor change. If it is unwanted I won't though.

To be upfront, my main motivation is to ultimately get this to work with Marlin Firmware. Since Creality quietly began shipping motherboards with GD32 mcus, users are left with a less optimized firmware for this chip. (ie. Slower clocks, unsupported mcu features, etc). I would love to be able to use native chip features, since there appears to be an ever-growing list of these chips showing up in 3d printer motherboards. These chips have their upsides and downsides compared to STM32, but so far we haven't been able to tap into any of the upsides.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants