Initializing UDB Auxiliary Control Register before main()?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JaBo_1574611
Level 4
Level 4
5 questions asked First question asked First solution authored

I have a UDB component (single UDB) and was wondering how to initialize the associated Auxiliary Control Register from within the component itself without having to do it at the project level with a call to an initialization API function in main() or some other project-level technique? I want to configure the FIFOs of a UDB into their "Single Buffer" mode by writing 0x03 into the Auxiliary Control Register of that UDB (Architecture TRM, section 16.2.3.7), but can't figure out a way of doing that automatically.

Edit 2020/09/16: To clarify, I am trying to initialize that register at the component level, rather than at the project level, so that someone using the component just has to drag it onto their schematic from the component library, and all the necessary hardware configuration would be done transparently by the component itself simply because it has been instantiated (and not require an initialization function to be called in main() or for the startup code to be modified at the project level). This is the case already for everything but that Auxiliary Control Register. The notion was to make the component potentially a pure "hardware" component from the perspective of someone using it in their project from the component library (it has some parameters that can be set from the schematic, and i was hoping that was all that would needed to be done by someone using it).

I saw in the Component Author Guide the ".cy_registers()" function (section 4.3.5 "Fixed Blocks") that "For all fixed blocks, a parameter of cy_registers is available to allow you to explicitly set the values for the given registers for the block. The values listed will be included in the configuration bitstream generated to program the part, which will be established before the main() function is called." This seems to be exactly what I want, but it doesn't seem that the datapath itself allows this parameter. When I look at the .vh2 file created for the component, the instance of cy_clock_v1_0 that I put on my schematic (and wired to my component) has a parameter "cy_registers" (it's empty, but it's listed); but the cy_psoc3_dp I instantiated does not have such a parameter listed. When I tried to add it to the parameter list of the datapath, I get an error.

Is there a "proper" way of doing this from within my component so the value is automagically intialized by the time main() runs? I wanted the component to be able to run without needing to be initialized in the user's software (effectively a pre-configured hardware component), and the FIFO configuration is the only thing I can't seem to access from within my Verilog code (and it won't work without the FIFOs being in the proper mode). I hope I'm just missing something obvious.

I'm guessing that the cyfitter_cfg() function can do it (and is where this should end up), but I can't figure out how to get it in there (there's a BS_UDB_0_0_0_CONFIG_VAL[] array in the cyfitter_cfg.c file that was created that seems to have the UDB config in it, and presumably the Auxiliary Control Register is one of those values). I read through Alan Hawse's excellent IoTExpert article on PSoC startup, and it told me where it would be done, but provided me with no clues on how to get it done.

https://iotexpert.com/2017/05/02/psoc4-boot-sequence-part-5-initializing-the-psoc-with-initialize_ps...

0 Likes
5 Replies
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

I don't think it will make any difference setting the FIFOs during startup or in the main().

In any case, if you want to customize the startup code, you need to import the cy_boot component. See how to do here:

PSoC Creator Tutorial - Importing and Copying Components - YouTube

Then open the PSoC4/API/Cm0Start.c to do your changes.

Thanks for the suggestion. I watched the video and thought about it, and that isn't what I want to do. When I was asking my question, I wasn't entirely sure I was being clear, and I was not (I will edit my question to clarify). As you say, doing it this way, or having an initialization function that gets called by the user in main() makes no difference because it is happening at the project level. What I realized I should have said was that I am trying to initialize that register at the component level, so that someone using the component just has to drag it onto their schematic, and all the necessary hardware configuration is done transparently by the component itself (and not require an initialization function to be called in main() or for the startup code to be modified... although it's good to know that technique for my own projects now that you've pointed it out to me). This is the case for everything but that Auxiliary Control Register. The notion was to make the component potentially a pure "hardware" component from the perspective of someone using it in their project from the component library (it has some parameters that can be set from the schematic, and i was hoping that was all that needed to be done by someone using it). Thanks for helping me refine my question.

0 Likes

I understand now what you want.

I'm not aware a way to do this automatically. I think the only way is to create an API for your component and let the user call it in the main().

That is what I'm suspecting as well, but am hoping I've missed something.

I am wondering now, looking at the wording, whether there's a back door I can use? Section 4.3.5 "Fixed Blocks" in the Component Author Guide, it says "For all fixed blocks, a parameter of cy_registers is available". In referring to the figure in section 4.3.1.1 "UDB Overview" it says "The blocks are color coded to differentiate between the types. Purple is a register, blue is a fixed block that performs a defined function, ...". The only blue block ("fixed block") that I can instantiate explicitly in my code is the cy_psoc3_count7 block, so I wonder if it will accept a cy_registers parameter? And if it does, will it check what register directive I pass in to it? The cy_registers parameter is not listed in the instantiation list in the guide for cy_psoc3_count7, so I am guessing this will not work, but I'll give it a try Wednesday (hopefully) and report back.

I scoured the Internet before I asked my question and have not been able to find a single reference to cy_registers, so I am not even sure how (or if) it is supposed to be used. The fact that it was listed in the "Implement a UDB Component" section suggests that there should be some way to access this capability from a library component's Verilog code. But maybe that's not the case, I don't know.

0 Likes

In a surprise to nobody, and despite the glimmer of hope from the wording in the Component Author Guide, the cy_psoc3_count7 component does not accept cy_registers as an argument.

This compiles fine:

cy_psoc3_count7 #(.cy_period(7'b1111111))

    C7Counter (.clock(CLK), .reset(1'b0), .load(1'b0), .enable(1'b1), .count(), .tc());

This results in the error, "'cy_registers' not a parameter of module 'cy_psoc3_count7'" during synthesis:

cy_psoc3_count7 #(.cy_period(7'b1111111), .cy_registers(""))

    C7Counter (.clock(CLK), .reset(1'b0), .load(1'b0), .enable(1'b1), .count(), .tc());

I guess unless someone from Cypress can help, I'll need to re-think my plans on this.

0 Likes