Closed Gavin-Perry closed 2 years ago
If you're mixing up analog code and digital code, then I think setting an "ADC-capable GPIO" (i.e. GPIO26-GPIO29) into analog mode disconnects it from the digital controls? Can you paste a full example program that demonstrates the problem please, rather than just a short snippet?
This is the first thing I do so there isn't any more relevant code:
int ChanGroup = 0; // 7 groups of channels available (16 per group) groups 0-7
int StartChannel = BASE_ADDRESS + (NUM_CHANNELS ChanGroup); // Default to lowest group
void setup()
{
delay(200);
// Figure out which channel group we are to use for this board
// A simple way to read 3 pins to get 0-7 - Set to input pull-up for this
// doc's say "pull-up means the pushbutton's logic is inverted" WTF? pull_up just means default is high
gpio_set_dir(26, GPIO_IN);
gpio_pull_up(26);
gpio_set_dir(27, GPIO_IN);
gpio_pull_up(27);
gpio_set_dir(28, GPIO_IN);
gpio_pull_up(28);
/ // This doesn't work right! bool (non zero <>1?) vs int vs byte?
ChanGroup = gpio_get(26);
ChanGroup = ChanGroup + (gpio_get(27)<<1);
ChanGroup = ChanGroup + (gpio_get(28)<<2);
//*/
// Why is get (or digitalRead() always returning 0? if (gpio_get(26)) ChanGroup = 1; else ChanGroup = 0; if (gpio_get(27)) ChanGroup = ChanGroup + 2; if (gpio_get(28)) ChanGroup = ChanGroup + 4; if (ChanGroup >6) ChanGroup = 6; // Groups 0 to 6 only allowed
// Update the start channel StartChannel = BASE_ADDRESS + (NUM_CHANNELS * ChanGroup); // always getting BASE_ADDRESS
Seems like those pins are already set to some alternate function (by SDK or bootloader?) or something. I don't know what or why but when I run your example I get the same results so pull-up doesn't work. Anyway, you need to start with gpio_init()
, then it works for me:
gpio_init(26)
gpio_set_dir(26, GPIO_IN);
gpio_pull_up(26);
... etc
Seems like those pins are already set to some alternate function (by SDK or bootloader?) or something. I don't know what or why
In Section 2.3.1.2 of https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf it says "To drive a pin with the SIO’s GPIO registers, the GPIO multiplexer for this pin must first be configured to select the SIO GPIO function." and I believe that's what the gpio_init()
function does. Looking up the GPIO0_CTRL
register (in Table 295) shows that the FUNCSEL
field defaults to NULL, i.e. each external GPIO pin is "non-functioning" until assigned to a specific function-select.
Also, once you have the GPIOs and pull-ups properly configured, I guess your gpio-reading code could (optionally) be reduced down to something like:
ChanGroup = (gpio_get_all() & (1<<26 | 1<<27 | 1<<28)) >> 26;
to read all three GPIOs into a single 3-bit value with just one function-call.
Thank you guys for your help. That should do it. I'll try it when I get home. Your ChanGroup assignment code is even better than what I thought to use with individual gpio_get() per pin I suppose one could use ChanGroup = (gpio_get_all() & (7<<26 )) >> 26; for these particular pins I hadn't looked up the mapping of gpio_get_all(). It makes sense that the pin numbers would correspond to bit numbers but I haven't seen anything that sane since I started working with Arduino They didn't like to use proper pin or Dx values but assign IO numbers based on how the board was laid out.
I guess this can be closed now?
gpio_get() doesn't seem to work for channels 26-28 and possibly others above 16? example
gpio_set_dir(27, GPIO_IN); gpio_pull_up(27); // set to 1 or // gpio_pull_down(27); // set to 0 // Try it... my27Val = gpio_get(27); // or if (gpio_get(26)) ChanGroup = 1; // ALWAYS returns 0
I used a work around using analogRead() which works so it's not a hardware issue. if (analogRead(27)>400) my27Val = 1; else my27Val=0; // // I suppose just would work my27Bool = (analogRead(27)>400);