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.

UPP interrupt C6748

ggg

  • Hi,

     

    I am writing UPP driver and application for C6748.

    I am not getting the required event and interrupt after the control register configurations

    If anyone has any inputs pls share.

    Thanks

    Veena

    /*Control Register with Duplex Mode 1 Channel A Transmitter and Channel B Receiver*/

    /* Single data rate , Datawidth = 16,DataPacking = No data Packing,Justification =3h reserved*/


    #define UPP_UPCTL_VALUE 0x62630007


    /* UPICR Channel A = TX, Channel B = Rx ,ClkDivA =1, ClkDivB =1, TRISA = HighImpedeance,TRISB = HighImpedeance ,ENA = 0,ENB = 1 */

    /*CLKIVA =0(Not inverted),CLKINVB = 0,WAITA =1 ,WAITB =0,WAITPOLA = 0,WAITPOLA = 0,STARTA = 0,STARTB=1,STARTPOLA =0,STARTPOLB = 0.*/


    #define UPP_UPICR_VALUE 0x30182020


    /* UPTCR ChanA Tx size = 256bytes ReadSize =256bytes */

    #define UPP_UPTCR_VALUE 0x03030303


     

    /* UPIVR Both chan A and Chan B will be FFFFFFF when idle. */

    #define UPP_UPIVR_VALUE 0xFFFFFFFF


    #define UPP_UPIES_VALUE 0x00000EFF


    #define UPP_UPPCR_VALUE 0x00000007


     

    #define UPP_EVENT 94

    Code:

    m_pUppRegs = (CSL_UppRegsOvly)CSL_UPP_0_REGS;

     


    m_pUppRegs ->UPCTL |= UPP_UPCTL_VALUE;


    m_pUppRegs ->UPICR |= UPP_UPICR_VALUE;


    m_pUppRegs ->UPIVR |= UPP_UPIVR_VALUE;


    m_pUppRegs ->UPTCR |= UPP_UPTCR_VALUE;


    m_pUppRegs ->UPIES |= UPP_UPIES_VALUE;

     

     

     


    //Register the ISR

     

    /* map Upp event to cpu int5

    */

    CSL_FINS(g_pCSystemHandler->m_pIntcRegs->INTMUX1,

    DSPINTC_INTMUX1_INTSEL5,

    UPP_EVENT);

     

    /* set ISTP to point to the vector table address */


    //ISTP = (unsigned int)InterruptVectorTable;

     

    /* clear all interrupts, bits 4 thru 15 */

    ICR = 0xFFF0;

     

    /* enable the bits for non maskable interrupt and */

    IER = 0xF2;

     

    /* enable interrupts, set GIE bit */

    _enable_interrupts();

     

     

     

  • Veena,

    Are you writing your own driver for uPP, or using one of the drivers provided by TI?  There are two uPP drivers that are already available:

    1. A simple IOM driver posted to the wiki:
      http://processors.wiki.ti.com/index.php/Using_the_uPP_DSP/BIOS_Driver
    2. A more sophisticated driver included as part of the BIOS PSP:
      http://software-dl.ti.com/dsps/dsps_public_sw/psp/BIOSPSP/index.html

    I recommend looking at these drivers if you haven't already done so.  Even if you want to use your own driver, the first driver I linked to above includes a very simple test application that could be useful for comparing with your own code.  That could help you figure out what is going wrong.

    Also, I recommend reviewing section 2.6 of the uPP user guide.  This section explains the step-by-step process that you should follow to initialize and configure the uPP peripheral.  I see some (but not all) of those steps reflected in your current source code.

    Hope this helps.

  • Dear Joe,

     

    Thanks a lot.  It was V helpful.

    I have gone through the step by step proceesure in the user guide and had coded the same.

    the BIOSPSP has application which is polling based and not interrupt based.

    the BIOS_Driver is the one that can solve my purpose. I would appreciate if you could provide me something on the application for the CSL Driver( upp_bios_drv.pjt) to use the functions is the project.

    regards

    Veena

  • Dear Joe,

    I have tried using BIOS Driver.

    When I create task using

    // create task

    demo_tsk = TSK_create(LOCAL_upp_demo,

    NULL, 0);

    It sometiemes creates the task sometimes it fails.

    Could you provide me some inputs on this?

    my .tcf file is below

    utils.loadPlatform("ti.platforms.evm6748");

     

    /* The following DSP/BIOS Features are enabled. */

    bios.enableRealTimeAnalysis(prog);

    bios.enableRtdx(prog);

    bios.enableTskManager(prog);

     

    bios.MEM.STACKSIZE = 0x1000;

    bios.MEM.ARGSSEG = prog.get("DDR");

    bios.MEM.STACKSEG = prog.get("DDR");

    bios.MEM.GBLINITSEG = prog.get("DDR");

    bios.MEM.TRCDATASEG = prog.get("DDR");

    bios.MEM.SYSDATASEG = prog.get("DDR");

    bios.MEM.OBJSEG = prog.get("DDR");

    bios.MEM.BIOSSEG = prog.get("DDR");

    bios.MEM.SYSINITSEG = prog.get("DDR");

    bios.MEM.HWISEG = prog.get("DDR");

    bios.MEM.HWIVECSEG = prog.get("DDR");

    bios.MEM.RTDXTEXTSEG = prog.get("DDR");

    bios.MEM.TEXTSEG = prog.get("DDR");

    bios.MEM.SWITCHSEG = prog.get("DDR");

    bios.MEM.BSSSEG = prog.get("DDR");

    bios.MEM.FARSEG = prog.get("DDR");

    bios.MEM.CINITSEG = prog.get("DDR");

    bios.MEM.PINITSEG = prog.get("DDR");

    bios.MEM.CONSTSEG = prog.get("DDR");

    bios.MEM.DATASEG = prog.get("DDR");

    bios.MEM.CIOSEG = prog.get("DDR");

    bios.MEM.ENABLELOADADDR = 1;

    bios.MEM.LOADBIOSSEG = prog.get("DDR");

    bios.MEM.LOADSYSINITSEG = prog.get("DDR");

    bios.MEM.LOADGBLINITSEG = prog.get("DDR");

    bios.MEM.LOADTRCDATASEG = prog.get("DDR");

    bios.MEM.LOADTEXTSEG = prog.get("DDR");

    bios.MEM.LOADSWITCHSEG = prog.get("DDR");

    bios.MEM.LOADCINITSEG = prog.get("DDR");

    bios.MEM.LOADPINITSEG = prog.get("DDR");

    bios.MEM.LOADCONSTSEG = prog.get("DDR");

    bios.MEM.LOADHWISEG = prog.get("DDR");

    bios.MEM.LOADHWIVECSEG = prog.get("DDR");

    bios.MEM.LOADRTDXTEXTSEG = prog.get("DDR");

    bios.MEM.NOMEMORYHEAPS = 0;

    bios.MEM.instance("DDR").createHeap = 1;

    bios.MEM.instance("DDR").heapSize = 0x00100000;

    bios.MEM.BIOSOBJSEG = prog.get("DDR");

    bios.MEM.MALLOCSEG = prog.get("DDR");

    bios.LOG.create("trace");

    bios.LOG.instance("trace").bufLen = 1024;

    bios.TSK.STACKSEG = prog.get("DDR");

     

    bios.UDEV.create("UPP");

    bios.UDEV.instance("UPP").fxnTableType = "IOM_Fxns";

    bios.UDEV.instance("UPP").comment = "uPP IOM mini driver";

    bios.UDEV.instance("UPP").initFxn = prog.extern("UPP_INIT");

    bios.UDEV.instance("UPP").fxnTable = prog.extern("UPP_FXN_TABLE");

    bios.UDEV.instance("UPP").params = prog.extern("UPP_DEV_CONFIG");

     

    bios.ECM.ENABLE = 1;

    bios.HWI.instance("HWI_INT7").interruptSelectNumber = 2;

     

    // !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!

    /* Create application task */

     

    prog.gen();

     

    Also I wanted to us the PSP driver.

    the packag has a min with initializations only. Any application suitable could also be of help

    Regards

    Veena

     

  • Veena,

    I don't see anything wrong with your TCF file.  Let me make sure I understand what's happening.  When you run your application, the call to TSK_create() sometimes fails by returning a NULL (0) value.  However, this doesn't happen every time you run the application.  Is this correct?  Is there some pattern you can notice (i.e. TSK_create works the first time you load and run your application but not the second, or something like that)?

    It's unusual for TSK_create() to be inconsistent in this way.  I definitely want to help you solve this problem.

  • Joe,

    Yes.. you are correct. Thats exacltly whats happening.. without a hardware reset I try to load the same program again and the handle returns NULL(0) value.

    Regards

    Veena

     

  • Veena,

    When you attempt to re-run the program, do you reload it or merely reset the PC to the program entrypoint?  It sounds to me like DSP/BIOS is not getting properly reset/re-initialized between one run and the next.  If you could, please list the steps (i.e. menu commands in CCS) that you're using to restart your application.

  • Hi Joe,

    I'm using UPP IOM driver which you had mentioned,

    I am unable to figure out how to configure it in DUPLEX 1 mode.

    How to configure

    UPCTL register?

    Thanks in Advance

    regards

    Veena

  • Veena,

    Take a look at the "test" application that comes with the driver; this should give you the basic idea how to setup the driver.  To configure uPP in duplex 1 mode, all you need to do is configure the driver to use both channels, with channel A transmitting and channel B receiving.  The driver should then take care of all the uPP register configuration.

    Your code to setup the driver params struct may look something like this:

    upp_UserParams upp_setup = UPP_USERPARAMS;

    // common settings
    upp_setup.params.channels = 2;

    // settings for channel A
    upp_setup.params.A.direction = upp_dir_xmit;
    upp_setup.params.A.clock_div = 7;
    upp_setup.params.A.idle_value = 0xAAAA;

    // settings for channel B
    upp_setup.params.B.direction = upp_dir_rcv;
    upp_setup.params.B.clock_div = 7;
    upp_setup.params.B.idle_value = 0xBBBB;

    // not shown: setup callback functions for various interrupt events

    Hope this helps.

  • Hi Joe, I have configured the driver in Duplex 1 Without loopback.

    I am expecting interrupt to be genrated as soon as there is some data in buffer A.

    But I do not get any interrupt.
    Can u suggest any better method?

    Please fine the changes in red

    // application include file
    #include "upp_drv_testcfg.h"
    #include <upp_md.h>
    #include  <ti\pspiom\cslr\cslr_upp.h>
    #include "cslr_gpio.h"

    extern "C" {
     #include "evmc6748.h"
     #include "evmc6748_timer.h"

    }

    // PSC registers (lifted from GEL)
    #define PSC1_BASE       0x01E27000
    #define PSC1_MDCTL      (PSC1_BASE+0xA00)
    #define PSC1_MDSTAT     (PSC1_BASE+0x800)
    #define PSC1_PTCMD      *(unsigned int*) (PSC1_BASE + 0x120)
    #define PSC1_PTSTAT     *(unsigned int*) (PSC1_BASE + 0x128)

    // kick and pinmux registers (lifted from GEL)
    #define SYS_BASE        0x01C14000
    #define KICK0R          *(unsigned int*)(SYS_BASE + 0x038)
    #define KICK1R          *(unsigned int*)(SYS_BASE + 0x03C)
    #define PINMUX0         *(unsigned int*)(SYS_BASE + 0x120)
    #define PINMUX1         *(unsigned int*)(SYS_BASE + 0x124)
    #define PINMUX2         *(unsigned int*)(SYS_BASE + 0x128)
    #define PINMUX3         *(unsigned int*)(SYS_BASE + 0x12C)
    #define PINMUX4         *(unsigned int*)(SYS_BASE + 0x130)
    #define PINMUX5         *(unsigned int*)(SYS_BASE + 0x134)
    #define PINMUX6         *(unsigned int*)(SYS_BASE + 0x138)
    #define PINMUX7         *(unsigned int*)(SYS_BASE + 0x13C)
    #define PINMUX8         *(unsigned int*)(SYS_BASE + 0x140)
    #define PINMUX9         *(unsigned int*)(SYS_BASE + 0x144)
    #define PINMUX10        *(unsigned int*)(SYS_BASE + 0x148)
    #define PINMUX11        *(unsigned int*)(SYS_BASE + 0x14C)
    #define PINMUX12        *(unsigned int*)(SYS_BASE + 0x150)
    #define PINMUX13        *(unsigned int*)(SYS_BASE + 0x154)
    #define PINMUX14        *(unsigned int*)(SYS_BASE + 0x158)
    #define PINMUX15        *(unsigned int*)(SYS_BASE + 0x15C)
    #define PINMUX16        *(unsigned int*)(SYS_BASE + 0x160)
    #define PINMUX17        *(unsigned int*)(SYS_BASE + 0x164)
    #define PINMUX18        *(unsigned int*)(SYS_BASE + 0x168)
    #define PINMUX19        *(unsigned int*)(SYS_BASE + 0x16C)

    CSL_GpioRegsOvly     m_pGPIORegs ;

    CSL_UppRegsOvly      UppRegsOvly;

    // static init struct for uPP driver (use defaults)
    const upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;

    // local typedef
    typedef enum LOCAL_mode {
        LOCAL_mode_AB_dlb,
        LOCAL_mode_BA_dlb,
        LOCAL_mode_A_transmit,
        LOCAL_mode_A_receive,
        LOCAL_mode_B_receive
    } LOCAL_mode;

    // configuration macros
    #define upp_line_size        (1024)
    #define upp_line_count       (2)
    #define upp_line_offset      (upp_line_size)
    #define upp_clock_div        0//(7)
    #define upp_demo_mode        (LOCAL_mode_AB_dlb)

    // global variables
    volatile int upp_interrupt_count = 0;
    volatile int upp_error_count = 0;
    LOCAL_mode upp_mode = upp_demo_mode;
    Uint8 upp_buffer_a[upp_line_size];// * upp_line_count];
    Uint8 upp_buffer_b[upp_line_size];// * upp_line_count];

    // local functions
    static int LOCAL_upp_demo();
    static void LOCAL_upp_config(upp_UserParams *upp_setup);
    static void LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);
    static void LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
    static void LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
    static void LOCAL_kick_unlock();
    static void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int LPSC_num);
    static void LOCAL_apply_upp_pinmux();

    Fxn CUppDriver::UppDeviceInit()
    {
      //return ulnStatus;
      
       TSK_Handle demo_tsk;
       
         // system initialization (doesn't rely on GEL)
         printf("UPP Test start-----------\n");
             // unlock device
            KICK_Unlock();

            // turn on uPP LPSC
            PSC1_LPSC_enable(0, 19);

            // enable uPP pinmux - enable all uPP pin functions
            Apply_Upp_PINMUX();

            // enable HWI7 (tied to ECM block 2; see TCF)
            C64_enableIER(1 << 9);

      UppTransferBegin();
       
       
    }

    // LOCAL_upp_demo is the primary DSP/BIOS TSK function.  It is called
    // after main


    static int CUppDriver::UppTransferBegin()
    {
     upp_UserParams upp_setup;
        upp_Transfer upp_xfer_a, upp_xfer_b;
        GIO_Handle upph;
        int i, status, target_int_count;
     size_t  Psize = 16;
     
     
       
        // initialize uPP buffers
        for (i = 0; i < sizeof(upp_buffer_a); i++) //sizeof(upp_buffer_a) / 4
        {
            // put data in transmit buffer and clear receive buffer
            if (upp_mode == LOCAL_mode_BA_dlb)
            {
                ((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555;
                ((Uint32 *)upp_buffer_a)[i] = 0x00000000;
            }
            else
            {
                ((Uint32 *)upp_buffer_a)[i] = i;//0xAAAA5555;
                ((Uint32 *)upp_buffer_b)[i] = 0x00000000;
            }
           
            if(upp_mode==LOCAL_mode_A_transmit)
             {
              
             ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;
             }

         if(upp_mode==LOCAL_mode_B_receive)
             {
              
       ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;
              
             }           
           
        }

     upp_setup.params.A.width = 16;
        // specify driver parameters
        LOCAL_upp_config(&upp_setup);

        // create driver handle
        upph = GIO_create("/UPP", IOM_INOUT, &status, &upp_setup, NULL);
        if (upph == NULL)
        {
            LOG_printf (&trace, "GIO_create failed");
            //return -1;
        }

        // program transfer(s)
        LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b);
      
        LOG_printf (&trace, "Programming uPP transfers...");


        // note: begin read first if in DLB mode
        switch (upp_mode)
        {
            case LOCAL_mode_AB_dlb:
             
                status  = GIO_read(upph, &upp_xfer_b,  NULL);
                status |= GIO_write(upph, &upp_xfer_a, NULL);
                break;

            case LOCAL_mode_BA_dlb:
                status  = GIO_read(upph, &upp_xfer_a, NULL);
                status |= GIO_write(upph, &upp_xfer_b, NULL);
                break;

            case LOCAL_mode_A_transmit:
                status  = GIO_write(upph, &upp_xfer_a, NULL);
                break;

            case LOCAL_mode_A_receive:
                status  = GIO_read(upph, &upp_xfer_a, NULL);
                break;
               
      case LOCAL_mode_B_receive:
                status  = GIO_read(upph, &upp_xfer_b, NULL);
                break;           

            default:
                // unrecognized mode (shouldn't happen)
                status  = -1;
                break;
        }
     
     
           
        // catch GIO_submit errors)
        if (status < 0)
        {
            LOG_printf(&trace, "Error programming uPP transfers.\n");
            upp_error_count++;
        }


        // wait until transfer(s) complete
        target_int_count = (upp_mode == LOCAL_mode_AB_dlb  ||
                             upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;
                            

       while (upp_interrupt_count < target_int_count && upp_error_count == 0)
        asm(" nop");
        

        // check buffers (loopback modes only)
        if (target_int_count == 2 && upp_error_count == 0)
            for (i = 0; i < sizeof(upp_buffer_a); i++)
                if (upp_buffer_a[i] != upp_buffer_b[i])
                {
                   // LOG_printf(&trace, "Data mismatch in buffers.\n");
          printf("Data mismatch in buffers.\n");
                    upp_error_count++;
                }

        // report test result
        if (upp_error_count)
    //        LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count);
            printf("uPP transfers completed with %u errors.\n", upp_error_count);
        else
         //   LOG_printf (&trace, "uPP transfers complete!");
         printf("uPP transfers complete!\n");

     

        return 0;

    }

    static void LOCAL_upp_config(upp_UserParams *upp_setup)
    {
       start with default settings
        *upp_setup = UPP_USERPARAMS;

        upp_setup->params.B.clock_div = upp_clock_div;
        upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb

     upp_setup->params.B.en_enable = TRUE;
     upp_setup->params.B.en_wait = FALSE;
     upp_setup->params.B.en_start = FALSE;
     upp_setup->params.A.clock_div =0;
     upp_setup->params.B.clock_div =0;

     upp_setup->params.A.width = 16;
     upp_setup->params.B.width = 16;
     
        switch (upp_mode)
        {
            case LOCAL_mode_AB_dlb:
                // A-to-B loopback
                upp_setup->params.A.direction = upp_dir_xmit;
                upp_setup->params.B.direction = upp_dir_rcv;
                upp_setup->params.channels = 2;
                //upp_setup->params.special_mode = upp_digital_loopback;
                UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;
                UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;
                break;

            case LOCAL_mode_BA_dlb:
                // B-to-A loopback
                upp_setup->params.A.direction = upp_dir_rcv;
                upp_setup->params.B.direction = upp_dir_xmit;
                upp_setup->params.channels = 2;
                upp_setup->params.special_mode = upp_digital_loopback;
                break;

            case LOCAL_mode_A_transmit:
                // Single channel transmit
                upp_setup->params.A.direction = upp_dir_xmit;
                break;

            case LOCAL_mode_A_receive:
                // Single channel receive
                upp_setup->params.A.direction = upp_dir_rcv;
                break;

      case LOCAL_mode_B_receive:
                // Single channel receive
                upp_setup->params.B.direction = upp_dir_rcv;
                break;           

            default:
                // unrecognized mode (shouldn't happen)
                LOG_printf(&trace, "Warning: unrecognized uPP mode\n");
                break;
        }
    }

     

    // LOCAL_upp_config_xfers initializes uPP transfers according to parameters
    // defined in local macros

    static void LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)
    {
        // start with default settings
        *xfer_a = UPP_TRANSFER;
        *xfer_b = UPP_TRANSFER;

        // apply common settings
        xfer_a->windowAddr = upp_buffer_a;
        xfer_a->lineCount = upp_line_count;
        xfer_a->lineSize =   upp_line_size;
        xfer_a->lineOffset = upp_line_offset;
        xfer_a->channel = upp_A;

        xfer_b->windowAddr = upp_buffer_b;
        xfer_b->lineCount =  upp_line_count;
        xfer_b->lineSize =   upp_line_size;
        xfer_b->lineOffset = upp_line_offset;
        xfer_b->channel = upp_B;

        // note: upp_xfer_b will only be used in DLB modes
    }


    // LOCAL_upp_complete_cb is a callback function used to track the
    // completion of uPP transfers (i.e. EOW events)

    static void LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
    {
    //    LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit);
     printf("uPP interrupt: 0x%08X", upp_isr_bit);
        upp_interrupt_count++;
        // note: only uPP HWI is enabled, so increment should be atomic/safe
    }


    // LOCAL_upp_error_cb is a callback function used to track uPP error
    // events (underrun/overflow, internal error, or DMA programming error)

    static void LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
    {
        LOG_printf(&trace, "uPP error: 0x%08X", upp_isr_bit);
        upp_error_count++;
        // note: only uPP HWI is enabled, so increment should be atomic/safe
    }


     LOCAL_kick_unlock allows register access at run time.  Based on code
     taken from GEL file

    static void LOCAL_kick_unlock()
    {
        // enables register access at run time
        KICK0R = 0x83e70b13;  // Kick0 register + data (unlock)
        KICK1R = 0x95a4f1e0;  // Kick1 register + data (unlock)
    }


    // LOCAL_PSC1_LPSC_enable powers on one LPSC.  Based on code taken from
    // GEL file

    static void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int LPSC_num)
    {
        *(unsigned int*) (PSC1_MDCTL + 4 * LPSC_num) =
            (*(unsigned int*) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;
       
        PSC1_PTCMD = 0x1 << PD;

        // Wait for power state transition to finish
        while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop");
        while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop");
    }


    // LOCAL_apply_upp_pinmux enables all uPP pin functions.  Based on code taken
    // from GEL file

    static void LOCAL_apply_upp_pinmux()
    {
        // all pins (channel A, channel B, DATA, and XDATA)
        PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000;
        PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400;
        PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444;
        PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444;
        PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444;
        PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444;
    }


    //-------------
    // END OF FILE
    //-------------

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    // application include file

     

    #include

     

     

    "upp_drv_testcfg.h"

     

    #include <upp_md.h>

     

     

    #include

     

     

    <ti\pspiom\cslr\cslr_upp.h>

    #include

     

     

    "cslr_gpio.h"

     

    extern

     

     

    "C"

    {

     

     

    #include

    "evmc6748.h"

     

     

     

    #include

    "evmc6748_timer.h"

    }

    // PSC registers (lifted from GEL)

    #define

     

     

     

    PSC1_BASE 0x01E27000

    #define

     

     

     

    PSC1_MDCTL (PSC1_BASE+0xA00)

    #define

     

     

     

    PSC1_MDSTAT (PSC1_BASE+0x800)

     

    #define

     

     

    PSC1_PTCMD *(unsigned int

    *) (PSC1_BASE + 0x120)

     

    #define

     

     

    PSC1_PTSTAT *(unsigned int

    *) (PSC1_BASE + 0x128)

    // kick and pinmux registers (lifted from GEL)

    #define

     

     

     

    SYS_BASE 0x01C14000

     

    #define

     

     

    KICK0R *(unsigned int

    *)(SYS_BASE + 0x038)

     

    #define

     

     

    KICK1R *(unsigned int

    *)(SYS_BASE + 0x03C)

     

    #define

     

     

    PINMUX0 *(unsigned int

    *)(SYS_BASE + 0x120)

     

    #define

     

     

    PINMUX1 *(unsigned int

    *)(SYS_BASE + 0x124)

     

    #define

     

     

    PINMUX2 *(unsigned int

    *)(SYS_BASE + 0x128)

     

    #define

     

     

    PINMUX3 *(unsigned int

    *)(SYS_BASE + 0x12C)

     

    #define

     

     

    PINMUX4 *(unsigned int

    *)(SYS_BASE + 0x130)

     

    #define

     

     

    PINMUX5 *(unsigned int

    *)(SYS_BASE + 0x134)

     

    #define

     

     

    PINMUX6 *(unsigned int

    *)(SYS_BASE + 0x138)

     

    #define

     

     

    PINMUX7 *(unsigned int

    *)(SYS_BASE + 0x13C)

     

    #define

     

     

    PINMUX8 *(unsigned int

    *)(SYS_BASE + 0x140)

     

    #define

     

     

    PINMUX9 *(unsigned int

    *)(SYS_BASE + 0x144)

     

    #define

     

     

    PINMUX10 *(unsigned int

    *)(SYS_BASE + 0x148)

     

    #define

     

     

    PINMUX11 *(unsigned int

    *)(SYS_BASE + 0x14C)

     

    #define

     

     

    PINMUX12 *(unsigned int

    *)(SYS_BASE + 0x150)

     

    #define

     

     

    PINMUX13 *(unsigned int

    *)(SYS_BASE + 0x154)

     

    #define

     

     

    PINMUX14 *(unsigned int

    *)(SYS_BASE + 0x158)

     

    #define

     

     

    PINMUX15 *(unsigned int

    *)(SYS_BASE + 0x15C)

     

    #define

     

     

    PINMUX16 *(unsigned int

    *)(SYS_BASE + 0x160)

     

    #define

     

     

    PINMUX17 *(unsigned int

    *)(SYS_BASE + 0x164)

     

    #define

     

     

    PINMUX18 *(unsigned int

    *)(SYS_BASE + 0x168)

     

    #define

     

     

    PINMUX19 *(unsigned int

    *)(SYS_BASE + 0x16C)

    CSL_GpioRegsOvly m_pGPIORegs ;

    CSL_UppRegsOvly UppRegsOvly;

    // static init struct for uPP driver (use defaults)

    const

     

     

     

    upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;

     

    // local typedef

    typedef

     

     

    enum

    LOCAL_mode {

    LOCAL_mode_AB_dlb,

    LOCAL_mode_BA_dlb,

    LOCAL_mode_A_transmit,

    LOCAL_mode_A_receive,

    LOCAL_mode_B_receive

    } LOCAL_mode;

    // configuration macros

    #define

     

     

     

    upp_line_size (1024)

    #define

     

     

     

    upp_line_count (2)

    #define

     

     

     

    upp_line_offset (upp_line_size)

     

    #define

     

     

    upp_clock_div 0

    //(7)

    #define

     

     

     

    upp_demo_mode (LOCAL_mode_AB_dlb)

     

    // global variables

    volatile

     

     

    int

    upp_interrupt_count = 0;

     

    volatile

     

     

    int

    upp_error_count = 0;

    LOCAL_mode upp_mode = upp_demo_mode;

    Uint8 upp_buffer_a[upp_line_size];

     

    // * upp_line_count];

    Uint8 upp_buffer_b[upp_line_size];

     

     

    // * upp_line_count];

    // local functions

     

    static

     

     

    int

    LOCAL_upp_demo();

     

    static

     

     

    void

    LOCAL_upp_config(upp_UserParams *upp_setup);

     

    static

     

     

    void

    LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);

     

    static

     

     

    void

    LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);

     

    static

     

     

    void

    LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);

     

    static

     

     

    void

    LOCAL_kick_unlock();

     

    static

     

     

    void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int

    LPSC_num);

     

    static

     

     

    void

    LOCAL_apply_upp_pinmux();

    Fxn CUppDriver::UppDeviceInit()

    {

     

     

    //return ulnStatus;

     

    TSK_Handle demo_tsk;

     

     

     

     

    // system initialization (doesn't rely on GEL)

     

    printf(

     

    "UPP Test start-----------\n"

    );

     

     

    // unlock device

    KICK_Unlock();

     

     

     

    // turn on uPP LPSC

    PSC1_LPSC_enable(0, 19);

     

     

     

    // enable uPP pinmux - enable all uPP pin functions

    Apply_Upp_PINMUX();

     

     

     

    // enable HWI7 (tied to ECM block 2; see TCF)

     

    C64_enableIER(1 << 9);

    UppTransferBegin();

     

     

     

    if

    (demo_tsk == NULL)

    LOG_printf(&trace,

     

    "TSK_create() failed.\n"

    );

     

    }

     

    // LOCAL_upp_demo is the primary DSP/BIOS TSK function. It is called

    // after main

     

    static

     

     

    int

    CUppDriver::UppTransferBegin()

    {

    upp_UserParams upp_setup;

    upp_Transfer upp_xfer_a, upp_xfer_b;

    GIO_Handle upph;

     

     

    int

    i, status, target_int_count;

    size_t Psize = 16;

     

     

     

     

     

    // initialize uPP buffers

     

     

     

    for (i = 0; i < sizeof(upp_buffer_a); i++)

    //sizeof(upp_buffer_a) / 4

    {

     

     

     

    // put data in transmit buffer and clear receive buffer

     

     

     

    if

    (upp_mode == LOCAL_mode_BA_dlb)

    {

    ((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555;

    ((Uint32 *)upp_buffer_a)[i] = 0x00000000;

    }

     

     

    else

    {

    ((Uint32 *)upp_buffer_a)[i] = i;

     

     

    //0xAAAA5555;

     

    ((Uint32 *)upp_buffer_b)[i] = 0x00000000;

    }

     

     

     

    if

    (upp_mode==LOCAL_mode_A_transmit)

    {

     

    ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;

    }

     

     

    if

    (upp_mode==LOCAL_mode_B_receive)

    {

     

    ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;

     

    }

     

    }

    upp_setup.params.A.width = 16;

     

     

    // specify driver parameters

    LOCAL_upp_config(&upp_setup);

     

     

     

    // create driver handle

     

    upph = GIO_create(

     

    "/UPP"

    , IOM_INOUT, &status, &upp_setup, NULL);

     

     

    if

    (upph == NULL)

    {

    LOG_printf (&trace,

     

    "GIO_create failed"

    );

     

     

    //return -1;

    }

     

     

     

    // program transfer(s)

     

    LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b);

     

    LOG_printf (&trace,

     

    "Programming uPP transfers..."

    );

     

     

     

    // note: begin read first if in DLB mode

     

     

     

    switch

    (upp_mode)

    {

     

     

    case

    LOCAL_mode_AB_dlb:

     

    status = GIO_read(upph, &upp_xfer_b, NULL);

    status |= GIO_write(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_BA_dlb:

    status = GIO_read(upph, &upp_xfer_a, NULL);

    status |= GIO_write(upph, &upp_xfer_b, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_transmit:

    status = GIO_write(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_receive:

    status = GIO_read(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

     

    case

    LOCAL_mode_B_receive:

    status = GIO_read(upph, &upp_xfer_b, NULL);

     

     

    break

    ;

     

     

    default

    :

     

     

    // unrecognized mode (shouldn't happen)

     

    status = -1;

     

     

    break

    ;

    }

     

     

     

     

     

    // catch GIO_submit errors)

     

     

     

    if

    (status < 0)

    {

    LOG_printf(&trace,

     

    "Error programming uPP transfers.\n"

    );

    upp_error_count++;

    }

     

     

     

    // wait until transfer(s) complete

     

    target_int_count = (upp_mode == LOCAL_mode_AB_dlb ||

    upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;

     

     

     

    while

    (upp_interrupt_count < target_int_count && upp_error_count == 0)

    asm(

     

    " nop"

    );

     

     

     

    // check buffers (loopback modes only)

     

     

     

    if

    (target_int_count == 2 && upp_error_count == 0)

     

     

    for (i = 0; i < sizeof

    (upp_buffer_a); i++)

     

     

    if

    (upp_buffer_a[i] != upp_buffer_b[i])

    {

     

     

    // LOG_printf(&trace, "Data mismatch in buffers.\n");

     

    printf(

     

    "Data mismatch in buffers.\n"

    );

    upp_error_count++;

    }

     

     

    // report test result

     

     

     

    if

    (upp_error_count)

     

    // LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count);

    printf(

     

    "uPP transfers completed with %u errors.\n"

    , upp_error_count);

     

     

    else

     

     

     

    // LOG_printf (&trace, "uPP transfers complete!");

     

    printf(

     

    "uPP transfers complete!\n"

    );

     

     

     

     

    return

    0;

    }

     

    static

     

     

    void

    LOCAL_upp_config(upp_UserParams *upp_setup)

    {

    start with

     

    default

    settings

    *upp_setup = UPP_USERPARAMS;

    upp_setup->params.B.clock_div = upp_clock_div;

    upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb;

     

    //(upp_CbFxn)Upp_Complete_CB;

     

    upp_setup->params.B.en_enable = TRUE;

    upp_setup->params.B.en_wait = FALSE;

    upp_setup->params.B.en_start = FALSE;

    upp_setup->params.A.clock_div =0;

    upp_setup->params.B.clock_div =0;

    upp_setup->params.A.width = 16;

    upp_setup->params.B.width = 16;

     

     

     

    switch

    (upp_mode)

    {

     

     

    case

    LOCAL_mode_AB_dlb:

     

     

    // A-to-B loopback

    upp_setup->params.A.direction = upp_dir_xmit;

    upp_setup->params.B.direction = upp_dir_rcv;

    upp_setup->params.channels = 2;

     

     

     

    //upp_setup->params.special_mode = upp_digital_loopback;

     

    UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;

    UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;

     

     

    break

    ;

     

     

    case

    LOCAL_mode_BA_dlb:

     

     

    // B-to-A loopback

     

    upp_setup->params.A.direction = upp_dir_rcv;

    upp_setup->params.B.direction = upp_dir_xmit;

    upp_setup->params.channels = 2;

    upp_setup->params.special_mode = upp_digital_loopback;

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_transmit:

     

     

    // Single channel transmit

     

    upp_setup->params.A.direction = upp_dir_xmit;

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_receive:

     

     

    // Single channel receive

     

    upp_setup->params.A.direction = upp_dir_rcv;

     

     

    break

    ;

     

     

    case

    LOCAL_mode_B_receive:

     

     

    // Single channel receive

     

    upp_setup->params.B.direction = upp_dir_rcv;

     

     

    break

    ;

     

     

    default

    :

     

     

    // unrecognized mode (shouldn't happen)

     

    LOG_printf(&trace,

     

    "Warning: unrecognized uPP mode\n"

    );

     

     

    break

    ;

    }

    }

     

     

     

    // LOCAL_upp_config_xfers initializes uPP transfers according to parameters

    // defined in local macros

    static

     

     

    void

    LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)

    {

     

     

    // start with default settings

    *xfer_a = UPP_TRANSFER;

    *xfer_b = UPP_TRANSFER;

     

     

     

    // apply common settings

    xfer_a->windowAddr = upp_buffer_a;

    xfer_a->lineCount = upp_line_count;

    xfer_a->lineSize = upp_line_size;

    xfer_a->lineOffset = upp_line_offset;

    xfer_a->channel = upp_A;

    xfer_b->windowAddr = upp_buffer_b;

    xfer_b->lineCount = upp_line_count;

    xfer_b->lineSize = upp_line_size;

    xfer_b->lineOffset = upp_line_offset;

    xfer_b->channel = upp_B;

     

     

     

    // note: upp_xfer_b will only be used in DLB modes

     

    }

     

    // LOCAL_upp_complete_cb is a callback function used to track the

    // completion of uPP transfers (i.e. EOW events)

    static

     

     

    void

    LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)

    {

     

    // LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit);

    printf(

     

    "uPP interrupt: 0x%08X"

    , upp_isr_bit);

    upp_interrupt_count++;

     

     

    // note: only uPP HWI is enabled, so increment should be atomic/safe

     

    }

     

    // LOCAL_upp_error_cb is a callback function used to track uPP error

    // events (underrun/overflow, internal error, or DMA programming error)

    static

     

     

    void

    LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)

    {

    LOG_printf(&trace,

     

    "uPP error: 0x%08X"

    , upp_isr_bit);

    upp_error_count++;

     

     

    // note: only uPP HWI is enabled, so increment should be atomic/safe

     

    }

     

    LOCAL_kick_unlock allows

     

    register

    access at run time. Based on code

    taken from GEL file

     

    static

     

     

    void

    LOCAL_kick_unlock()

    {

     

     

    // enables register access at run time

    KICK0R = 0x83e70b13;

     

     

    // Kick0 register + data (unlock)

    KICK1R = 0x95a4f1e0;

     

     

    // Kick1 register + data (unlock)

     

    }

     

    // LOCAL_PSC1_LPSC_enable powers on one LPSC. Based on code taken from

    // GEL file

    static

     

     

    void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int

    LPSC_num)

    {

    *(

     

    unsigned int

    *) (PSC1_MDCTL + 4 * LPSC_num) =

    (*(

     

    unsigned int

    *) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;

     

    PSC1_PTCMD = 0x1 << PD;

     

     

    // Wait for power state transition to finish

     

     

     

    while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop"

    );

     

     

    while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop"

    );

    }

     

     

    // LOCAL_apply_upp_pinmux enables all uPP pin functions. Based on code taken

    // from GEL file

    static

     

     

    void

    LOCAL_apply_upp_pinmux()

    {

     

     

    // all pins (channel A, channel B, DATA, and XDATA)

    PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000;

    PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400;

    PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444;

    PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444;

    PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444;

    PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444;

    }

     

    //-------------

    // END OF FILE

    //-------------

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    // application include file

     

     

     

     

     

    #include 

     

     

    "upp_drv_testcfg.h"

     

     

     

    #include <upp_md.h>

    #include

     

     

    <ti\pspiom\cslr\cslr_upp.h>

    #include "

     

     

    slr_gpio.h"

    extern

     

     

    "C"

     

     

    {

     

     

     

     

     

     

     

    #include "evmc6748.h"

     

     

    #include "evmc6748_timer.h"

    }

    // PSC registers (lifted from GEL)

    #define

     

     

     

    PSC1_BASE 0x01E27000

    #define

     

     

     

    PSC1_MDCTL (PSC1_BASE+0xA00)

    #define

     

     

     

    PSC1_MDSTAT (PSC1_BASE+0x800)

     

    #define

     

     

    PSC1_PTCMD *(unsigned int

     

     

    *) (PSC1_BASE + 0x120)

     

    #define

     

     

    PSC1_PTSTAT *(unsigned int

     

    *) (PSC1_BASE + 0x128)

    // kick and pinmux registers (lifted from GEL)

    #define

     

     

     

     

     

    SYS_BASE 0x01C14000

     

    #define

     

     

    KICK0R *(unsigned int

     

    *)(SYS_BASE + 0x038)

     

    #define

     

     

    KICK1R *(unsigned int

     

    *)(SYS_BASE + 0x03C)

     

    #define

     

     

    PINMUX0 *(unsigned int

     

    *)(SYS_BASE + 0x120)

     

    #define

     

     

    PINMUX1 *(unsigned int

     

    *)(SYS_BASE + 0x124)

     

    #define

     

     

    PINMUX2 *(unsigned int

     

    *)(SYS_BASE + 0x128)

     

    #define

     

     

    PINMUX3 *(unsigned int

     

    *)(SYS_BASE + 0x12C)

     

    #define

     

     

    PINMUX4 *(unsigned int

     

    *)(SYS_BASE + 0x130)

     

    #define

     

     

    PINMUX5 *(unsigned int

     

    *)(SYS_BASE + 0x134)

     

    #define

     

     

    PINMUX6 *(unsigned int

     

    *)(SYS_BASE + 0x138)

     

    #define

     

     

    PINMUX7 *(unsigned int

     

    *)(SYS_BASE + 0x13C)

     

    #define

     

     

    PINMUX8 *(unsigned int

     

    *)(SYS_BASE + 0x140)

     

    #define

     

     

    PINMUX9 *(unsigned int

     

    *)(SYS_BASE + 0x144)

     

    #define

     

     

    PINMUX10 *(unsigned int

     

    *)(SYS_BASE + 0x148)

     

    #define

     

     

    PINMUX11 *(unsigned int

     

    *)(SYS_BASE + 0x14C)

     

    #define

     

     

    PINMUX12 *(unsigned int

     

    *)(SYS_BASE + 0x150)

     

    #define

     

     

    PINMUX13 *(unsigned int

     

    *)(SYS_BASE + 0x154)

     

    #define

     

     

    PINMUX14 *(unsigned int

     

    *)(SYS_BASE + 0x158)

     

    #define

     

     

    PINMUX15 *(unsigned int

     

    *)(SYS_BASE + 0x15C)

     

    #define

     

     

    PINMUX16 *(unsigned int

     

    *)(SYS_BASE + 0x160)

     

    #define

     

     

    PINMUX17 *(unsigned int

     

    *)(SYS_BASE + 0x164)

     

    #define

     

     

    PINMUX18 *(unsigned int

     

    *)(SYS_BASE + 0x168)

     

    #define

     

     

    PINMUX19 *(unsigned int

     

    *)(SYS_BASE + 0x16C)

    CSL_GpioRegsOvly m_pGPIORegs ;

    CSL_UppRegsOvly UppRegsOvly;

    // static init struct for uPP driver (use defaults)

    const

     

     

     

     

     

    upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;

     

    // local typedef

     

    typedef

     

     

    enum

     

    LOCAL_mode {

    LOCAL_mode_AB_dlb,

    LOCAL_mode_BA_dlb,

    LOCAL_mode_A_transmit,

    LOCAL_mode_A_receive,

    LOCAL_mode_B_receive

    } LOCAL_mode;

    // configuration macros

    #define

     

     

     

     

     

    upp_line_size (1024)

    #define

     

     

     

     

    upp_line_count (2)

    #define

     

     

     

     

    upp_line_offset (upp_line_size)

     

    #define

     

     

    upp_clock_div 0

     

    //(7)

    #define

     

     

     

     

    upp_demo_mode (LOCAL_mode_AB_dlb)

     

    // global variables

     

    volatile

     

     

    int

     

    upp_interrupt_count = 0;

     

    volatile

     

     

    int

     

    upp_error_count = 0;

    LOCAL_mode upp_mode = upp_demo_mode;

    Uint8 upp_buffer_a[upp_line_size];

     

    // * upp_line_count];

    Uint8 upp_buffer_b[upp_line_size];

     

     

     

    // * upp_line_count];

    // local functions

     

    static

     

     

    int

     

    LOCAL_upp_demo();

     

    static

     

     

    void

     

    LOCAL_upp_config(upp_UserParams *upp_setup);

     

    static

     

     

    void

     

    LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);

     

    static

     

     

    void

     

    LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);

     

    static

     

     

    void

     

    LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);

     

    static

     

     

    void

     

    LOCAL_kick_unlock();

     

    static

     

     

    void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int

     

    LPSC_num);

     

    static

     

     

    void

     

    LOCAL_apply_upp_pinmux();

    Fxn CUppDriver::UppDeviceInit()

    {

     

     

    //return ulnStatus;

     

    TSK_Handle demo_tsk;

     

     

     

     

     

    // system initialization (doesn't rely on GEL)

     

    printf(

     

    "UPP Test start-----------\n"

     

    );

     

     

    // unlock device

    KICK_Unlock();

     

     

     

     

    // turn on uPP LPSC

    PSC1_LPSC_enable(0, 19);

     

     

     

     

    // enable uPP pinmux - enable all uPP pin functions

    Apply_Upp_PINMUX();

     

     

     

     

    // enable HWI7 (tied to ECM block 2; see TCF)

     

    C64_enableIER(1 << 9);

    UppTransferBegin();

     

     

     

    if

     

    (demo_tsk == NULL)

    LOG_printf(&trace,

     

    "TSK_create() failed.\n"

    );

     

    }

     

    // LOCAL_upp_demo is the primary DSP/BIOS TSK function. It is called

    // after main

     

     

    static

     

     

    int

     

    CUppDriver::UppTransferBegin()

    {

    upp_UserParams upp_setup;

    upp_Transfer upp_xfer_a, upp_xfer_b;

    GIO_Handle upph;

     

     

    int

    i, status, target_int_count;

    size_t Psize = 16;

     

     

     

     

     

    // initialize uPP buffers

     

     

     

    for (i = 0; i < sizeof(upp_buffer_a); i++)

     

    //sizeof(upp_buffer_a) / 4

    {

     

     

     

     

    // put data in transmit buffer and clear receive buffer

     

     

     

    if

     

    (upp_mode == LOCAL_mode_BA_dlb)

    {

    ((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555;

    ((Uint32 *)upp_buffer_a)[i] = 0x00000000;

    }

     

     

    else

    {

    ((Uint32 *)upp_buffer_a)[i] = i;

     

     

     

    //0xAAAA5555;

     

    ((Uint32 *)upp_buffer_b)[i] = 0x00000000;

    }

     

     

     

    if

     

    (upp_mode==LOCAL_mode_A_transmit)

    {

     

    ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;

    }

     

     

    if

    (upp_mode==LOCAL_mode_B_receive)

    {

     

    ((Uint32 *)upp_buffer_b)[i] = 0xAAAA;

     

    }

     

    }

    upp_setup.params.A.width = 16;

     

     

    // specify driver parameters

    LOCAL_upp_config(&upp_setup);

     

     

     

     

    // create driver handle

     

    upph = GIO_create(

     

    "/UPP"

     

    , IOM_INOUT, &status, &upp_setup, NULL);

     

     

    if

    (upph == NULL)

    {

    LOG_printf (&trace,

     

    "GIO_create failed"

    );

     

     

    //return -1;

    }

     

     

     

     

    // program transfer(s)

     

    LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b);

     

    LOG_printf (&trace,

     

    "Programming uPP transfers..."

     

    );

     

     

     

    // note: begin read first if in DLB mode

     

     

     

    switch

     

    (upp_mode)

    {

     

     

    case

    LOCAL_mode_AB_dlb:

     

    status = GIO_read(upph, &upp_xfer_b, NULL);

    status |= GIO_write(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_BA_dlb:

    status = GIO_read(upph, &upp_xfer_a, NULL);

    status |= GIO_write(upph, &upp_xfer_b, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_transmit:

    status = GIO_write(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

    case

    LOCAL_mode_A_receive:

    status = GIO_read(upph, &upp_xfer_a, NULL);

     

     

    break

    ;

     

     

     

    case

    LOCAL_mode_B_receive:

    status = GIO_read(upph, &upp_xfer_b, NULL);

     

     

    break

    ;

     

     

    default

    :

     

     

    // unrecognized mode (shouldn't happen)

     

    status = -1;

     

     

    break

     

    ;

    }

     

     

     

     

     

    // catch GIO_submit errors)

     

     

     

    if

     

    (status < 0)

    {

    LOG_printf(&trace,

     

    "Error programming uPP transfers.\n"

    );

    upp_error_count++;

    }

     

     

     

    // wait until transfer(s) complete

     

    target_int_count = (upp_mode == LOCAL_mode_AB_dlb ||

    upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;

     

     

     

    while

     

    (upp_interrupt_count < target_int_count && upp_error_count == 0)

    asm(

     

    " nop"

    );

     

     

     

    // check buffers (loopback modes only)

     

     

     

    if

     

    (target_int_count == 2 && upp_error_count == 0)

     

     

    for (i = 0; i < sizeof

    (upp_buffer_a); i++)

     

     

    if

    (upp_buffer_a[i] != upp_buffer_b[i])

    {

     

     

    // LOG_printf(&trace, "Data mismatch in buffers.\n");

     

    printf(

     

    "Data mismatch in buffers.\n"

     

    );

    upp_error_count++;

    }

     

     

    // report test result

     

     

     

    if

     

    (upp_error_count)

     

    // LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count);

     

    printf(

     

    "uPP transfers completed with %u errors.\n"

     

    , upp_error_count);

     

     

    else

     

     

     

     

    // LOG_printf (&trace, "uPP transfers complete!");

     

    printf(

     

    "uPP transfers complete!\n"

     

    );

     

     

     

     

    return

    0;

    }

     

    static

     

     

    void

     

    LOCAL_upp_config(upp_UserParams *upp_setup)

    {

    start with

     

    default

    settings

    *upp_setup = UPP_USERPARAMS;

    upp_setup->params.B.clock_div = upp_clock_div;

    upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb;

     

    //(upp_CbFxn)Upp_Complete_CB;

     

    upp_setup->params.B.en_enable = TRUE;

    upp_setup->params.B.en_wait = FALSE;

    upp_setup->params.B.en_start = FALSE;

    upp_setup->params.A.clock_div =0;

    upp_setup->params.B.clock_div =0;

    upp_setup->params.A.width = 16;

    upp_setup->params.B.width = 16;

     

     

     

    switch

     

    (upp_mode)

    {

     

     

    case

    LOCAL_mode_AB_dlb:

     

     

    // A-to-B loopback

    upp_setup->params.A.direction = upp_dir_xmit;

    upp_setup->params.B.direction = upp_dir_rcv;

    upp_setup->params.channels = 2;

     

     

     

     

    //upp_setup->params.special_mode = upp_digital_loopback;

     

    UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;

    UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;

     

     

    break

     

    ;

     

     

    case

    LOCAL_mode_BA_dlb:

     

     

    // B-to-A loopback

     

    upp_setup->params.A.direction = upp_dir_rcv;

    upp_setup->params.B.direction = upp_dir_xmit;

    upp_setup->params.channels = 2;

    upp_setup->params.special_mode = upp_digital_loopback;

     

     

    break

     

    ;

     

     

    case

    LOCAL_mode_A_transmit:

     

     

    // Single channel transmit

     

    upp_setup->params.A.direction = upp_dir_xmit;

     

     

    break

     

    ;

     

     

    case

    LOCAL_mode_A_receive:

     

     

    // Single channel receive

     

    upp_setup->params.A.direction = upp_dir_rcv;

     

     

    break

     

    ;

     

     

    case

    LOCAL_mode_B_receive:

     

     

    // Single channel receive

     

    upp_setup->params.B.direction = upp_dir_rcv;

     

     

    break

     

    ;

     

     

    default

    :

     

     

    // unrecognized mode (shouldn't happen)

     

    LOG_printf(&trace,

     

    "Warning: unrecognized uPP mode\n"

     

    );

     

     

    break

    ;

    }

    }

     

     

     

    // LOCAL_upp_config_xfers initializes uPP transfers according to parameters

    // defined in local macros

     

    static

     

     

    void

     

    LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)

    {

     

     

    // start with default settings

    *xfer_a = UPP_TRANSFER;

    *xfer_b = UPP_TRANSFER;

     

     

     

     

    // apply common settings

    xfer_a->windowAddr = upp_buffer_a;

    xfer_a->lineCount = upp_line_count;

    xfer_a->lineSize = upp_line_size;

    xfer_a->lineOffset = upp_line_offset;

    xfer_a->channel = upp_A;

    xfer_b->windowAddr = upp_buffer_b;

    xfer_b->lineCount = upp_line_count;

    xfer_b->lineSize = upp_line_size;

    xfer_b->lineOffset = upp_line_offset;

    xfer_b->channel = upp_B;

     

     

     

     

    // note: upp_xfer_b will only be used in DLB modes

     

    }

     

     

    // LOCAL_upp_complete_cb is a callback function used to track the

    // completion of uPP transfers (i.e. EOW events)

    static

     

     

    void

     

    LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)

    {

     

    // LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit);

     

    printf(

     

    "uPP interrupt: 0x%08X"

     

    , upp_isr_bit);

    upp_interrupt_count++;

     

     

    // note: only uPP HWI is enabled, so increment should be atomic/safe

     

    }

     

     

    // LOCAL_upp_error_cb is a callback function used to track uPP error

    // events (underrun/overflow, internal error, or DMA programming error)

    static

     

     

    void

     

    LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)

    {

    LOG_printf(&trace,

     

    "uPP error: 0x%08X"

    , upp_isr_bit);

    upp_error_count++;

     

     

    // note: only uPP HWI is enabled, so increment should be atomic/safe

     

    }

     

    LOCAL_kick_unlock allows

     

    register

     

    access at run time. Based on code

    taken from GEL file

     

    static

     

     

    void

     

    LOCAL_kick_unlock()

    {

     

     

    // enables register access at run time

    KICK0R = 0x83e70b13;

     

     

     

    // Kick0 register + data (unlock)

    KICK1R = 0x95a4f1e0;

     

     

     

    // Kick1 register + data (unlock)

     

    }

     

     

    // LOCAL_PSC1_LPSC_enable powers on one LPSC. Based on code taken from

    // GEL file

    static

     

     

    void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int

     

    LPSC_num)

    {

    *(

     

    unsigned int

    *) (PSC1_MDCTL + 4 * LPSC_num) =

    (*(

     

    unsigned int

    *) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;

     

    PSC1_PTCMD = 0x1 << PD;

     

     

    // Wait for power state transition to finish

     

     

     

    while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop"

     

    );

     

     

    while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop"

    );

    }

     

     

    // LOCAL_apply_upp_pinmux enables all uPP pin functions. Based on code taken

    // from GEL file

     

    static

     

     

    void

     

    LOCAL_apply_upp_pinmux()

    {

     

     

    // all pins (channel A, channel B, DATA, and XDATA)

    PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000;

    PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400;

    PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444;

    PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444;

    PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444;

    PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444;

    }

     

    //-------------

    // END OF FILE

    //-------------

     

     

  • Veena,

    Could you describe your hardware setup?  Are you trying to run an "external" loopback test (i.e. connecting the channel A and B pins), or are you doing something else?

    One thing I notice in your code is that you are attempting to set some register values manually:

    UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;
    UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;

    This is not necessary since the driver will set these register values automatically.  Generally speaking, any settings you apply before calling GIO_create() will be lost when the driver resets the uPP peripheral.  I recommend checking the uPP registers after calling GIO_create() to make sure the settings you want have actually been applied.

    Also, when sharing an entire source file on the forum, I recommend simply attaching it to your post (using the "options" tab next to "compose" above the text entry box).  The forum doesn't handle big blocks of text very well; it likes to double the line breaks in copy-pasted text.

  • Hi Joe,

    My hardware Setup is as follows:

    UPP communicated with FPGA for transmit and recieve. I use Duplex 1 mode

    in Transmit mode:

    I have not confiured START as ENABLE is enough for transmission. on FPGA I am able to recieve the transmitted data.

    In recieve mode:

    I have disabled ENABLE and START, I have enabled WAIT.

    my concern is that when I get data through FPGA on Data pins interrupt should be generated at every ENABLE high.

    I get some junk data in between the actual data.

    What am I missing?

    Thanks and regards

    Veena

    Uppdriver.cpp
  • Hi Joe,

    This is V important and Urgent. I would appreciate if you cud guide me on this.

    In the above UPP prgram, I get EOl and EOW interrupts only after I do a GIO_Read.

    My expectation is : Once the data is ready I should get interrupt first then I do a GIO_read.

     

    Thanks and regards

    Veena

     

  • Veena,

    With ENABLE and START disabled for receive mode, the uPP peripheral will read incoming data every time the clock line pulses.  If you're getting spurious data, it may indicate that you have some glitch or extra pulse in your clock signal.  Using ENABLE could be helpful for correcting this sort of error.  (With ENABLE, data is only read when the clock pulses and ENABLE is asserted.)

    Also, you should generally call GIO_read before you expect data to arrive.  The sequence of events should be like this:

    1. Call GIO_read on DSP
    2. External device begins transmission
    3. Transmission completes
    4. Receive channel EOW interrupt is generated
    5. For aysnc mode: EOW callback function is run
    6. For synchronous mode: GIO_read returns

    Hope this helps.

  • Hi Joe,

    Thanks a lot for all the inputs it was helpful,

    My UPP driver is working now in terms of transmit and recieve.

    one more concern is that I get external HW interrupt on a GPIO and then the driver begins recieving.

    but I cannot call GIO_read in a HWI.

    Could you throw some light on how to make this driver a non-blocking driver and how to set GIO Manager properties to use non-blocking synchronization methods

    Thanks and regards

    Veena

     

     

  • Hi Joe,

    Thanks a lot for all the support.

    I have one more query.

    I have configured EOL

    I call GIO_Read every 2.5ms but call to EOL gets missed it gets called in 5ms sometimes 2.5 ms

    does it cause some delay?

    rgds

    Veena

     

     

     

  • Veena,

    Do your transfers have more than one line per window?  It is possible for multiple interrupt events to be handled by a single call to the ISR function.  For example, the last line in a transfer will generate an EOL event at almost the same time as the EOW event.  For very small line sizes, you can also have multiple EOL events serviced by a single ISR call.  In this case, one of the EOL events may be "masked" by the other, and your application may only see that a single EOL event occurred.  The best way to avoid this is to increase your buffer and line sizes (or decrease the uPP clock speed) so that interrupts occur less frequently.

    Please let me know if this answers your question.