Build a custom component with internal interrupts

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

cross mob
Anonymous
Not applicable

 Hi,

   

I can't figure out how to create a component that has interrupts in It. 

   

I tried doing it using a library project, but since I can't build the project and if the interrupt block isn't built I can't define the block functionality. 

   

The same problem occurs when I try to use a design project and then add a component with a symbol and a schematic implementation (when I  build the project the component itself isn't built). 

   

Any Ideas how such a block is supposed to be built?

   

 For example say I want to build my own counter with a clock and an an interrupt block (rising edge) ,  so that each interrupt increases a global variable by 1. 

   

Thanks, 

   

        Peli

0 Likes
8 Replies
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

There is always the method to create internal to component

   

an output that contains your desired logic, then external to

   

component attach ISR component to that output.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

 Hi Dana,

   

It is indeed possible to add an Interrupt component (ISR) outside the component, put that way it will be harder to duplicate the component inside the Top design.

   

Also In my case the ISR component is responsible (via its code) to change the control values of digital muxes inside the custom block. So, though it is possible to do that, I think in my case it's bad practice.

   

Is there absolutely no way to put an ISR component inside a custom block?

   

Thanks again,

   

   Peli

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You may convert a complete schematic into a macro. When you additionally provide the APIs as .h and .c-files it may be manageable (although I've not done that yet).

   

 

   

Bob

0 Likes
Anonymous
Not applicable

 Hi Bob,

   

I'm not sure what's the difference when using a macro, but in a library project you can't  "build" a macro either.

   

I tried something different. I used the top design of a  design project to create a component and added a symbol to the top design. That way, because the component is the TopDesign, the ISR component can be built.

   

Then when I opened the created component inside a new project it contained the interrupt code (and all other block API's).

   

Here is the problem, when I opened the component isr_1.c code (component_1_isr_1.c) it didn't contain the changes made to the interrupt code(inside the define section and the CY_ISR section). 

   

Do you have an Idea why the code hasn't changed the way it was supposed to? 

0 Likes
Anonymous
Not applicable

What problem are you having?

   

I've done many ccomponents with isr and even dma inside. For just the reasons you gave. ISR and DMA dependent code lives in and is customized to the component. 

   

Don't forget to prefix all of the internals with the instance name tag. I use it so much it is setup as ctrl-shift-i in my macro keyboard program.

   

 

   

Ed

0 Likes
Anonymous
Not applicable

 Hi,

   

O.K I figured It out, you have to change the ISR function Inside the component  after you add the custom component to your TopDesign and build the the project.

   

I was under the impression that the ISR code should be written inside the custom component itself,  before it is added to the TopDesign, so that was the source of the problem. 

   

 

   

Thanks for the help everyone

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I'm not sure what you're meaning. I do the ISR code inside the component.

   

here is a snippet, attached is a png of the component schematic.

   

//=====================================================================
//
//    `$INSTANCE_NAME`.c - component c code
//
//=====================================================================

#include "`$INSTANCE_NAME`.h"

PORT_CONTROL    *`$INSTANCE_NAME`_pcPtr[PARAM_PORT_SFX_CNT];

CY_ISR_PROTO(`$INSTANCE_NAME`_ISR_A_ISR);
CY_ISR_PROTO(`$INSTANCE_NAME`_ISR_B_ISR);

//---------------------------------------------------------------------
//
//    `$INSTANCE_NAME`_Start() - start function
//
//---------------------------------------------------------------------

void `$INSTANCE_NAME`_Start(void *control)
{
    uint8                    sfxIdx;
    register PORT_CONTROL    *pcPtr;
   
    pcPtr = control;
   
    if (pcPtr->portConfig[0].actMode == 'Y')
    {
        sfxIdx = pcPtr->portConfig[0].sfx - 'A';
       
        `$INSTANCE_NAME`_pcPtr[sfxIdx] = pcPtr;
       
        switch(sfxIdx)
        {
        case 0:
            J1_REG8(`$INSTANCE_NAME`_PixA_BitCount__CONTROL_AUX_CTL_REG) |= 0x20;
   
            `$INSTANCE_NAME`_ISR_A_StartEx(&`$INSTANCE_NAME`_ISR_A_ISR);

            pcPtr->DMA_Chan        = `$INSTANCE_NAME`_DMA_A_DmaInitialize(1,1,HI16(CYDEV_SRAM_BASE),HI16(CYDEV_PERIPH_BASE));
            pcPtr->DMA_TDs[0]    = CyDmaTdAllocate();
            CyDmaTdSetConfiguration(pcPtr->DMA_TDs[0],pcPtr->outBfrByteCnt,DMA_DISABLE_TD,TD_INC_SRC_ADR);
            CyDmaTdSetAddress(pcPtr->DMA_TDs[0], LO16((uint32) (pcPtr->output[0].outBfrPtr)), LO16((uint32) `$INSTANCE_NAME`_PixA_pixel_u0__F0_REG));
            CyDmaChSetInitialTd(pcPtr->DMA_Chan, pcPtr->DMA_TDs[0]);
            break;
           
        case 1:
            J1_REG8(`$INSTANCE_NAME`_PixB_BitCount__CONTROL_AUX_CTL_REG) |= 0x20;
   
            `$INSTANCE_NAME`_ISR_B_StartEx(&`$INSTANCE_NAME`_ISR_B_ISR);

            pcPtr->DMA_Chan        = `$INSTANCE_NAME`_DMA_B_DmaInitialize(1,1,HI16(CYDEV_SRAM_BASE),HI16(CYDEV_PERIPH_BASE));
            pcPtr->DMA_TDs[0]    = CyDmaTdAllocate();
            CyDmaTdSetConfiguration(pcPtr->DMA_TDs[0],pcPtr->outBfrByteCnt,DMA_DISABLE_TD,TD_INC_SRC_ADR);
            CyDmaTdSetAddress(pcPtr->DMA_TDs[0], LO16((uint32) (pcPtr->output[0].outBfrPtr)), LO16((uint32) `$INSTANCE_NAME`_PixB_pixel_u0__F0_REG));
            CyDmaChSetInitialTd(pcPtr->DMA_Chan, pcPtr->DMA_TDs[0]);
            break;
        }
       
        switch(pcPtr->portConfig[0].type)
        {
        case PT_DMX:
        case PT_REN:
            `$INSTANCE_NAME`_Ctrl_Control = 0b1111;
            break;
           
        case PT_LPD6803:
        case PT_WS2801:
            `$INSTANCE_NAME`_Ctrl_Control = 0b1001;
            `$INSTANCE_NAME`_Clock_SetDivider(BCLK__BUS_CLK__HZ / ( 2000ul * (uint32) pcPtr->portConfig[0].speed));
            break;
           
        case PT_TM180X:
            `$INSTANCE_NAME`_Ctrl_Control = 0b1010;
            `$INSTANCE_NAME`_Clock_SetDivider(BCLK__BUS_CLK__HZ / ( 6000ul * (uint32) pcPtr->portConfig[0].speed));
            break;
           
        case PT_TLS3001:
            `$INSTANCE_NAME`_Ctrl_Control = 0b1111;
            break;
           
        case PT_WS281X:
            `$INSTANCE_NAME`_Ctrl_Control = 0b1100;
            `$INSTANCE_NAME`_Clock_SetDivider(BCLK__BUS_CLK__HZ / (10000ul * (uint32) pcPtr->portConfig[0].speed));
            break;
       
        default:
            break;
        }
    }
}

//---------------------------------------------------------------------
//
//    `$INSTANCE_NAME`_ISR_A_ISR() - the ISR for the idle
//
//---------------------------------------------------------------------

CY_ISR(`$INSTANCE_NAME`_ISR_A_ISR)
{
    `$INSTANCE_NAME`_ISR_A_ClearPending();
    `$INSTANCE_NAME`_pcPtr[0]->portState    = PORT_STATE_DONE;
}

//---------------------------------------------------------------------
//
//    `$INSTANCE_NAME`_ISR_B_ISR() - the ISR for the idle
//
//---------------------------------------------------------------------

CY_ISR(`$INSTANCE_NAME`_ISR_B_ISR)
{
    `$INSTANCE_NAME`_ISR_B_ClearPending();
    `$INSTANCE_NAME`_pcPtr[1]->portState    = PORT_STATE_DONE;
}

0 Likes
Anonymous
Not applicable

 Thanks Ed, that will be very helpful!

0 Likes