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.

c5515 - spi interface with cc2500 transceiver

Other Parts Discussed in Thread: TMS320C5515

folks,

I'm trying to change the SPICDR register CLKDV field from 0x31 ( SPI_CLK 2MH ) into 0x18 (SPI_CLK  4MH) in order to change the transmission rate on the SPI bus.

SPIDCR1 registyer DD1 field is set t0 2 -> first SPI_CLK edge is delayed 2.5 SPI clock cycles from SPI_CS1 assertion).

Unfortunately I don't see any change with the SPI bus rate transmission .

what am I missing?

BR

Talmor

  • hi,

     

    Did you check the IO register set correctly by looking at debug window (I/O memory)?

    Regards,

    Hyun

  • I am also experiencing an anomaly when changing SPICDR, which I have carefully explored:

    I am developing with Code Composer Studio version 4 (CCSv4) for a TMS320C5515 which I debug using an ezDSP ‘5515 USB Stick.

    I have incorporated the utility function getSysClk() (listed below at the end) from csl_uart_dma_example.c into my code when calculating the clock divider ratio for the SPI peripheral.  Executing getSysClk(), however, appears to interfere in some strange way with later writes to the SPI Clock Divider Register SPICDR.

    Furthermore, the phenomenon is extremely sensitive to debugger sequences.

    Please see my observations, below.  Any ideas as to why this occurs?

    (I’ve implemented a workaround that uses a global variable for the DSP System Clock Frequency that is to be updated should the PLL ever be reprogrammed.)

    Dan 


     

    I have implemented in my code the recommendations of

    TMS320C5515/14/05/04/VC05/VC04 DSP Serial Peripheral Interface (SPI) User's Guide

    Literature Number: SPRUFO3

    September 2009

     

    2.12 Initialization

    The following initialization procedure describes the basic setup of the SPI module. Please note that the

    exact configuration will depend on the characteristics of the slave device. For specific examples, please

    refer to Section 3.

    1. Ensure the SPI is out reset by setting SPI_RST = 0 in the peripheral reset control register (PRCR).

    See the device-specific data manual for more information on PRCR.

    2. Enable the SPI input clock by setting SPICG to 0 in the peripheral clock gating configuration register

    (PCGCR1). See the device-specific data manual for more information on PCGCR1.

    3. Set CLKEN = 0 to disable SPI_CLK. The CLKEN bit is part of SPICCR.

    4. Set CLKDV in SPICCR to provide the appropriate SPI_CLK frequency. Note that for proper device

    operation, CLKDV must be greater than or equal to 3. Also, note that the clock frequency selected in

    this step applies to all slave devices. If a different frequency is required for each slave, you must

    reprogram the clock register each time you access a different slave.

    5. Set CLKEN = 1 to enable SPI_CLK.

    6. Program the device configuration registers (SPIDCR1 and SPIDCR2) with the required clock phase,

    clock polarity, chip select pin polarity, and data delay settings for each slave.

    7. Program the SPI module to generate an interrupt after a frame of characters has been transferred

    (FIRQ = 1) or after a single character has been transferred (CIRQ = 1), If you want to use interrupts.

    The FIRQ and CIRQ bits are located in SPICMD1.

     

    NOTE:  “Set CLKDV in ***CR” above should read “Set CLKDV in ***DR”

     


     

    My code:

     

    CSL_SPI_REGS->SPICCR          = 0x0000 ;

     

    CSL_SPI_REGS->SPICDR          = ( getSysClk() / 5000000u ) - 1 ;

     

    CSL_SPI_REGS->SPICCR          = 0x8000 ;

     

    Disassembly of my code in CCSv4:

     

    178         CSL_SPI_REGS->SPICCR          = CSL_SPI_SPICCR_RESETVAL ;

    0x03A08E:   e651003001               MOV #0,port(#03001h)

     

    195       CSL_SPI_REGS->SPICDR            = ( getSysClk() / SPI_FREQ_SLOW ) - 1 ;

    0x03A093:   6c03ae33                 CALL getSysClk

    0x03A097:   ec31be4c4b40             AMAR *(#04c4b40h),XAR3

    0x03A09D:   90b1                     MOV XAR3,AC1

    0x03A09F:   6c046b6f                 CALL _divul

    0x03A0A3:   4210                     SUB #1,AC0

    0x03A0A5:   c0513000                 MOV AC0,port(#03000h)

     

    199         CSL_SPI_REGS->SPICCR          = CSL_SPI_SPICCR_CLKEN_MASK ;

    0x03A0A9:   fb5180003001             MOV #-32768,port(#03001h)

     

     


     

    In the following experiments, I observed SPICDR as I/O location 0x3000:

     

    “Run to Line” C-code line 199

          →   SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected, but “MOV AC0,port(#03000h)” has failed! ]

     

    “Run to Line” C-code Line 195

    C-code "Step Over"

          →    SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected, but “MOV AC0,port(#03000h)” has failed! ]

     

    “Run to Line” C-code Line 195

    "Assembly Step Over" "CALL getSysClk",

     then "Run to Line" C-code line 199

          →    SPICDR = 0x13           THIS IS THE DESIRED RESULT

     

     


     

    I also tried adding a wait loop:

     

    Volatile Uint16         iDelayCounter ;

    static Uint32           lngSysClkTemp ;

     

    CSL_SPI_REGS->SPICCR          = 0x0000 ;

     

    lngSysClkTemp = getSysClk() ;

      

    iDelayCounter = 255 ;

    do {

    iDelayCounter-- ;

    } while ( iDelayCounter != 0) ;

     

    CSL_SPI_REGS->SPICDR          = ( lngSysClkTemp / SPI_FREQ_SLOW ) - 1 ;

     

    CSL_SPI_REGS->SPICCR          = 0x8000 ;

     

     

    Disassembly of my code in CCSv4:

     

    178         CSL_SPI_REGS->SPICCR          = CSL_SPI_SPICCR_RESETVAL ;

    0x03A08A:   e651003001               MOV #0,port(#03001h)

     

    180       lngSysClkTemp = getSysClk() ;

    0x03A08F:   6c03ae3f                 CALL getSysClk

    182       iDelayCounter = 255 ;

    0x03A093:   fb0000ff                 MOV #255,*SP(#00h)

     

    184       iDelayCounter-- ;

              C$DW$L$_io_config$2$B, C$L11:

    0x03A097:   f700ffff                 ADD #-1,*SP(#00h)

    0x03A09B:   20                       NOP

    0x03A09C:   20                       NOP

    0x03A09D:   20                       NOP

     

    185       } while ( iDelayCounter != 0) ;

    0x03A09E:   a900                     MOV *SP(#00h),AR1

    0x03A0A0:   0419f4                   BCC C$L11,AR1 != #0

     

    195       CSL_SPI_REGS->SPICDR            = ( lngSysClkTemp / SPI_FREQ_SLOW ) - 1 ;

              C$DW$L$_io_config$2$E:

    0x03A0A3:   ec31be4c4b40             AMAR *(#04c4b40h),XAR3

    0x03A0A9:   90b1                     MOV XAR3,AC1

    0x03A0AB:   6c046b7b                 CALL _divul

    0x03A0AF:   4210                     SUB #1,AC0

    0x03A0B1:   c0513000                 MOV AC0,port(#03000h)

     

    198         CSL_SPI_REGS->SPICCR          = CSL_SPI_SPICCR_CLKEN_MASK ;

    0x03A0B5:   fb5180003001             MOV #-32768,port(#03001h)

     

     

     


     

    “Run to Line” C-code line 198

          →   SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected, but “MOV AC0,port(#03000h)” has failed! ]

     

    “Run to Line” C-code line 195

    C-code "Step Over"

          →   SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected, but “MOV AC0,port(#03000h)” has failed! ]

     

     “Run to Line” C-code Line 180

    C-code "Step Over"

    then "Run to Line" C-code line 195

    then "Assembly Step Over" each machine instruction under 195

          →   SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected,

     but MOV AC0,port(#03000h)” has explicitly failed when single-stepped! ]

     

    At this point, attempting to overwrite I/O location 0x3000 via the debugger also fails!  Something has locked out changes to that register.

     

    “Run to Line” C-code Line 180

    "Assembly Step Over" "CALL getSysClk",

    then "Run to Line" C-code line 195

    then C-code "Step Over" line 195

    or "Run to Line" C-code line 198

    or "Assembly Step Over" each machine instruction under 195

          →   SPICDR is not written (remains 0x0000)

                            [AC0 = 0x13, as expected,

     but MOV AC0,port(#03000h)” has explicitly failed when single-stepped! ]

     

     “Run to Line” C-code Line 180

    "Assembly Step Over" "CALL getSysClk",

     then "Run to Line" C-code line 198

          →    SPICDR = 0x13           THIS IS THE DESIRED RESULT

     


     

    Uint32 getSysClk(void)

    {

       Bool      pllRDBypass;

       Bool      pllOutDiv;

       Uint32    sysClk;

       Uint16    pllVP;

       Uint16    pllVS;

       Uint16    pllRD;

       Uint16    pllVO;

     

       pllVP = CSL_FEXT(CSL_SYSCTRL_REGS→CGCR1, SYS_CGCR1_VP);

       pllVS = CSL_FEXT(CSL_SYSCTRL_REGS→CGCR1, SYS_CGCR1_VS);

     

       pllRD = CSL_FEXT(CSL_SYSCTRL_REGS→CGICR, SYS_CGICR_RDRATIO);

      

       pllVO = CSL_FEXT(CSL_SYSCTRL_REGS→CGOCR, SYS_CGOCR_OD);

     

       pllRDBypass = CSL_FEXT(CSL_SYSCTRL_REGS→CGICR, SYS_CGICR_RDBYPASS);

      

       pllOutDiv   = CSL_FEXT(CSL_SYSCTRL_REGS→CGOCR, SYS_CGOCR_OUTDIVEN);

     

       if (pllRDBypass)

       {

          sysClk = FREQ_RTCX;

       }

       else

       {

          sysClk = FREQ_CLKIN /(pllRD + 4);

       }

     

       sysClk = (sysClk * ((pllVP << 2) + pllVS + 4));

     

       if (1 == pllOutDiv)

       {

          sysClk = sysClk/(pllVO + 1);

       }

     

       return(sysClk);

    }

     

     

  • Any luck on this?  I am having the same problem.

  • I don't know if this will help but I got my 5535 working by doing the following

    SPI_CCR &= ~CLKEN;

    SPI_CCR &= ~RST;   //This step was not in the directions, it must be done

    SPI_CDR = 0x0025;

    SPI_CCR = CLKEN;  //This must not be a read, modify, write.  It has to be a write only.  

    When I do the steps above my divider stays set and using only write the clock stays enabled.