help with using registers to chagne pin dirrections and states.
help with using registers to chagne pin dirrections and states.
I'm trying to follow the TRM and set my registers but I'm struggling.
I think I want maybe
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG, SIG_GPIO_OUT_IDX);
or
GPIO_FUNC0_OUT_SEL_CFG_REG ( 256 )
Or maybe that is the same thing?
and then maybe
WRITE_PERI_REG( GPIO_OUT_REG[0], REG_READ(GPIO_OUT_REG[0] |= 0x01) );
WRITE_PERI_REG( GPIO_ENABLE_REG[0], REG_READ(GPIO_ENABLE_REG[0] |= 0x01) );
What I'm trying to do here is set GPIO1 to output and high or low. then I will need to bring the GPIO in and read its states without the peripheral holding it high or low so that I can read the external device.
I work with many device that require a transition in ttl around 50ns. so the API will not work for me, I did set up a GPIO bundle and was able to play with the ee.set_bit_gpio_out registers but I want to try the GPIO_FUNC0_OUT_SEL_CFG_REG .
I think I want maybe
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG, SIG_GPIO_OUT_IDX);
or
GPIO_FUNC0_OUT_SEL_CFG_REG ( 256 )
Or maybe that is the same thing?
and then maybe
WRITE_PERI_REG( GPIO_OUT_REG[0], REG_READ(GPIO_OUT_REG[0] |= 0x01) );
WRITE_PERI_REG( GPIO_ENABLE_REG[0], REG_READ(GPIO_ENABLE_REG[0] |= 0x01) );
What I'm trying to do here is set GPIO1 to output and high or low. then I will need to bring the GPIO in and read its states without the peripheral holding it high or low so that I can read the external device.
I work with many device that require a transition in ttl around 50ns. so the API will not work for me, I did set up a GPIO bundle and was able to play with the ee.set_bit_gpio_out registers but I want to try the GPIO_FUNC0_OUT_SEL_CFG_REG .
Re: help with using registers to chagne pin dirrections and states.
This looks great, I think its what I want but its written in C++ and I can not use the header. So I'd have to take this all a part and rewrite it. Sadly way complicated and worse, not documented. I feel like its just putting my at another drawing board.
-
- Posts: 1760
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: help with using registers to chagne pin dirrections and states.
yeah looks better, I do not see how to interface with it ( i.e. how to use the hw pointer and what not) but its a lot easier to follow. I may be able to use the functions anyways.
any idea what is meant by The LL layer? I do have the s3.
EDIT__________
So yes this is very good info, thx for this but my manipulation is still not working under its guidance
looking at this function.
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
}
When I do this my connected device can not change the condition of the lines. On my attached images the brown and white lines are my attached device to pins 1 and 2. As soon as I run the PIN_INPUT_ENABLE on those pins it stops. Red is just debug, to show when I did this.
Somehow the esp32 is holding low on my lines. Like the level is set to low, but how can that be if its in input mode?
any idea what is meant by The LL layer? I do have the s3.
EDIT__________
So yes this is very good info, thx for this but my manipulation is still not working under its guidance
looking at this function.
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
}
When I do this my connected device can not change the condition of the lines. On my attached images the brown and white lines are my attached device to pins 1 and 2. As soon as I run the PIN_INPUT_ENABLE on those pins it stops. Red is just debug, to show when I did this.
Somehow the esp32 is holding low on my lines. Like the level is set to low, but how can that be if its in input mode?
- Attachments
-
- img.png (5.5 KiB) Viewed 1502 times
Re: help with using registers to chagne pin dirrections and states.
I see what was wrong, its my GPIO bundle code. I guess to get precise timing, you need to use the GPIO bundles. but need to disbale it to use inputs.
Re: help with using registers to chagne pin dirrections and states.
You dont have to re-write it. just pull the parts out you need.
For example to set GPIO high and low
// Set GPIO1 high
GPIO.out_w1ts = ((uint32_t)1 << GPIO_NUM_1);
// Set GPIO1 Low
GPIO.out_w1tc = ((uint32_t)1 << GPIO_NUM_1);
just keep in mind if the GPIOs are >=32 you need to do it differently
// // Register GPIO.out_w1ts is for set bits 0-31
// // Register GPIO.out_w1tc is for clr bits 0-31
// //
// // Register GPIO.out1_w1ts.val is for set bits >=32
// // Register GPIO.out1_w1tc.val is for clr bits >=32
For example to set GPIO high and low
// Set GPIO1 high
GPIO.out_w1ts = ((uint32_t)1 << GPIO_NUM_1);
// Set GPIO1 Low
GPIO.out_w1tc = ((uint32_t)1 << GPIO_NUM_1);
just keep in mind if the GPIOs are >=32 you need to do it differently
// // Register GPIO.out_w1ts is for set bits 0-31
// // Register GPIO.out_w1tc is for clr bits 0-31
// //
// // Register GPIO.out1_w1ts.val is for set bits >=32
// // Register GPIO.out1_w1tc.val is for clr bits >=32
Re: help with using registers to chagne pin dirrections and states.
yes I saw that, as I said, but I found my underlying issue.
If I do as suggested it works, but its very sloppy and slow. The solution learned a ways back as to use GPIO bundle code. This makes the timing very fast and very smooth. But in in working with the info given in this thread, I now see things are not working if my bundles are set up. Once I disable them, then yes all works but horribly as noted.
So, going back to my bundle code I need to understand why I can not use the inputs. It would seem only the outputs work.
This is how I set them up
dedic_gpio_bundle_handle_t createBundle( const int arr[], int size, bool makeBundle)
{
gpio_config_t io_conf;
for (int i = 0; i <size; i++)
{
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
io_conf.pin_bit_mask = (1ULL<<i);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
}
// Create bundleA,
dedic_gpio_bundle_handle_t bundleA = NULL;
dedic_gpio_bundle_config_t bundleA_config =
{
.gpio_array = arr,
.array_size = size,
.flags = {
.out_en = 1,
.in_en = 1,
},
};
if (makeBundle) dedic_gpio_new_bundle(&bundleA_config, &bundleA);
return bundleA;
}
I thought that was both input and output? Or maybe I need to know how to change direction?
I use this to set my output pin states
asm volatile ("ee.set_bit_gpio_out %0" : : "I"(p) : );
I think this will read states
asm volatile ( "ee.get_gpio_in %[r]" : [r] "=r" (r));
but how to change from output to input?
If I do as suggested it works, but its very sloppy and slow. The solution learned a ways back as to use GPIO bundle code. This makes the timing very fast and very smooth. But in in working with the info given in this thread, I now see things are not working if my bundles are set up. Once I disable them, then yes all works but horribly as noted.
So, going back to my bundle code I need to understand why I can not use the inputs. It would seem only the outputs work.
This is how I set them up
dedic_gpio_bundle_handle_t createBundle( const int arr[], int size, bool makeBundle)
{
gpio_config_t io_conf;
for (int i = 0; i <size; i++)
{
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
io_conf.pin_bit_mask = (1ULL<<i);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
}
// Create bundleA,
dedic_gpio_bundle_handle_t bundleA = NULL;
dedic_gpio_bundle_config_t bundleA_config =
{
.gpio_array = arr,
.array_size = size,
.flags = {
.out_en = 1,
.in_en = 1,
},
};
if (makeBundle) dedic_gpio_new_bundle(&bundleA_config, &bundleA);
return bundleA;
}
I thought that was both input and output? Or maybe I need to know how to change direction?
I use this to set my output pin states
asm volatile ("ee.set_bit_gpio_out %0" : : "I"(p) : );
I think this will read states
asm volatile ( "ee.get_gpio_in %[r]" : [r] "=r" (r));
but how to change from output to input?
-
- Posts: 1760
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: help with using registers to chagne pin dirrections and states.
For code compatibility between ESP32 variants, the higher-level IDF code/drivers use functions from the "Hardware Abstraction Layer" (HAL), which in turn uses chip-specific implementations of low-level functions located in the "Low Level" (LL) layer. App -> driver -> HAL -> LL -> hardware.
So the low-level functions are as close as you'll get to the hardware short of manipulating bits in registers yourself.
(Directly using the LL functions from application code is not officially supported by Espressif, so in theory the functions can change/be replaced by other functions from one IDF release to the next, potentially breaking your code which relies on them.)
-
- Posts: 1760
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Who is online
Users browsing this forum: Majestic-12 [Bot] and 71 guests