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.

28335 controlCARD: troubleshooting help needed

Something is strange with my DSP's clock. I think it should be running at 100MHz but it vaguely seems like it's running at 50MHz instead. Here's what I know so far:

1) I am using the 28335 controlCARD with a 20MHz crystal.

2) I am using the DSP2833x_*.[c,h] files including DSP2833x_SysCtrl.c

(// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
// $Release Date: August 4, 2009 $)

with InitSysCtrl() with DSP28_DIVSEL = 2, DSP28_PLLCR = 10 (so SYSCLKOUT should be 20MHz * 10 / 2 = 100MHz).

I have verified using the debugger that SysCtrlRegs.PLLSTS.all = 257 (in particular the PLLSTS.DIVSEL = 2) and SysCtrlRegs.PLLCR = 10.

3) I have a program that seems like it is running about half the speed I expect. I got suspicious and added these lines to toggle the GPIO25 pin:

    GpioDataRegs.GPACLEAR.all = GPIO25MASK;
    GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
    GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
    GpioDataRegs.GPATOGGLE.all = GPIO25MASK;

which compile to

    MOV        @PH,#0x0200
    MOV        @PL,#0
    MOVW       DP,#0x01BF
    MOVL       @4,P
    MOVL       @6,P
    MOVL       @6,P
    MOVL       @6,P

which *should* take 1 cycle per MOVL instruction. But when I look at the GPIO25 pin on an oscilloscope, it is showing up as toggle steps with 20ns duration. (e.g. 20ns low, 20ns high, and 20ns low).

Something doesn't make sense. Either the CPU clock is running at 50MHz instead of 100MHz, or the instruction set manual is wrong about MOVL [loc16], P taking only 1 cycle.

Any suggestions what to look at next?

  • Hmm. The clock appears to be correct at 100MHz but it looks like there are wait states being added by the CPU pipeline somewhere.

    I have changed the code to this:

    GpioDataRegs.GPACLEAR.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        asm("   NOP");
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        asm("   NOP");
        asm("   NOP");
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        asm("   NOP");
        asm("   NOP");
        asm("   NOP");
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;

    The first 3 GPATOGGLEs have no delay, and they take 20ns (verified on an oscilloscope).

    The 4th GPATOGGLE is preceded by a NOP, but it also takes 20ns.

    The 5th GPATOGGLE is preceded by 2 NOPs, and it takes 30ns.

    The 6th GPATOGGLE is preceded by 3 NOPs, and it takes 40ns.

    What controls the wait states? (I am executing this code from RAM for debugging purposes)

  • Jason R Sachs said:

        GpioDataRegs.GPACLEAR.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;
        GpioDataRegs.GPATOGGLE.all = GPIO25MASK;

    which compile to

        MOV        @PH,#0x0200
        MOV        @PL,#0
        MOVW       DP,#0x01BF
        MOVL       @4,P
        MOVL       @6,P
        MOVL       @6,P
        MOVL       @6,P

    Jason,

    Back-to-back writes to this peripheral frame will incur a extra cycle.  A single write is 1 cycle.

    Regards,

    -Lori

     

  • Lori Heustess said:

    Back-to-back writes to this peripheral frame will incur a extra cycle.  A single write is 1 cycle.

    Hmm. Where is this documented? I'm confused. GpioDataRegs.GPATOGGLE is at 0x6FC6 which according to SPRS439F, p. 35, is in Peripheral Frame 1, and according to Table 3-5 (Wait-states) on p. 40, this has 0 wait for writes and 2 wait for reads. It says consecutive writes to CAN will experience a 1-cycle pipeline hit, but doesn't say anything about GPIO having 1-cycle hits for consecutive writes.

     

  • Jason R Sachs said:
    Hmm. Where is this documented? I'm confused. GpioDataRegs.GPATOGGLE is at 0x6FC6 which according to SPRS439F, p. 35, is in Peripheral Frame 1, and according to Table 3-5 (Wait-states) on p. 40, this has 0 wait for writes and 2 wait for reads. It says consecutive writes to CAN will experience a 1-cycle pipeline hit, but doesn't say anything about GPIO having 1-cycle hits for consecutive writes.

    Jason,

    Yes, unfortunately this was something we missed in the documentation and late last year we started updating data manuals with this info.  It looks like it has made it into the 280x data manual but not the 2833x yet. 

    My apologies for any confusion or frustration this has presented.    I am checking on the status of the update to the 2833x datasheet.

    -Lori

  • Lori Heustess said:
    I am checking on the status of the update to the 2833x datasheet.

    Jason,

    Looks like the update will likely occur within the week.  The new table will look like this:

    -Lori

  • OK, thanks. Could you post the whole table?

    (by the way, there is a slight bug in the existing SPRS439F Table 3-5; the L4-L7 SARAM lines show up as separate items. At first glance it looks like L4 = 0-wait data(read), L5 is 0-wait data(write), L6 is 1-wait program(read), and L7 is 1-wait program (write). There should be no horizontal separator lines in this group except in the leftmost column.)

  • Jason,

    Here it is:

  • Hi,

    I've been looking into similar timing issues with the F280x.  Tim Love pointed me to this thread and suggested that I post here.

    I can confirm that there is an additional cycle for back to back peripheral writes on the F2808.  However, I'm also seeing a discrepancy with respect to reads that follow writes.  Is there an update to the Write Followed By Read Protection Mode as well?  My experience is that peripheral reads that follow peripheral writes take 7 cycles. It looks like the pipe protection is actually 4 cycles instead of 3. The following two code fragments execute in the same number of cycles.


    mov @peripheral,al ; 1 cycle
    mov al,@peripheral ; 7 cycles


    mov @peripheral,al ; 1 cycle
    nop
    nop
    nop
    nop
    mov al,@peripheral ; 3 cycles

    galen

  • Galen Seitz said:

    I can confirm that there is an additional cycle for back to back peripheral writes on the F2808.  However, I'm also seeing a discrepancy with respect to reads that follow writes.  Is there an update to the Write Followed By Read Protection Mode as well?  My experience is that peripheral reads that follow peripheral writes take 7 cycles. It looks like the pipe protection is actually 4 cycles instead of 3. The following two code fragments execute in the same number of cycles.


    mov @peripheral,al ; 1 cycle
    mov al,@peripheral ; 7 cycles


    mov @peripheral,al ; 1 cycle
    nop
    nop
    nop
    nop
    mov al,@peripheral ; 3 cycles

    Galen,

    Recall the C28x pipeline looks like this:

    D2  R1  R2  EXE    W

    Notice the Read phase is before the write.  For any write followed by read to the same memory location, the pipeline will stall the read until the write has completed. 

    In addition peripheral frame 0 and 1 are protected by a write followed by read protection to any location within the frame. 

    In your case It means that the first instruction (write) must complete before the 2nd instruction (read) will continue (It will be stalled in the R2 phase of the pipeline until the write completes).  On top of that the read itself takes 3 cycles.  

    The last read in your code does not get stalled because it is proceeded by NOP's.

    Regards

    Lori

     

  • Lori Heustess said:

     

    Galen,

    Recall the C28x pipeline looks like this:

    D2  R1  R2  EXE    W

    Notice the Read phase is before the write.  For any write followed by read to the same memory location, the pipeline will stall the read until the write has completed. 

    In addition peripheral frame 0 and 1 are protected by a write followed by read protection to any location within the frame. 

    In your case It means that the first instruction (write) must complete before the 2nd instruction (read) will continue (It will be stalled in the R2 phase of the pipeline until the write completes).  On top of that the read itself takes 3 cycles.  

    The last read in your code does not get stalled because it is proceeded by NOP's.

    Regards

    Lori

    I'm familiar with the pipeline.  The documentation for Write Followed By Read Protection Mode indicates that the pipe protection is 3 cycles long.  See page 123 of spru430e.  My example seems to indicate that the pipe protection is in fact 4 cycles, not 3.

    galen