How to set values in IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to set values in IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39

2,193 Views
DiBosco
Contributor III

Folks,

Am struggling to understand this arcane method of setting registers with the SDK.

So, for a little background, been an embedded engineer since the early 90s, programmed millions of micros, been coding with M3 and M4 devices almost exlcusively since about 2009 so am no stranger to this kind of thing.

However...

...this code in the SDK for the 1062 is incomprehensible to me. All I want to do is set the values in IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39. I would normally expect to be able to do something like:

IOMUXC->CTL39 = 0xXXXXXXXX

I cannot see anyhting like that at all. I can see millions of #defines pointing frommone thing to another by which time you forget what you were originally looking for with baffling things like this:

#define IOMUXC_GPIO_EMC_39_SEMC_DQS 0x401F80B0U, 0x0U, 0, 0, 0x401F82A0U

(I cannot even begin to understand what all that is about in terms of that string of numbers.)

Which you seem to be able to use in

IOMUXC_SetPinConfig

But that seems inappropriate for the situation my board is in. It looks like, from the debugger,   the SION bit is set in IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_39 (full values is 0x10) which to me says the pad is going to GPIO_EMC_39. This in itself is baffling as it's the value at reset according to rhe debugger, yet the default value according to the manual is 0x05.

According to the debugger, and from what the scope tells me, pin B7 which is GPIO_EMC_39--USDHC2_CD_B, is set low and it needs to be an input pin, which means that IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39 which according to the debugger is set to 0x000110f9, wants to be somethign quite different for an input pin. 

Ideally, I'd just directly access the register rather than these excerable #defines upon #defines, but if it's the on;y way to use these arcane methods, how do you actually set GPIO_EMC_39--USDHC2_CD_B to be an input pin.

That doesn't even begin to address what I suspect is going to be the nightmareish task of simply reading that pin to find its value!

So, questions are:

1. Can I directly access IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39 without using these layered macros? If so, how?

2. If the answer to 1 is no, you cannot directly access registers, how do you change IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39 to be an input pin?

3. It looks like GPIO_EMC_39--USDHC2_CD_B can have ten alt valuesm, one of which is routing through to GPIO3_IO25. However, you can also, by the looks of it route it rhough using the SION bit to one, to GPIO_EMC_39. So there seems to be two possible GPIO type functions of this pin, one of which is this EMC thing. Why is that? Why would you sometimes use GPIO3_IO25 and sometimes GPIO_EMC_39? What's the difference between them?

Many thanks.

 

 

 

 

0 Kudos
Reply
8 Replies

2,164 Views
mjbcswitzerland
Specialist V

There is a practical spread sheet of the pins/pads/ports for the i.MX RT 1062 here:
https://www.utasker.com/iMX/iMXRT1060/iMX_RT_1060.xls

For info about using the i.MX RT 1062's high speed port option this video can be used:
https://www.youtube.com/watch?v=nLInUIboLR0

0 Kudos
Reply

2,159 Views
DiBosco
Contributor III

Many thanks for that, and the other video of yours that Nick posted, Mark. 

I'm still unsure about a few things.

1. When they talk about pads here are they talking about the physical pads on the PCB. So, in other worlds they use pad and pin as interchangeable terms? They use pad because they're BGAs rather than, say, QFPs? In  the datasheet, the corresponding pin (I've typed pin by force of habit!), I think, is in the "Ball Name" column of the "Functional Contact Assignments" table and is called GPIO_EMC_39.

2. I still don't understand what this SION bit does. The user manual says in the Mux register for this pin:

Force the selected mux mode Input path no matter of MUX_MODE functionality.
1 ENABLED — Force input path of pad GPIO_EMC_39
0 DISABLED — Input Path is determined by functionality

What does "Force input path of pad GPIO_EMC_39" mean? Force it to what? The manual says this bit should be low at power up, but if I stop the debugger at the start of main() it is high.

3. The next thing is that I'm still unclear about the difference between GPIO_EMC_39 and GPIO3_IO25. The IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_39 says (ignoring this mysterious SION bit for a moment) that ALT5 connects GPIO_EMC_39 to GPIO3_IO25, so is it the case that GPIO_EMC_39 is the pin/pad/ball and GPIO3_IO25 is a kind of virtual port that you can mux to, and seemingly from various pin/pad/balls around the chip? In one of your videos you did talk about how it's not like we conventionally talk about GPIO pins and the first couple of times I just couldn't understand what you were trying to get at, but maybe that's it. Maybe you need to think of GPIOx (where x is 1-6) as a virtual port on these processors that are routed with a mux from a physical pin/pad/ball?

4. Why when writing 0 to the mux register does its value then get set to 5? It then crashes the program, so I'm guessing that there's something funky going on with the order in which you need to set this all up.

I should possibly/probably have mentioned in this is an RT1062.

Many thanks for your help.

 

 

0 Kudos
Reply

2,139 Views
mjbcswitzerland
Specialist V

Hi

1. The way they do it is a source of immense confusion. They are essentially no different to others where the ports are simple names by the GPIO name but instead they have named then by the peripheral function that a certain block is typically/sometimes/never allocated to. For example your GPIO_EMC_39 is GPIO3_25 (when configured as GPIO) but, because it has an SEMC function it is named after the peripheral function for external bus interface along with other EMC_x ones. If the design has no external memory interface (or doesn't use all of the bus width) the name is essentially quite meaningless.
It is just a name so no need to try to work out exactly what it is physically referring to inside or on the chip. I think of pins since that is what is relevant at the end of the day, seeing as it is what connects the chip to the outside world.
I the uTasker project this pin has this definition:
#define PIN_GPIO_EMC_39_GPIO3_IO25    PORT3_BIT25  (which is 0x02000000, or 0x1 << 25)
whereby the EMC_39 part is usually only necessary to locate it in the EVK circuit diagram or in the user's manual. The more important bit is the GPIO3_25.

To set up a peripheral function (eg. as LPUART8_RXD) it is done with
_CONFIG_PERIPHERAL(GPIO_EMC_39, LPUART8_RXD, UART_PULL_UPS); // select LPUART8 Rx on GPIO3-24 - alt function 2 [iMX LPUARTs count 1..8]

or for its GPIO use as input
_CONFIG_PORT_INPUT(3, PIN_GPIO_EMC_39_GPIO3_IO25, PORT_PS_UP_ENABLE);
whereby the importance of knowing which GPIO it is on becomes apparent (which makes the GPIO_EMC_39 naming alone a nuisance).

2. SION means that the signal that is being sent out is looped back in again. It is necessary for some clocks, for example, like the ENET clock which can be generated by the peripheral and supplied to the external circuit bus is also needs to be used by the peripheral itself. If not set the clock is sent out but not looped back for its own internal use.

The BOOT ROM may change some signal when it starts so the user manual is only 99% correct. Generally believe the HW and not the user's manual (assuming it is not a measurement/debugger error)

3. See 1.

4. Before writing/reading registers the clock must first be gated to their block. Accesses to un-clocked peripheral (registers) cause a hard fault. Before writing to the mux register enable the GPIO's clock.
Again, for the GPIO_EMC_39, it is its GPIO port that is relevant (PORT 3) and again the advantage of naming the pins with GPIO (or both) [PIN_GPIO_EMC_39_GPIO3_IO25] becomes obvious.
Therefore before accessing make sure that its mask is set in
CCM_CCGR2

#define CCM_CCGR2_GPIO3_CLOCK_MASK 0x0c000000
#define CCM_CCGR2_GPIO3_CLOCK_OFF 0x00000000 // clock is off during all modes (stop enter hardware handshake disabled)
#define CCM_CCGR2_GPIO3_CLOCK_RUN 0x04000000 // clock is on in RUN mode but off in WAIT and STOP modes
#define CCM_CCGR2_GPIO3_CLOCK_STOP 0x0c000000 // clock is on during all modes except STOP mode

In the uTasker project the gating is controlled automatically in the port macros so it can't get forgotten, and, due to the naming conventions, it is impossible to set up a peripheral function incorrectly (without the build failing).

Regards

Mark

2,116 Views
DiBosco
Contributor III

OK thanks, Mark. That's been really helpful and is appreciated.

0 Kudos
Reply

2,177 Views
nickwallis
Senior Contributor I

One is the pad, and one is the pin.

Yes I did, a long time ago!

-Nick

0 Kudos
Reply

2,175 Views
DiBosco
Contributor III

Am trying to get my head around the pad/pin thing, will go and rewatch the video.

Thanks again.

Small world re: Baxall. I met you a couple of times as a supplier!

Tags (1)
0 Kudos
Reply

2,179 Views
DiBosco
Contributor III

Thanks, Nick. Is it the case then that GPIO3_IO25 and GPIO_EMC_39 are exacrtly the same?

Couldn't agree more about the HAL being bloaty and unecessary!

Did you used to work at Baxall by any chance?!

Thanks, Rob

0 Kudos
Reply

2,181 Views
nickwallis
Senior Contributor I

I feel your pain!

First, you need to set the muxing for the pin of interest to be GPIO usage, that is most easily done by:

IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_GPIO3_IO25, 0U);

Then, you need to set the options for that pin (pullups, drive strength, open drain etc....) as follows:

IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_39_GPIO3_IO25, <insert your value here>);

Then you need to set the GPIO direction to be input, which I find is most easily done simply by:

GPIO3->GDIR &= ~(1UL << 25);

And finally to read the pin, you can do it like this:

if( GPIO3->PSR & (1UL << 25) )
......

 

Of course, you can use the HAL layer code for some of this, but I find it bloaty and mostly unnecessary.

Finally, @mjbcswitzerland  of this parish did an excellent video that explains all of this much better than I have:

https://www.youtube.com/watch?v=SmFTi8hlba0

-Nick

0 Kudos
Reply