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.

CC2533: CC253X SPI Master USART0 Alt. 2

Part Number: CC2533
Other Parts Discussed in Thread: CC2541, , CC2543

Hi guys,

I'm using a CC2533F96 to communicate (SPI master) with an external flash (SPI slave). When I use USART1 Alt. 2 (MISO P1.7 MOSI P1.6 SCLK P1.5), I'm able to get the manufacturer/device information from the slave (observed by debugging in IAR as well as using the Saleae logic analyzer).

However, when I use USART0 Alt. 2 (MOSI P1.5 MISO P1.4 SCLK P1.3), there is no clock generation neither outputed signal on MOSI pin .

For both implementations, I'm using SS P1.2 as GPIO output with the same configuration.

Here the code for both solutions:

// UART1 Alt. 2 in SPI mode
/* Mode select UART1 SPI Mode as master. */
U1CSR = 0; 

/* Setup for 250kHz baud. */
U1GCR = 13; 
U1BAUD = 0;  

/* Set bit order to MSB */
U1GCR |= BV(5); 

/* Set UART1 I/O to alternate 2 location on P1 pins. */
PERCFG |= 0x02;  /* U1CFG */

/* Select peripheral function on I/O pins but SS is left as GPIO for separate control. */
P1SEL |= 0xE0;  /* SELP1_[7:4] */

/* Give UART1 priority over Timer3. */
P2SEL &= ~0x20;  /* PRI2P1 */

/* When SPI config is complete, enable it. */
U1CSR |= 0x40;

and

// UART0 Alt. 2 in SPI mode.
/* Mode select UART0 SPI Mode as master. */
U0CSR = 0; 

/* Setup for 250kHz baud. */
U0GCR = 13; 
U0BAUD = 0;  

/* Set bit order to MSB */
U0GCR |= BV(5); 

/* Set UART0 I/O to alternate 2 location on P1 pins. */
PERCFG |= 0x01;  /* U0CFG */

/* Select peripheral function on I/O pins but SS is left as GPIO for separate control. */
P1SEL |= 0x38; 

/* Give UART0 priority */
P2DIR &= ~0xC0;  /* PRIP0 */
P2SEL &= ~0x40;  /* PRI3P1 */
P2SEL &= ~0x08;  /* PRI0P1 */

/* When SPI config is complete, enable it. */
U0CSR |= 0x40; 

There is no other peripheral connected to the microcontroller.

It is a custom board where the pins can be switched in order to route the signals in the desired way. All pins have been tested and there is no electrical problem.

What could be wrong?

  • Hello,

    We are looking into this.

    We Will get back to you as soon as we get an answer.

    Thank you for your patience,
    AB
  • Hi,
    Just a remark while this is being looked into: "For both implementations, I'm using SS P1.2 as GPIO output with the same configuration."

    According to the users guide, USART 1 SPI (Alt2) actually uses P1.4 for SS.
  • In fact the Slave Select pin can be any GPIO pin.

    For example, the USART1 SPI (Alt2) solution is working correctly using SS = P2.0.
  • Hi,
    You can use the spi example here to modify the code as per your settings.
    www.ti.com/.../getliterature.tsp
    Use the SPI master example and change it to function in UART0 ALT2 mode. The settings for CC254x and CC253x should be the same.
    Regards,
  • Thanks for the code examples.

    Unfortunately, regarding the UART SPI mode, there is no example for UART0 Alternative 2 (but only for Alternative 1).

  • Something here does not make sense ...

    CC253x/4x User's Guide (Rev. F):

    USART0 SPI Alt.2:

    MOSI P1.5

    MISO P1.4

    SCLK P1.3

    SS P1.2

    CC254x Basic Software Examples Overview (swrc257.zip):

    CC2543EM R1.1 Schematics (swrr098.zip):

    CC2541_43_44_45_Peripherals_Software_Examples (swrc257.zip):

    #if (chip==2541 || chip==2543 || chip==2545)
        // Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0).
        PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U0CFG_ALT1;    
    #endif
    
    #if (chip==2541 || chip==2543 || chip==2545)
        // Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output.
        P0SEL = (P0SEL & ~BIT4) | BIT5 | BIT3 | BIT2;
        P0DIR |= BIT4;

    Can you clarify what is right and what is wrong?

    The peripherals examples document is not in accordance with Table 7.1 from User's Guide. And the sample code does not conform to the documentation itself.

    Just out of curiosity, it seems that someone has had the same problem previously (unable to solve).

    https://e2e.ti.com/support/wireless_connectivity/bluetooth_low_energy/f/538/t/266605?CC2540-UART0-SPI-alternative-2-location

  • Hi ,
    You can configure the mode as follows:

    // Configure USART0 for Alternative 2=> Port P0 (PERCFG.U0CFG = 0).
    PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U0CFG_ALT2;

    // Give priority to USART 0 over Timer 1 for port 0 pins.
    PPRI &= ~PPRI_PRI0P1;
    // Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output.
    P1SEL = (P1SEL & ~BIT2) | BIT5 | BIT3 | BIT4;
    P1DIR |= BIT2;

    The rest of the code should work fine.
    I have just verified on an EM board.
    Let me know if you get into issues.
    Regards,
  • First of all, PERCFG_U0CFG, PERCFG_U0CFG_ALT2, PPRI and PPRI_PRI0P1 settings exist for the chip of the example (CC2543) but those registers do not exist for the chip in question (CC2533). We can compare the files ioCC2533.h and ioCC2543.h.

    In addition, the suggested settings are exactly the same as those shown by me at the beginning of the topic.

    When you say you tested successfully with the EM board, did you use CC2533 chip with USART 0 SPI Alt.2 configuration?

    As I told before, there is no clock generation neither outputted signal on MOSI pin.

  • CC2530_spi_master_send.c
    /***********************************************************************************
      Filename:     spi_master_send.c
    
      Description:  This example uses a master to send data to a slave using SPI.
    
    
    
    ***********************************************************************************/
    
    /***********************************************************************************
    * INCLUDES
    */
    #include <hal_types.h>
    // Include Name definitions of individual bits and bit-fields in the CC254x device registers.
    #include <ioCC254x_bitdef.h>
    #include "ioCC2533.h"
    
    #define PERCFG_U1CFG                  0x02               // USART 1 I/O location
    #define PERCFG_U0CFG                  0x01               // USART 0 I/O location
    #define PERCFG_U0CFG_ALT1                 0x00          // Alternative 1 location
    #define PERCFG_U0CFG_ALT2                 0x01          // Alternative 2 location
    #define PPRI_PRI0P1                       0x04
    /***********************************************************************************
    * CONSTANTS
    */
    
    // These values will give a baud rate of approx. 2.00 Mbps at 32 MHz system clock
    #define SPI_BAUD_M  0
    #define SPI_BAUD_E  16
    
    // Define size of buffer and number of bytes to send
    #define BUFFER_SIZE 252
    
    /***********************************************************************************
    * LOCAL VARIABLES
    */
    
    // Masters's transmit buffer
    static uint8 txBufferMaster[BUFFER_SIZE];
    
    /***********************************************************************************
    * LOCAL FUNCTIONS
    */
    
    
    /***********************************************************************************
    * @fn          main
    *
    * @brief       Send data to a single slave using SPI in Master mode
    *
    * @param       void
    *
    * @return      void
    */
    void main(void)
    {
        /****************************************************************************
         * Clock setup
         * See basic software example "clk_xosc_cc254x"
         */
        
        // Set system clock source to HS XOSC, with no pre-scaling.
        CLKCONCMD = (CLKCONCMD & ~(CLKCON_OSC | CLKCON_CLKSPD)) | CLKCON_CLKSPD_32M;
        while (CLKCONSTA & CLKCON_OSC);   // Wait until clock source has changed
        
        // Note the 32 kHz RCOSC starts calibrating, if not disabled.
    
    
        /***************************************************************************
         * Setup I/O ports
         *
         * Port and pins used by USART0-ALT2 operating in SPI-mode are
         * MISO (MI): P1_4
         * MOSI (MO): P1_5
         * SSN (SS) : P1_2
         * SCK (C)  : P1_3
         */
        
        // Configure USART0 for Alternative 2 => Port P1 (PERCFG.U0CFG = 1).
        PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U0CFG_ALT2;          
    
        // Set USART 0 proiotrity to 1st.
        P2DIR &= ~0xC0;
        // Set pins 3, 4 and 5 as peripheral I/O and pin 2 as GPIO output.
        P1SEL = (P1SEL & ~BIT2) | BIT5 | BIT3 | BIT4;
        P1DIR |= BIT2;
        
        
        /***************************************************************************
         * Configure SPI
         */
    
        // Fill array with bytes to send.
        uint8 value = 0x00;
        int i;
        for (i = 0; i < BUFFER_SIZE; i++)
        {
            txBufferMaster[i] = value++;
        }
    
        // Set USART to SPI mode and Master mode.
        U0CSR &= ~(U0CSR_MODE | U0CSR_SLAVE);
    
        // Set:
        // - mantissa value
        // - exponent value
        // - clock phase to be centered on first edge of SCK period
        // - negative clock polarity (SCK low when idle)
        // - bit order for transfers to LSB first
        U0BAUD = SPI_BAUD_M;
        U0GCR = (U0GCR & ~(U0GCR_BAUD_E | U0GCR_CPOL | U0GCR_CPHA | U0GCR_ORDER))
            | SPI_BAUD_E;
    
        /***************************************************************************
         * Transfer data
         */
    
        
    
        P1_2 = 0;
        for (i = 0; i < BUFFER_SIZE; i++)
        {
            // Write byte to USART0 buffer (transmit data).
            U0DBUF = txBufferMaster[i];
    
            // Check if byte is transmitted.
            while(!(U0CSR & U0CSR_TX_BYTE));
    
            // Clear transmit byte status.
            U0CSR &= ~U0CSR_TX_BYTE;
        }
    
        // Set SSN, the SPI slave is inactive when SSN is high.
        P1_2 = 1;
    
       
        // end function with infinite loop (for debugging purposes). 
    while(1){}
    }
    
    
    /***********************************************************************************
      Copyright 2012 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    ***********************************************************************************/
    
    
     Hi,

    Please find attached .c file for the SPI setup in ALT2 mode on USART0.

    I have kept the bit definition file for CC254x for convenience but the header file is that for CC2533.

    You should be able to build the code in the example project. The associated result showing CLK and MOSI is also attached.

    Regards,

  • Thank you very much for your support.

    In fact, my settings were already correct. Turns out I forgot to change the following defines:

    #define SPI_TX(x)               st(U1CSR &= ~0x02; U1DBUF = (x);)
    #define SPI_WAIT_TX_DONE()      st(while (!(U1CSR & BYTE_TX));)
    #define SPI_RX()                U1DBUF

    Now I can switch between USARTs:

    #ifdef SPI_UART1_ALT2
    #define SPI_TX(x)               st(U1CSR &= ~0x02; U1DBUF = (x);)
    #define SPI_WAIT_TX_DONE()      st(while (!(U1CSR & BYTE_TX));)
    #define SPI_RX()                U1DBUF
    #elif (defined SPI_UART0_ALT2)
    #define SPI_TX(x)               st(U0CSR &= ~0x02; U0DBUF = (x);)
    #define SPI_WAIT_TX_DONE()      st(while (!(U0CSR & BYTE_TX));)
    #define SPI_RX()                U0DBUF
    #endif

    Communication is already working correctly with both sets of pins (USART0 Alt2 or USART1 Alt2).