Using the SCT such as described in the Blinky example here: http://support.code-red-tech.com/CodeRedWiki/NewInVersion4?action=AttachFile&do=get&target=Red_State.... there is an input DOWN to set the operational mode of the state machine.
This input can be mapped to a pin of the LPC (in my case LPC824) using the functions.
Chip_INMUX_SetSCTInMux(LPC_INMUX, SCT_INMUX_0, SCT_INP_IN0); Chip_SWM_MovablePinAssign(SWM_SCT_IN0_I, DOWN_IN_PIN); |
But how could the DOWN input be controlled by the lpc software instead? I.e. in the example I want the lpc824 firmware to manage the UPDOWN operation.
I have tried to set the pin as a PIO output and write to the port, but it does not seem to work.
Chip_GPIO_SetDir(LPC_GPIO_PORT, 0, DOWN_IN_PIN), true); | |
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, DOWN_IN_PIN), false); |
Any help is appreciated.
已解决! 转到解答。
With SCT_IN0 assigned to a pin via the switch matrix, you are no longer able to control that pin with the GPIO block.
As presumably no external connection is made to that pin, an easy solution is to alternate between the internal pull-up and pull-down resistors in the IOCON block. This allows software to control the input level of SCT_IN0, provided it's not on one of the true open-drain pins (PIO0_10/PIO0_11).
If you are using the TSSOP20 package and are short of pins, you could assign the SCT input to a PIOx_y pin not bonded out for this package, for instance PIO0_6.
indeed - this trick works nicely to generate fixed values. Thanks a lot.
I wish I had found this a bit earlier, which leads me to:
If I should give some feedback to the documentation team at NXP, it would be that the use of Red-state tool to develop SCT state machines is poorly documented with examples. Most SCT examples - even the SCT-COOK Book! are based on the C programmatic approach , which isn't exactly easy to grasp. Strangely - the cook book has a couple of Red-state diagrams, but the corresponding .rsm descriptions are meticulously removed from the example code base and the generated code is edited for readability - a thing which is you should not do with a frontend tool like Redstate.
In summary, the lack of full examples with red-state renders the use of SCT a bit hard to get into. Please note that the examples should also include the instantiation of the state machine into the C code because this is not trivial. As a further piece of evidence, note that none of the examples for LPC824 distributed with LPCxpresso holds an example of SCT + Red-state usage.
Lack of good examples to ease the learning curve is unfortunate, because the SCT with Red-state are extremely useful - and to my knowledge not matched by any other micro-controller families. And for my part they are the _reason_ to use LPC and not some of the many other arm chips!
Are anybody from NXP team reading this?
Thanks a lot Rolf Meeser. This works nicely - just what I have been missing.
It also solves another problem I have been puzzled by:
How to make a transition in the SCT red-state which is always taken? i.e. the transition condition is True always. You could make a pair of transitions in parallel: one taken for !DOWN and the other for DOWN (to use the Blinky namespace). This works, but takes up transition resources. In stead just use the pull-up resistor trick described by Rolf Meeser, on an unused pin (not bonded one is a good choice).
Maybe I can pass on a little gotcha encountered in this process: If you declare your chip pin-out in some way like this
#define DOWN_IN_PIN 12
and extrapolate from GPIO calls like..
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, DOWN_IN_PIN, false);
to this IOCON call:
Chip_IOCON_PinSetMode(LPC_IOCON, DOWN_IN_PIN, PIN_MODE_PULLUP);
then it does not work, because the pin-number selector has ANOTHER ENCODING in IOCON than in GPIO !
The correct way is:
Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO12, PIN_MODE_PULLUP);
This is slightly inconvenient when it comes to having maintainable code - it is error prone to change pin-out for instance, as the change must take place multiple locations. One way around would be a look-up table structure to transform from one encoding to the other. Easy enough but it will take resources in the firmware.
Can the number conversion maybe by solved by using some pre-processor macro?
In any case - thanks again to Rolf.
The following bit of intriguing macro will transform from GPIO pin number to the corresponding CHIP_PINx_T enumerated pin type (IOCON_PIO1,,,etc):
#define GPIO_PIN_TO_IOCON_PIO(s) str(s)
#define str(p) IOCON_PIO ## p
Used like this:
#define DOWN_IN_PIN 12
...
Chip_IOCON_PinSetMode(LPC_IOCON, GPIO_PIN_TO_IOCON_PIO(DOWN_IN_PIN), PIN_MODE_PULLUP);
In this way there is only _one_ place (the #define..) where the pin-out is defined.
You can get an "always true" event also from using an SCT output instead of an input. Preset the SCT output line to 1, and then use it in the event equation in pretty much the same way as you use an input. The advantage is that in contrast to the input line this doesn't require an assignment to a physical pin.
With SCT_IN0 assigned to a pin via the switch matrix, you are no longer able to control that pin with the GPIO block.
As presumably no external connection is made to that pin, an easy solution is to alternate between the internal pull-up and pull-down resistors in the IOCON block. This allows software to control the input level of SCT_IN0, provided it's not on one of the true open-drain pins (PIO0_10/PIO0_11).
If you are using the TSSOP20 package and are short of pins, you could assign the SCT input to a PIOx_y pin not bonded out for this package, for instance PIO0_6.