This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6748/OMAPL-L138 UPP ISR

Hi,

I am using the Logic evm6748 board and trying to use the ADC/DAC interface.  I have used the BIOS to create the isr as shown

bios.HWI.instance("HWI_INT4").interruptSelectNumber = 94;
bios.HWI.instance("HWI_INT4").fxn = prog.extern("HWI_UPPisr");

and this semaphore

var semDac = bios.SEM.create("semDac");
semDac.count = 1;

I created this task dynamically

void DacTask(void)
{
  UPXS2_t * UPQS2r = (UPXS2_t *)&(UPP->UPQS2);
  Uns ticks;

      /* clear all interrupts, bits 4 thru 15                                   */
    ICR = 0xFFF0;
   
    /* enable the bits for non maskable interrupt and CPUINT4                 */
    IER |= 0x12;
   
    /* enable interrupts, set GIE bit                                         */
    _enable_interrupts();

  while (1)
  {
   config.UPIES.bits.EOLQ =1;

    LOG_printf(&trace, "The time in task is: %d ticks",(Int)TSK_time());

    UPP->UPQD0 = (uint32_t)&xmit_buffer;//add next DMA transfer
    UPP->UPQD1 = 0x00010080;                        //1 lines 128 bytes per line
    UPP->UPQD2 = 0x00000080;                        //no offset between lines

   SEM_pend(&semDac,SYS_FOREVER);

  }
}

And I follow the UPP user manual section 2.6.4 as written

void HWI_UPPisr(void)
{
  UPISR_t interrupt_status;
  interrupt_status.value = UPP->UPIER;

  while (interrupt_status.value != 0)
  {
    if (interrupt_status.bits.EOLQ)
    {
      interrupt_status.bits.EOLQ = 1; // clear EOLQ

      // Handle EOLQ...
      SEM_post(&semDac);

    }
    if (interrupt_status.bits.EOWQ)
    {
      interrupt_status.bits.EOWQ = 1; // clear EOLQ
      // Handle EOLQ...
    }
    // loop again if any interrupts are left
    interrupt_status.value = UPP->UPIER;
  } // end of while


  // write end of interrupt vector to allow future calls
  UPP->UPEOI = 0;
} // end of function

As described in the manual, when I write to UPP->UPIER.bits.EOLQ =1 it should clear this bit.  But this bit does not get cleared, and I got stuck in this forever loop inside this ISR.

Could some one help me?

Thanks.

 

 

 

  • Kevin,

    Are you sure that you're writing back to the actual register and not just to some intermediate variable?  Here are a few things that could conceivably go wrong:

    1. You are only writing 1 to some intermediate variable holding a copy of the register contents
    2. Your write is being cached but not actually written back to the memory map
    3. Your write is being optimized out because the compiler sees that you are writing 1 after checking that the value is already 1

    You can get around #2 and #3 by declaring your variable as volatile.

    Also: if you haven't already seen the uPP driver for DSP/BIOS, you might want to take a look.  We provide full source code for this driver, so you can use it as a reference even if you prefer to use your own code.

    Hope this helps.

  • Thanks Joe,

    You are correct in item #1.  After replacing this line

    interrupt_status.bits.EOLQ = 1;

    with

    UPP->UPIER = 0x1000; // clear EOLQ

    then my isr works O.K but only for one time.

    It never gets interrupted again with my DacTask starts another DMA transfer  immediately after it gets the semaphore.  Your uPP driver is really an excellent reference source. 

    void DacTask(void){ 

     Int32 oldCSR; 

     while (1)
      {
        LOG_printf(&trace, "The time in task is: %d ticks",(Int)TSK_time());

       oldCSR = HWI_disable();

        UPP->UPQD0 = (uint32_t)&xmit_buffer;//add next DMA transfer
        UPP->UPQD1 = 0x00010080;                        //1 lines 128 bytes per line
        UPP->UPQD2 = 0x00000080;                        //no offset between lines
         UPP->UPIES=0x1000;

        // re-enable interrupts
        HWI_restore(oldCSR);

       SEM_pend(&semDac,SYS_FOREVER);
     }

    }