Component Wizard inheritance selected register access

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

Component Wizard inheritance selected register access

Jump to solution
1,843 Views
jgirard1
Contributor III

I am creating a new component that inherits from the 'TimerInt' component.  In one of my methods, I need to write to a TPM register.  I can use the following macros in the driver code to access the inherited components values:

 

  inhrsym.TimerInt._Cmp;    /* This expands into TPM11 */

  inhrsym.TimerInt.Tmr;    /* This expands into TPM1 */

 

From this I loosely know which TPM unit and channel were selected through the property sheet. 

 

How do I actually translate this into the actual register name such as the following?

 

  TPM1C1SC = 0x00;

 

Do I need to futher use the macroprocessor language to select the correct register through some sort of switch statement?

 

I can't look into the code of the existing components to get any good examples.  The help file is very vague. 

0 Kudos
1 Solution
1,350 Views
ProcessorExpert
Senior Contributor III



Generally, the Component Wizard is not intended for components that are directly modifying hardware registers.  The user should instead use inheritance and use existing components (as a "harware abstraction layer") so use  only methods and events.
It's clear that this approach has limitations, but let me explain the reasons and benefits of this approach:

1 . Components using inheritance can be easily ported to other plaforms with differrent hardware, where components with same interface are available. If you access some registers directly, the omponent is specific for the particular CPU and you probably will encounter problems when you would such component on other one.

2.  No conflicts with other components in the project - The built-in component accessing hardware (we call them "hardware components") like TimerInt use an internal infrastructure which inludes a timing model and information database of CPU registter and these components are implemented and tested the way they can interract with all other components preventing the situation when one components breaks operation of the other (for example when timer is shared). Processor Expert checks the dependencies and reports conflicts. When you "just write" to some registers, you can easily break things without letting Processor
Expert know.

As the PEx infrastructure and macro-language API for timing, devices allocation and register data is not publically available at the moment, the possiblities for creating components accessing hardware directly are limited.
On new families like Kinetis there is this limitation partially reduced by more flexible LDD components and PDD macros which is a layer for controlling peripherals without need for knowing particular register names and values.

If you conclude you cannot go over without creating hardware components, please see the text below. However, please be aware that you component can encounter the mentioned problems.

Your question:
"How do I actually translate this into the actual register name such as the following?
  TPM1C1SC = 0x00;
Do I need to futher use the macroprocessor language to select the correct register through some sort of switch statement?"

 

Answer:

You can assemble the register name via string manipulation functions. You get the number of timer and channel from the _Cnt symbol like this, expecting you have TPM or FTM timer and you have TimerOut property containing inherited TimerOut component:

  %define! tmp_channel %get(@TimerOut@_Cmp,Value)
  %define! tmp_device %get(@TimerOut@_Cmp,Value)
  %define! timer_device %get(@TimerOut@_Cmp,Value)
  %substring tmp_channel,5,1
  %substring tmp_device,4,1
  %substring timer_device,1,3

Then you have macros tpm_channel, tpm_device and timer_device containing neccesary information.

We have create an example project for you (please find it attached) that demonstrates extendint TimerOut component with a method SetOutputAction that can switch the mode of seeting output polarity signal for output compare (toggle, set, clear) using TPMxCnSC register.
You can for example call this from the event routine like this: Comp1_SetOuputAction (OUTPUT_COMPARE_SET);

best regards
Petr Hradsky
Processor Expert Support Team

View solution in original post

0 Kudos
7 Replies
1,351 Views
ProcessorExpert
Senior Contributor III



Generally, the Component Wizard is not intended for components that are directly modifying hardware registers.  The user should instead use inheritance and use existing components (as a "harware abstraction layer") so use  only methods and events.
It's clear that this approach has limitations, but let me explain the reasons and benefits of this approach:

1 . Components using inheritance can be easily ported to other plaforms with differrent hardware, where components with same interface are available. If you access some registers directly, the omponent is specific for the particular CPU and you probably will encounter problems when you would such component on other one.

2.  No conflicts with other components in the project - The built-in component accessing hardware (we call them "hardware components") like TimerInt use an internal infrastructure which inludes a timing model and information database of CPU registter and these components are implemented and tested the way they can interract with all other components preventing the situation when one components breaks operation of the other (for example when timer is shared). Processor Expert checks the dependencies and reports conflicts. When you "just write" to some registers, you can easily break things without letting Processor
Expert know.

As the PEx infrastructure and macro-language API for timing, devices allocation and register data is not publically available at the moment, the possiblities for creating components accessing hardware directly are limited.
On new families like Kinetis there is this limitation partially reduced by more flexible LDD components and PDD macros which is a layer for controlling peripherals without need for knowing particular register names and values.

If you conclude you cannot go over without creating hardware components, please see the text below. However, please be aware that you component can encounter the mentioned problems.

Your question:
"How do I actually translate this into the actual register name such as the following?
  TPM1C1SC = 0x00;
Do I need to futher use the macroprocessor language to select the correct register through some sort of switch statement?"

 

Answer:

You can assemble the register name via string manipulation functions. You get the number of timer and channel from the _Cnt symbol like this, expecting you have TPM or FTM timer and you have TimerOut property containing inherited TimerOut component:

  %define! tmp_channel %get(@TimerOut@_Cmp,Value)
  %define! tmp_device %get(@TimerOut@_Cmp,Value)
  %define! timer_device %get(@TimerOut@_Cmp,Value)
  %substring tmp_channel,5,1
  %substring tmp_device,4,1
  %substring timer_device,1,3

Then you have macros tpm_channel, tpm_device and timer_device containing neccesary information.

We have create an example project for you (please find it attached) that demonstrates extendint TimerOut component with a method SetOutputAction that can switch the mode of seeting output polarity signal for output compare (toggle, set, clear) using TPMxCnSC register.
You can for example call this from the event routine like this: Comp1_SetOuputAction (OUTPUT_COMPARE_SET);

best regards
Petr Hradsky
Processor Expert Support Team

0 Kudos
1,350 Views
jgirard1
Contributor III

Thank you for the advanced information.

 

I understand all that you said and your recommendation to stay away from directly manipulating the registers.  I understand the concepts of using inheritance to gain access to the registers; however, your statements are contradictory. 

 

To create a Bean for a simple abstracted Output Compare that will allow you to generate software controlled arbitrary waveforms, you did exactly what you said not to do.  You added a method that manipulates the Output Compare edge register.  Had a method already existed in the first place from Freescale that allowed such a simple and common task to occur, we wouldn't be here discussing any of this.

 

So what do you do in a situation like this?  Because there is no method from Freescale that allows the safe and portable way to change the output edge on compare, what we must do is break the rules and forgo the portability philosophy and write driver code that goes directly to the registers.  We can add as much portability and checking as possible in the driver code using the macro language, but is that really the end user’s responsibility?  Doesn’t that defeat the whole purpose of using Processor Expert?

 

The sample code you supplied is exactly what I was looking for.  I had other ideas I tried and they worked, but the %substring macro was basically what I needed.  One thing that puzzles me is when I do a search in Component Wizard’s help file, it does not find %substring macro anywhere.  I wonder what other undocumented gems exist that could help me use the product to its fullest potential?

 

 

0 Kudos
1,350 Views
ProcessorExpert
Senior Contributor III

 

Regarding:

..Because there is no method from Freescale that allows the safe and portable way to change the output edge on compare,..

I haven't mentioned that but there is a safe and portable way. The way is using two components - TimerInt and BitIO components. You can make periodical timing by TimerInt and toggle output pin as you need in the TimerInt event code. This would create a portable HW independent code. This approach using PEx components as building bloks providing HW abstraction.

On the other side, we are aware that high-level componenst set is not sufficient for many users that exactly know what to do with registers, so we provide peripheral initialization components (like Init_TPM) that just initialize and allocate peripheral and the user can continue using the hardware on his own risk (but such application are not portable).

 

I have just posted the example component to show that there is a way to create some kind of hardware access low-level component on user side but I have also stated that it has limitations, drawbacks and you must exactly know what you are doing.

When we create components we always have to balance between leveraging fully all features present on hardware and maintaining portable interface. Interface is a compromise of these demands. We have tried in some cases to extend the components with platform specific methods and properties but it's not possible to cover all possibilities and modes.

 

Anyway, the list of such features is also  (besides other influences) driven by customer request, so it's right that you are demanding such methods and I am passing this request to the delopment team to consider implementing that for future Processor Expert versions. Thank you for your feedback!

 

Regarding %substring: 

You are right,  this should be added to the documentation I have passed that to the documentation team and asked for reviewing macro lenguage description.

 

best regards
Petr Hradsky
Processor Expert Support Team

0 Kudos
1,350 Views
jgirard1
Contributor III

I am still struggling to create a simple Timout component using an output compare register.  I am inheriting TimerInt and the problem I am having is with the interrupt event.  The interrupt event modifies the compare register and I do not want this.

 

I had specifically not inherited the interrupt method when I went through the Inheritance Wizard but the interrupt still shows up when I add the component to the project.  Instead of using the interrupt method from the TimerInt component, I also inherited the InterruptVector component.  My goal was to use InterruptVector to create my own interrupt.  The InterruptVector seems to be inheriting okay, but I cannot choose the output compare interrupt because it conflicts with the interrupt from TimerInt.  If TimerInt interrupt event method would just friggen go away, I might be one step closer to my goal.

 

How do I prevent an interrupt event method from being inherited?

0 Kudos
1,350 Views
ProcessorExpert
Senior Contributor III

You are trying to change  part of the generated component internal ISR code, however, as I already mentioned when you are using inheritance you should only use methods and events of the component. I'm sorry, but it's not possible to modify part of generated module of a component.  I wouldn't recomment it anyway as it's a high risk of breaking functionality of other components that can for example share the timer.

 

For creating TimeOut, I recommend to use FreeCntr component instead. This component encapsulates free running counter (can be using compare register) that you can get counter value, enable, disable, reset and that can also provide interrupt. You can inherit FreeCntr and add methods that you need for timeout handling and redefine content of event routine of inherited bean.

 

 

best regards
Petr Hradsky
Processor Expert Support Team

 

 

 

 

 

0 Kudos
1,350 Views
jgirard1
Contributor III

FreeCntr was what I needed. 

 

I originally looked at FreeCntr16 because I knew I needed 16 bit resolution.  However, it was not even close to what I wanted, so I abaonded it.

 

I thought FreeCntr was just an 8-bit version of the same thing and I never even looked at it.  On the contrary, it is something way different and it allowed me to implement my high resolution timeout component in no time.

 

Thank you! 

0 Kudos
1,350 Views
ProcessorExpert
Senior Contributor III

Great. I understand your confusion, the FreeCntr and FreeCntr8/16/32 work differently but have the same name for some legacy reasons . The FreeCntr allows access to hw counter (reads counter register), but the FreeCntr8, 16, 32 create a software counter variable of a specific bit width (8/16/32), counting using periodical interrupt occurences.

 

best regards
Petr Hradsky
Processor Expert Support Team

 

0 Kudos