8 Replies Latest reply on Oct 17, 2014 1:12 AM by peli.fidelman

    Build a custom component with internal interrupts

    peli.fidelman

       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

        • 1. Re: Build a custom component with internal interrupts
          user_14586677

          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.

          • 2. Re: Build a custom component with internal interrupts
            peli.fidelman

             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

            • 3. Re: Build a custom component with internal interrupts
              user_1377889

              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

              • 4. Re: Build a custom component with internal interrupts
                peli.fidelman

                 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? 

                • 5. Re: Build a custom component with internal interrupts
                  user_274749305

                  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

                  • 6. Re: Build a custom component with internal interrupts
                    peli.fidelman

                     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

                    • 7. Re: Build a custom component with internal interrupts
                      user_274749305

                      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;
                      }

                      • 8. Re: Build a custom component with internal interrupts
                        peli.fidelman

                         Thanks Ed, that will be very helpful!