PINMUX and IOMUX proposal

43 views
Skip to first unread message

Dave Marples

unread,
May 28, 2019, 2:55:54 PM5/28/19
to nu...@googlegroups.com

Folks,

OK, As promised I got my typing finger out to properly document what I'm suggesting. I am not wedded to this solution, I just want _a_ solution that lets me work with pinmux and iomux definitions. If someone has a better idea for how we can sensibly integrate mutable IOMUX definitions into a pin definition then I'm all ears...so far, I've not heard any alternative suggestions.

Regards

DAVE

=====================================

Proposal

Unification of function pin labeling for functions with single pinning option.

Background

NuttX has a clever mechanism for encoding all of the information about a specific pin function into a single #define. This can include everything from the physical pin number to its default start state. An example from imxrt;

#define GPIO_LPUART5_RX_1              (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_39_INDEX))
#define GPIO_LPUART5_RX_2              (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_AD_B0_11_INDEX))

In this case there are two alternative pinnings for LPUART5_RX (EMC_39 or AD_B0_11). To select between them the programmer simply adds a definition into their board.h like;

#define GPIO_LPUART5_RX                GPIO_LPUART5_RX_1

This definition allows the bottom half driver code to be 'pin agile' simply by using GPIO_LPUART5_RX rather than one of the more specific choices - that code doesn't need to know anything about the specific pin that is selected.  This principle is extended by adding in the IOMUX (drive strength etc.) elements of the pin definition in the board.h, like this;

#define GPIO_LPUART5_RX   ( GPIO_LPUART5_RX_1 | IOMUX_PULL_UP_100K | IOMUX_CMOS_OUTPUT  | IOMUX_SCHMITT_TRIGGER )

This works well. IOMUX characteristics can, and do, change per board, so they should not be set in the original definitions of each of the pin options (typically, drive strength will change, or the SION bit (pin output reflection bit) in the case of imxrt). They are properly board specific.

Problem Statement

The problem occurs when a pin only has a single pinning option. In that case the NuttX coding standard suggests that no suffix shall be added. A typical example is for LPUART5_CTS on imxrt;

#define GPIO_LPUART5_CTS         (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_36_INDEX))

...as can be seen the opportunity to add IOMUX decorations into this pin in board.h has been lost because the pin is already fully defined in pinmux.h. The current solution to this problem is to add the IOMUX definitions into the pinmux.h definition. The problem with doing this is that the potential to change the IOMUX configuration per target is lost.

Proposed Solution

It is proposed that the NuttX coding standard is modified very slightly such that single option pins still receive a _1 suffix. This removes the name clash and allows the IOMUX decorations to be applied uniformly in the board.h file. A fringe benefit is that _every_ pin used by a particular build would be documented in one place (the board.h file).

Advantages: IOMUX flexibility is maximized per board. Pin definition is consistent and uniform. Closer to MISRA-C practice. No need for custom pinmux.h per build. Impact is limited to SoC-specific code (i.e. there is no impact on NuttX 'core' code or changes to semantics).

Disadvantages: Very slightly different to what is done today.

Alternatives

(1) Set the iomux in the pinmux.h file : mingles iomux and pinmux functionality, makes iomux immutable without non-standard builds.

(2) give the 'active' pin a different label (e.g. ending _PIN) : Much less aligned with what is currently done, non-standard, needs extensive code changes to every bottom half driver.

(3) Define the IOMUX configuration in the board.h and then blend it into the pinmux.h definition : This could work, and is IMHO the second best option, but it's much less intuitive than the proposed solution, has the potential to be error prone (if we had a #ifndef default per pin) and is an enormous amount of effort for no visible benefit.

Back Compatibility

This proposal has minimal impact, and is compatible with, existing code. A programmer, finding that a pin did not have an 'unextended' definition, would look in the pinmux.h file and see an _1 option to select. This is exactly the same as they would currently do for functions with multiple pinning options. The only difference is that there are no _2, _3, _4 etc. pinnings to also select from. Its arguable that this approach is more consistent than the current one (where the decision if a pin has an extended definition or not is dependent on the particular chip variant under consideration).

There is no requirement for re-work on existing builds, since that would potentially break existing code and need new entries in board.h files that didn't previously need them (some chips don't have IOMUX functionality done in this way, or flexible pinning, so the current solution is perfectly adequate for them).


david....@gmail.com

unread,
May 28, 2019, 3:14:05 PM5/28/19
to nu...@googlegroups.com

To maintain the consistency and have the flexibility to set the pin options correctly in board.h

I would add _0 suffix to show that there is clearly a no other pin mux option.

 

-#define GPIO_LPUART5_CTS         (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_36_INDEX))
+#define GPIO_LPUART5_CTS_0       (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMXRT_PADMUX_GPIO_EMC_36_INDEX))

 

I would add some common sense IOMUX defines to the file set for things like I2C - that make sense for the majority of the use cases regardless of the tuning used for a board.

 

I would mix in those IOMUX defines with the pin mux defines and add the big note about you must set the other settings when defining a pin in board.h

 

I think that does not have a major ripple effect, but I have not looked at all configs to get a changed line count.

 

We can localize the change in the imxrt and then decide if it adds value in other configs.  

 

David

--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/9389c10f-fc85-03a3-174d-315236cc73d6%40marples.net.
For more options, visit https://groups.google.com/d/optout.

Juha Niskanen (Haltian)

unread,
May 28, 2019, 4:33:13 PM5/28/19
to nu...@googlegroups.com

> I would add _0 suffix to show that there is clearly a no other pin mux option.


Over time people will confuse this as zero-based numbering and then we start having _0 and _1 here and there with the same meaning as _1 and _2 today.


- Juha


From: nu...@googlegroups.com <nu...@googlegroups.com> on behalf of david....@gmail.com <david....@gmail.com>
Sent: Tuesday, May 28, 2019 10:13:56 PM
To: nu...@googlegroups.com
Subject: RE: [nuttx] PINMUX and IOMUX proposal
 

Gregory Nutt

unread,
May 28, 2019, 6:07:36 PM5/28/19
to nu...@googlegroups.com

> OK, As promised I got my typing finger out to properly document what
> I'm suggesting. I am not wedded to this solution, I just want _a_
> solution that lets me work with pinmux and iomux definitions. If
> someone has a better idea for how we can sensibly integrate mutable
> IOMUX definitions into a pin definition then I'm all ears...so far,
> I've not heard any alternative suggestions.
>
This is inconsistent with how other architectures work and, hence,
unacceptable.

Alan Carvalho de Assis

unread,
May 28, 2019, 6:53:32 PM5/28/19
to nu...@googlegroups.com
Hi Greg,

So, if all other architectures be updated to follow Dave's suggestion, could it be acceptable?

I understood the issue Dave is facing, but I'm worried if implementing his suggestion all MCUs pins should be redefined at board.h, same way we do currently for pins that could be other at other MCU position.

Do you have some suggestion how we could solve this dilemma?

BR,

Alan


On Tuesday, May 28, 2019, Gregory Nutt <spud...@gmail.com> wrote:

OK, As promised I got my typing finger out to properly document what I'm suggesting. I am not wedded to this solution, I just want _a_ solution that lets me work with pinmux and iomux definitions. If someone has a better idea for how we can sensibly integrate mutable IOMUX definitions into a pin definition then I'm all ears...so far, I've not heard any alternative suggestions.

This is inconsistent with how other architectures work and, hence, unacceptable.

--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/0d5142db-2aac-d933-877d-d9528338f2a5%40gmail.com.

Gregory Nutt

unread,
May 28, 2019, 7:02:52 PM5/28/19
to nu...@googlegroups.com

>
> So, if all other architectures be updated to follow Dave's suggestion,
> could it be acceptable?
Of course, my only issue is that I will no permit one architecture to
deviate from the others, not under any cicumstance.
> I understood the issue Dave is facing, but I'm worried if implementing
> his suggestion all MCUs pins should be redefined at board.h, same way
> we do currently for pins that could be other at other MCU position.
Yes, it effects all pinmux/pinmap files and all board.h files.
> Do you have some suggestion how we could solve this dilemma?

There are only two:

1. Change all of the pinmux and board.h files, or

2. Do not make the change

I am happy with either.  But I will not permit any one architecture to
deviate.  Consistency is more important than this change by far.


patacongo

unread,
May 28, 2019, 7:20:38 PM5/28/19
to NuttX


> I understood the issue Dave is facing, but I'm worried if implementing
> his suggestion all MCUs pins should be redefined at board.h, same way
> we do currently for pins that could be other at other MCU position.

Yes, it effects all pinmux/pinmap files and all board.h files.


There might be ways to simplify the change.  If a definition like the following appears in the pinmux file:


#define XYZ_USART1_RXD     (GPIO_BLAH | GPIO_OPTIONS | GPIO_PORT | GPIO_PIN)


Then perhaps you could just duplicat that that like:


#define XYZ_USART1_RXD     (GPIO_BLAH | GPIO_OPTIONS | GPIO_PORT | GPIO_PIN)
#define XYZ_USART1_RXD_X   (GPIO_BLAH | GPIO_PORT | GPIO_PIN)


Then you would only have to change the board.h header files if you are unhappy with the default definition.  They you would change it like:


#undef  XYZ_USART1_RXD
#define XYZ_UART1_RXD      (XYZ_USART1_RXD_X | MY_OPTIONS)


That would be a lot less work since, by definition, none of the existing board.h files would have to change.




patacongo

unread,
May 28, 2019, 7:23:43 PM5/28/19
to NuttX
This comment which is in  every pinmap file (bus customized for the actual pins for the MCU).  It also must change:

/* Alternate Pin Functions.
 *
 * Alternative pin selections are provided with a numeric suffix like _1, _2, etc.
 * Drivers, however, will use the pin selection without the numeric suffix.
 * Additional definitions are required in the board.h file.  For example, if
 * CAN0 RX connects vis P0.4 on some board, then the following definitions should
 * appear in the board.h header file for that board:
 *
 * #define GPIO_CAN0_RD GPIO_CAN0_RD_1
 *
 * The driver will then automatically configure P0.4 as the CAN0 RX pin.
 * ...
 */


patacongo

unread,
May 28, 2019, 7:34:49 PM5/28/19
to NuttX



> I understood the issue Dave is facing, but I'm worried if implementing
> his suggestion all MCUs pins should be redefined at board.h, same way
> we do currently for pins that could be other at other MCU position.

Yes, it effects all pinmux/pinmap files and all board.h files.



There is even a simpler way to handle the pin definitions in only the i.MXRT board.h files.  It is not so elegant, but does keep the existing rules in place.

Simply un-define and re-define the problematic pin definitions in the board.h.  Using my previous example, this definition:

#define XYZ_USART1_RXD     (GPIO_BLAH | GPIO_OPTIONS | GPIO_PORT | GPIO_PIN)


and then in the the effected board.h header file simply do:


undef  XYZ_USART1_RXD
#define XYZ_UART1_RXD     
(GPIO_BLAH | MY_OPTIONS | GPIO_PORT | GPIO_PIN)

I would accept this kind change because although it is inelegant, it does not introduce any usage incompatbilities at all.  It is very, very low effort.

But I will not accept an use case for i.MXRT that cannot be realized in other architectures.


Dave Marples

unread,
May 29, 2019, 12:23:11 AM5/29/19
to nu...@googlegroups.com
This could work. For those 'direct' definitions to work (at least on imxrt) you would also need iomux stuff in those default definitions, but I think I can figure a way around that which maintains what is, I think, the best of both approaches. 

@David; I would suggest keeping them 1 based since they are then compatible with the current _2, _3 etc....I don't see any value in folks being able to see it's an exclusive definition, do you?

Regards

Dave 

--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/b5e3f67c-48d7-41c3-ac4d-8def8cfb7914%40googlegroups.com.

patacongo

unread,
May 29, 2019, 8:45:57 AM5/29/19
to NuttX
My opinions on this have softened some overnight


> So, if all other architectures be updated to follow Dave's suggestion,
> could it be acceptable?
 
Of course, my only issue is that I will no permit one architecture to
deviate from the others, not under any circumstance.

It turns that there are other architectures that do not follow the pin multiplexing model.  I think all of the ARMs do, but some others do not.  So I don't really have any consistency to defend.

The only thing that I will require is that whatever changes are made to i.MXRT are also made to i.MX6.  The i.MXRT IOMUX derives from from i.MX6 and those two at least should be consistent.


David Sidrane

unread,
May 29, 2019, 8:50:12 AM5/29/19
to NuttX

OK You got it!

Dave Marples

unread,
May 29, 2019, 9:30:39 AM5/29/19
to nu...@googlegroups.com
I can make the patch and build for imx6, 1020, 1050 and 1060. I have already tested on 1020 and I guess David can test 1050/60 when he finds the time but I don't know who can test on imx6. Is there anyone who has an imx6 board to hand? Otherwise I'll have to see if there's one laying around the office somewhere....

Regards

Dave 

--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/d718b753-9af7-4d03-b511-588584786551%40googlegroups.com.

Gregory Nutt

unread,
May 29, 2019, 9:41:28 AM5/29/19
to nu...@googlegroups.com

> I can make the patch and build for imx6, 1020, 1050 and 1060. I have
> already tested on 1020 and I guess David can test 1050/60 when he
> finds the time but I don't know who can test on imx6. Is there anyone
> who has an imx6 board to hand? Otherwise I'll have to see if there's
> one laying around the office somewhere....

I have the a couple of Sabre-6Quad boards and can review and test changes.

The i.MX6 port is very sparse so there is not a lot that should need to
change.  I think only serial??? The port was only used for SMP testing
but I have been considering backporting the i.MXRT LCD support.  I have
a very high end i.MX6 with a 10.1 inch display I would like to get up
and running someday.

Many of the i.MX6 peripherals are the same as the i.MXRT, but many are
not.  The i.MXRT is a kind of blend of i.MX6 and Kinetis and bits of
other things.

Greg


Dave Marples

unread,
May 29, 2019, 9:55:42 AM5/29/19
to nu...@googlegroups.com
I wouldn't bother backporting just yet as there are changes still going into imxrt (I've just added RTS/CTS support for example, which is where this problem came from, although the patch itself is about 5 lines). At the very least I need to add rs485 support and I don't think Bluetooth is too far away. Then I _think_ it's just CAN and Versiboard2 support is complete.  WiFi might be a little bit longer because that needs multiport support in the SD card driver.

Regards

Dave 

--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages