1

I am writing in c++ for SAMD51G19A.

I have a project that someone else wrote that I am wanting to make some changes to. In the interest of speed and not knocking down the figurative Jenga tower, I want to change as little of what is already there as possible for the time being and I'd like to avoid having to go too deeply into the setup code (it's a messy amalgamation of horror).

I'd like to reconfigure some pins at runtime to be repurposed from SPI to GPIO.

Previous code uses SERCOM0 (pins: PA04, PA05, PA06, PA07) for SPI. This all works fine (i.e. I have confirmed there are no hardware or wiring issues with these pins and I can see all the signals on the oscilloscope).

Using the code below (placing it right after setup for the time being, no threads running) I attempt to reconfigure these pins to now be used as GPIO instead and to be set high (I attempted toggle earlier too and that works fine for the two working pins but not the other two).

The problem is, only PA06 and PA07 are working. PA04 and PA05 (previously used for MOSI and SCLK respectively) do not work (on the scope, PA04 looks like it is held low, 0V, and PA05 looks to be floating, approx 0V and kinda wiggly).

    SERCOM0->SPI.CTRLA.bit.SWRST = 1;
    SERCOM0->SPI.CTRLA.bit.ENABLE = 0;

    PORT->Group[0].PINCFG[4].reg = 0;
    PORT->Group[0].PINCFG[5].reg = 0;

    pinMode(6, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(5, OUTPUT);
    digitalWrite(6, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(5, HIGH);
    while(1){};

My question is two fold. Should it be possible to reconfigure these pins at run time without knowing for certain what exactly has been done in the setup code or is it possible there is some stuff that has been setup that requires not being set up at all?

And two, why are only two pins of the four working? I assume it's not related to clock settings since the clocks are port related? Is it possible interrupts could have been set up for those pins that need disabling? Or something else? What else am I missing?

Other notes: Code base uses a mix of modified RTOS, atmel start template code, and arduino stuff. I am building with Microchip studio.

Indi008
  • 41
  • 5

1 Answers1

1

I figured it out. The digitalWrite function has checks for what the current config is. So either the pin config needs changing or can just directly set the pin as follows:

PORT->Group[0].OUTSET.reg = (1ul << 4);

I didn't even need to disable spi, just set the pins without the arduino calls and it works. e.g.

PORT->Group[0].PINCFG[4].bit.PMUXEN = 0; // disable peripheral multiplexer for PA04
PORT->Group[0].DIRSET.reg = (1ul << 4); // set PA04 as an output pin
PORT->Group[0].OUTSET.reg = (1ul << 4); // Set pin PA04 high
Indi008
  • 41
  • 5
  • The whole pin routing of the GPIO on all the SAM parts is very confusing and made needlessly complicated. Every time I try to do simple GPIO, I have revisit the manual and check out all these weird routing registers yet again... very tiresome. – Lundin Mar 21 '23 at 09:52