Trying to get clock signal on a pin

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
dpru
 
Posts: 5
Joined: Sat Dec 31, 2016 1:50 am

Trying to get clock signal on a pin

Post by dpru »

Hey all,

I am currently working on porting the Microchip SDIO library so that it works within the Arduino environment (since Adafruit chose to only port it to CircuitPython, which is an odd decision in my opinion). I've got the library pretty much completely ported over, but I am running into one issue, and I could use some wisdom on how to accomplish this.

For the record: I am using an Adafruit Grand Central M4 as my board. I have modified the board definition slightly (but not much). Here are the changes I have made to the board definition:

Since the Grand Central M4 breaks out the pins for the SDHC1 instance, I modified the pin definitions in variant.cpp for the respective pins of SDHC1. Those pins are: PA21 (Clk), PA20 (Cmd), PB18 (dat0), PB19 (dat1), PB20 (dat2), and PB21 (dat3).

I changed each of these pins to use "PIO_SDHC". Also, each pin is set to "PIN_ATTR_NONE", "No_ADC_Channel", "NOT_ON_PWM", and "NOT_ON_TIMER". I made no changes to the "external int" column for each pin definition. Therefore, each pin definition now looks something like this:

Code: Select all

{ PORTA, 21, PIO_SDHC, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }
Then, since PB20 and PB21 are being used as I2C pins in the original board definition, I changed variant.h to eliminate that I2C instance. So now my board definition contains only one I2C instance, which was formerly called "Wire1", but now it is "Wire" (using pins PC17 and PC16). So now PB20 and PB21 no longer belong to an I2C instance.

Those are the full changes I have made to the board definition. Now, let's go to the SDHC code.... I am currently trying to verify that the clock is being set up correctly.... and it isn't.

The initial clock speed during initialization of the SD card should be 400 kHz. It then goes to higher speeds later. The function which does the work of setting the speed is called _mci_set_speed and it is found in the file hpl_sdhc.c. You can see the version used in Adafruit's CircuitPython code at this link (at line 64): https://github.com/adafruit/asf4/blob/8 ... hpl_sdhc.c

I have verified that everything being sent into this function is correct. Correct "hw" instance. Correct speed. Correct prog_clock_mode. It's all correct. But for some reason I am not getting a 400 kHz signal on the PA21 Clk pin. I have verified that when I run this code in Microchip Studio, rather than through Arduino, I do get a 400 kHz signal on the pin (reading the signal using my oscilloscope).

So: I am trying to figure out why this 400 kHz clock signal is not getting set. Since I know for sure that all the right information is getting into the _mci_set_speed function, it must be one of two things:
  1. The function is failing to properly set the registers to the correct values (I don't think this is the issue)
  2. The clock pin (PA21) is not being properly set up (This is what I think is the issue)

So, I'm curious how I can verify if this pin is being set up properly? In Microchip Studio, they do the following to set up the pin:

Code: Select all

gpio_set_pin_direction(PA21, GPIO_DIRECTION_OUT);
gpio_set_pin_level(PA21, false);
gpio_set_pin_pull_mode(PA21, GPIO_PULL_OFF);
gpio_set_pin_function(PA21, PINMUX_PA21I_SDHC1_SDCK); //Pin function I
I figured that by setting the pin to be "PIO_SDHC" in my variant.cpp of the board definition, I would hopefully get the same effect as the above Microchip Studio line of code where they set the pin to use "pin function I". But I am suspicious that it is not having the same effect. If it was properly being set to that pin function, I would assume that I could see the clock signal on that pin with my scope.

So: do you think this is the issue? How can I verify the pin function is being set correctly? Or, is there a different way (within the Arduino environment/board definition/code) that I can set the pin function?

Thanks for any help!

User avatar
dpru
 
Posts: 5
Joined: Sat Dec 31, 2016 1:50 am

Re: Trying to get clock signal on a pin

Post by dpru »

I figured out the issue. As I suspected, the pin was not properly being set to PIO_SDHC.

As a user, I would expect that if I set the pin function to PIO_SDHC in variant.cpp, then it would be properly set to that function by the core code. Basically, I would expect that somewhere in the core code there is a for-loop that simply iterates through the g_APinDescription array and calls pinPeripheral on each pin. But this never happens in the core code! So even though I specified the pins as PIO_SDHC in variant.cpp, it was literally meaningless. The core code only ever calls pinPeripheral in very specific places on very specific pins (such as in the UART, SPI, and I2C libraries). This seems like a flaw, in my opinion.

Anyways, I fixed it by manually called pinPeripheral to make sure those pins got set to PIO_SDHC. Now the clock signal is generated.

User avatar
westfw
 
Posts: 2005
Joined: Fri Apr 27, 2007 1:01 pm

Re: Trying to get clock signal on a pin

Post by westfw »

would expect that if I set the pin function to PIO_SDHC in variant.cpp, then it would be properly set to that function by the core code
Nope. As you found, ulPinType is essentially useless, and probably dangerous.
Serial and maybe PWM use it to decide whether to use the normal or alt pmux setting, and everything else pretty much ignores it. Just as well, since most pins have multiple functions.

Locked
Please be positive and constructive with your questions and comments.

Return to “Metro, Metro Express, and Grand Central Boards”