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.

RTOS/CC2640R2F: ---[BUG] SPI input PIN config patch

Part Number: CC2640R2F
Other Parts Discussed in Thread: DRV8711,

Tool/software: TI-RTOS

simplelink_cc2640r2_sdk_2_30_00_28, in this sdk, the SPI driver function SPICC26XXDMA_initIO, input pins need PIN_PULLUP, so that the electrical leve of the input pins are pulled up from the cc2640r2 soc side and be adapted to the required level for the soc cc2640r2. the following is the patch for SPICC26XXDMA.c.  there's same problem in SPICC26X2DMA.c, both files are found in ~/ti/simplelink_cc2640r2_sdk_2_30_00_28/source/ti/drivers/spi . for better flexibility, all the SPI pins should be controled by the function SPICC26XXDMA_control, with more command like SPICC26XXDMA_CMD_SET_MISO_PIN, SPICC26XXDMA_CMD_SET_MOSI_PIN, SPICC26XXDMA_CMD_SET_CLK_PIN

--- SPICC26XXDMA.c.orig	2018-12-15 14:16:13.473854253 +0800
+++ SPICC26XXDMA.c	2018-12-15 14:20:48.781926275 +0800
@@ -1104,15 +1104,15 @@
     /* Build local list of pins, allocate through PIN driver and map HW ports */
     if (object->mode == SPI_SLAVE) {
       /* Configure IOs for slave mode */
-      spiPinTable[i++] = hwAttrs->mosiPin | PIN_INPUT_EN;
+      spiPinTable[i++] = hwAttrs->mosiPin | PIN_INPUT_EN | PIN_PULLUP;
       spiPinTable[i++] = hwAttrs->misoPin | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MED;
-      spiPinTable[i++] = hwAttrs->clkPin  | PIN_INPUT_EN;
+      spiPinTable[i++] = hwAttrs->clkPin  | PIN_INPUT_EN | PIN_PULLUP;
       spiPinTable[i++] = object->csnPin   | PIN_INPUT_EN | PIN_PULLUP;
     }
     else {
       /* Configure IOs for master mode */
       spiPinTable[i++] = hwAttrs->mosiPin | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MED;
-      spiPinTable[i++] = hwAttrs->misoPin | PIN_INPUT_EN | PIN_PULLDOWN;
+      spiPinTable[i++] = hwAttrs->misoPin | PIN_INPUT_EN | PIN_PULLUP;
 
       /* Output low signal on SCLK until SPI module drives signal if clock polarity is configured to '0' */
       /* Output high signal on SCLK until SPI module drives signal if clock polarity is configured to '1' */

a

 

 

  • You write " input pins need PIN_PULLUP, so that the electrical leve of the input pins are pulled up from the cc2640r2 soc side and be adapted to the required level for the soc cc2640r2" Does that mean the device that is the SPI master uses a different VDD than the CC2640R2? If so, could you elaborate?
  • this problem is revealed by the ti drv8711 boost pack asks for pull up for the SPI master input.
  • I just looked through part of the datasheet for drv8711. Which voltage does the SPI interface operate on? For me it looks like the SPI interface is operating on 1.8 V.

    Normally the SPI interface will have the same power domain on both sides meaning that any form of level shifting is not required and the driver is correct as is since a signal driven either logic high or low do not need a pull-up in addition.

    A safer way to do this is to operate one of the VDDS domains on CC2640R2F on a different voltage, see 6.11 in www.ti.com/.../cc2640r2f.pdf
  • at top of page 4, 2nd row of PIN Functions table, the last column "EXTERNAL COMPONENTS OR CONNECTIONS" for SDATO states "serial data output to controller. open drain output requires external pullup " the same pullup required for all output pins in the same table. if open drain get pulldown, the pin will be kept in low level forever. other devices might use open source as SPI output, so need pulldown. other devices might use pushpull for SPI output, and need no pull. and the output SPI pin of cc2640r2f may need set lower drive strength to save power, or higher drive strength to satisfy device requirement.

    a better way should be set the pin config directly in the spiCC26XXDMAHWAttrs2 using PIN_Config instead of PIN_Id for all 4 SPI pins including the CSN,  and use the  SPICC26XXDMA_Object.PIN_Handle for all 4 SPI pins could be controlled with one handle by SPICC26XXDMA_control command SPICC26XXDMA_CMD_SET_PINS instead of only to control only one CSN pin by SPICC26XXDMA_CMD_SET_CSN_PIN. PIN_Id could be recovered from PIN_Config when needed.

    typedef struct SPICC26XXDMA_HWAttrsV2 {
        /*! SPI Peripheral's base address */
        uint32_t         baseAddr;
        /*! SPI CC26XXDMA Peripheral's interrupt vector */
        uint8_t          intNum;
        /*! @brief SPI CC26XXDMA Peripheral's interrupt priority.
    
            The CC26xx uses three of the priority bits,
            meaning ~0 has the same effect as (7 << 5).
    
            (7 << 5) will apply the lowest priority.
    
            (1 << 5) will apply the highest priority.
    
            Setting the priority to 0 is not supported by this driver.
    
            HWI's with priority 0 ignore the HWI dispatcher to support zero-latency interrupts, thus invalidating the critical sections in this driver.
        */
        uint8_t          intPriority;
        /*! @brief SPI SWI priority.
            The higher the number, the higher the priority.
            The minimum is 0 and the maximum is 15 by default.
            The maximum can be reduced to save RAM by adding or modifying Swi.numPriorities in the kernel configuration file.
        */
        uint32_t         swiPriority;
        /*! SPI Peripheral's power manager ID */
        PowerCC26XX_Resource   powerMngrId;
        /*! Default TX value if txBuf == NULL */
        uint16_t         defaultTxBufValue;
        /*! uDMA controlTable channel index */
        uint32_t         rxChannelBitMask;
        /*! uDMA controlTable channel index */
        uint32_t         txChannelBitMask;
        /*! SPI MOSI pin */
        PIN_Config           mosiPin;
        /*! SPI MISO pin */
        PIN_Config           misoPin;
        /*! SPI CLK pin */
        PIN_Config           clkPin;
        /*! SPI CSN pin */
        PIN_Config           csnPin;
    
    
        /*! Minimum transfer size for DMA based transfer */
        uint32_t minDmaTransferSize;
    } SPICC26XXDMA_HWAttrsV2;
    
    
    #ifdef USE_SPI
    #include <ti/drivers/SPI.h>
    #include <ti/drivers/spi/SPICC26XXDMA.h>
    
    SPICC26XXDMA_Object spiCC26XXDMAObjects[CC2640R2_RSM_SPICOUNT];
    
    const SPICC26XXDMA_HWAttrsV2 spiCC26XXDMAHWAttrs[CC2640R2_RSM_SPICOUNT] = {
        {
            .baseAddr           = SSI0_BASE,
            .intNum             = INT_SSI0_COMB,
            .intPriority        = ~0,
            .swiPriority        = 0,
            .powerMngrId        = PowerCC26XX_PERIPH_SSI0,
            .defaultTxBufValue  = 0,
            .rxChannelBitMask   = 1<<UDMA_CHAN_SSI0_RX,
            .txChannelBitMask   = 1<<UDMA_CHAN_SSI0_TX,
            .mosiPin            = CC2640R2_RSM_SPI0_MOSI | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MED,,
            .misoPin            = CC2640R2_RSM_SPI0_MISO | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN  | PIN_PULLUP,,
            .clkPin             = CC2640R2_RSM_SPI0_CLK | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MED,,
            .csnPin             = CC2640R2_RSM_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_INV_INOUT | PIN_INPUT_DIS  | PIN_DRVSTR_MED,
        }
    };
    
    const SPI_Config SPI_config[CC2640R2_RSM_SPICOUNT] = {
        {
             .fxnTablePtr = &SPICC26XXDMA_fxnTable,
             .object      = &spiCC26XXDMAObjects[CC2640R2_RSM_SPI0],
             .hwAttrs     = &spiCC26XXDMAHWAttrs[CC2640R2_RSM_SPI0]
        }
    };
    
    const uint_least8_t SPI_count = CC2640R2_RSM_SPICOUNT;
    #endif
    

  • Hi Ke,

    Needing pull-ups on SPI is a very rare use-case and the driver is written and tested for SPI operations assuming the typical SPI push-pull convention. Note that you are free to append extra options in the HwAttrs as it is today, you are not limited to only the IO itself, but can "or" in for example PIN_PULLUP if you want.

    Regarding "control", there is no access to the actual pins per design as the user should not change these in run-time. The CSN is a special case, where the you in some cases might want to "remove" the HW controlled CSN and instead use a SW CSN that you control yourself.

    Off-course, as special need arises, you are free to change the driver according to your needs as it is supplied as open-source.

  • as of drv8711 it is a high leve CS signal instead of a low leve CSN that select the device. so the CSN from cc2640r2 need be inverted.
    using sepperate soft CS/CSN, several SPI device with different interface pull mode may share one SPI interface as a bus, and this situation need to change these in run-time.