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.

TMDSECATCNCD379D: SPI peripheral interface data transmit and receive error

Part Number: TMDSECATCNCD379D
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

Hello Dear TI Team:

I am using the following example for the SPI peripheral interface.

C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2837xd\examples\cpu1\spi_loopback

I am not using the SPI 'loopback' state in this example. That's why I turned off the 'loopback' (SpiaRegs.SPICCR.bit.SPILBK = 0).

I cannot transmit and receive data using GPIOs (GPIO16-19) .

Sinan,

Thanks and best regards.

  • Hi Sinan,

    Let me try reproducing the issue. Have you checked the external loopback examples available in driverlib?

  • Hi, Veena:

    I'm waiting for you to try reproduce the issue.

    Let me try reproducing the issue.

    As far as I understand, there are two different spi_loopback examples in C2000ware.

    C:\ti\c2000\C2000Ware_3_04_00_00\driverlib\f2837xd\examples\cpu1\spi\spi_ex1_loopback

    C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2837xd\examples\cpu1\spi_loopback

    What is the difference between the external loopback example in driverlib and the example in device_support? Are example from driverlib better than example from device_support?

    Sinan,
    Thanks and best regards.

  • Hi Sinan,

    The examples in device_support folder uses bitfield structs to configure the peripheral. This way to peripheral configuration was being used in our prior SDKs. In C2000ware, we have added driverlib which provides low level APIs which can be used to configure the peripheral rather than user directly writing the individual register values. This provides a level of abstraction, improves code readability and compatibility across devices, it is also beginner friendly as user need not know the register level details to configure a peripheral.

    For more details : https://software-dl.ti.com/C2000/docs/software_guide/c2000ware/drivers.html

    We also have Sysconfig support for Dirverlib, which is GUI for peripheral configuration. Most of our new examples development are driverlib based.

    Regards,

    Veena

  • Hi Sinan,

    I tried running the spi_loopback example on a Launchapd and I was able to see the output on the SPI lines.

    I tried the example as-is and with LBK disabled. Both cases, I could observe the data on the GPIOs.

    Regards,

    Veena

  • Hi, Veena:

    Me too I saw the GPIO outputs in the spi_loopback example below.

    C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2837xd\examples\cpu1\spi_loopback

    However, in the SPI instance in both driverlib and device_support I could not get data from the GPIO.

    DSP is slave, STM32 ARM processor is master. STM32 ARM processor gives from GPIO data output with SPI. Likewise, DSP sends data via SPI from GPIO.

    However, when I connect STM32 to DSP with SPI, I cannot see data in DSP.

    What do you think could be the reason for this?

    Sinan,
    Thanks and best regards.

  • Hi Sinan,

    Can you explain what you meant by "I saw the GPIO outputs" and  "I could not get data from the GPIO"

    What I meant was, I used an external logic analyzer and was able to observe the data on the pins.

    Are you able to observe the data and clock coming out of STM device? Since C2000 device acts as a slave, it requires the master to provide the CLK to send out the data.

    Regards,

    Veena

  • Hi, Veena:

    Can you explain what you meant by "I saw the GPIO outputs" and  "I could not get data from the GPIO"

    I used an external logic analyzer and was able to observe the data on the pins. 

    Also, I observing the data and CLK from the STM device.

    Sinan.

  • Hi Sinan,

    Do you mean, you are observing the data from STM device on the pins, C2000 SPI is configured as slave mode, but data is not seen on the C28x SPI RX register?

     Are you using the slave configuration code from the external loopback example? Do you mind sharing the code?

    Regards,

    Veena

  • Hi, Veena:

    Do you mean, you are observing the data from STM device on the pins, C2000 SPI is configured as slave mode, but data is not seen on the C28x SPI RX register?

    Yes.

    I am sharing the codes that I have tried.

    The drivelib example I'm using:

    /cfs-file/__key/communityserver-discussions-components-files/171/spi_5F00_ex1_5F00_loopback.rar

    The device_support example I'm using:

    /cfs-file/__key/communityserver-discussions-components-files/171/0535.Example_5F00_2837xDSpi_5F00_FFDLB.c

    /cfs-file/__key/communityserver-discussions-components-files/171/4048.F2837xD_5F00_Spi.c

    Sinan,

    Thanks and best regards.

  • Hi Sinan,

    Is the application getting stuck at while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }?

    Regards,

    Veena

  • Hi, Veena:

    Yes. The application is stucking at while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } line.

    Regards,

    Sinan.

  • Hi Sinan,

    Have you configured STE pin? Is STM device driving that low?

    Regards,

    Veena

  • Hi, Veena:

    I configured the STE pin. STM device is'not driving that low.

    Sinan.

  • Hi SInan,

    The STE pin should be driven low for the SPI slave to receive the data.

    Regards,

    Veena

  • Hi, Veena:

    I set the STE pin to low. I saw the STE pin as low on the oscilloscope. But the DSP could not receive data from the slave device.

    Regards,

    Sinan.

  • Hi, Veena:

    Is the application getting stuck at while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }?

    The application is While(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } line does not get stuck when the STE (CS) pin between devices is not connected. The application is stucking at while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } line when the STE (CS) pin between devices is connected.

    My SPI main code for the STM32F7 device is as follows:

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>© Copyright (c) 2021 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under Ultimate Liberty license
      * SLA0044, the "License"; You may not use this file except in compliance with
      * the License. You may obtain a copy of the License at:
      *                             www.st.com/SLA0044
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "lwip.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "udpServerRAW.h"
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    SPI_HandleTypeDef hspi2;
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_SPI2_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    struct netif gnetif;
    
    extern char buf;
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    uint8_t rdata[2];
    
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* Enable I-Cache---------------------------------------------------------*/
      SCB_EnableICache();
    
      /* Enable D-Cache---------------------------------------------------------*/
      SCB_EnableDCache();
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_LWIP_Init();
      MX_SPI2_Init();
      /* USER CODE BEGIN 2 */
      udpServer_init ();
    
      uint8_t sdata[2];
    
      sdata[0] = 0xAB;
      sdata[1] = 0xEF;
    
      //HAL_SPI_Transmit(&hspi2, &deger, 1, 100);
    
      //uint8_t deger = 0xFA;
      /* USER CODE END 2 */
    
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    
    	//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
    	HAL_SPI_Transmit(&hspi2, sdata, 2, 100);
    	HAL_SPI_Receive(&hspi2, rdata, 2, 100);
    	//HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
    	//HAL_Delay(100);
    
    	ethernetif_input(&gnetif);
    	sys_check_timeouts();
    
    
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
      /** Configure the main internal regulator output voltage
      */
      __HAL_RCC_PWR_CLK_ENABLE();
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLM = 25;
      RCC_OscInitStruct.PLL.PLLN = 432;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
      RCC_OscInitStruct.PLL.PLLQ = 9;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** Activate the Over-Drive mode
      */
      if (HAL_PWREx_EnableOverDrive() != HAL_OK)
      {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /**
      * @brief SPI2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_SPI2_Init(void)
    {
    
      /* USER CODE BEGIN SPI2_Init 0 */
    
      /* USER CODE END SPI2_Init 0 */
    
      /* USER CODE BEGIN SPI2_Init 1 */
    
      /* USER CODE END SPI2_Init 1 */
      /* SPI2 parameter configuration*/
      hspi2.Instance = SPI2;
      hspi2.Init.Mode = SPI_MODE_MASTER;
      hspi2.Init.Direction = SPI_DIRECTION_2LINES;
      hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
      hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
      hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi2.Init.CRCPolynomial = 7;
      hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
      hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
      if (HAL_SPI_Init(&hspi2) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN SPI2_Init 2 */
    
      /* USER CODE END SPI2_Init 2 */
    
    }
    
    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */
    static void MX_GPIO_Init(void)
    {
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOG_CLK_ENABLE();
      __HAL_RCC_GPIOI_CLK_ENABLE();
      __HAL_RCC_GPIOH_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  Period elapsed callback in non blocking mode
      * @note   This function is called  when TIM14 interrupt took place, inside
      * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
      * a global variable "uwTick" used as application time base.
      * @param  htim : TIM handle
      * @retval None
      */
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
      /* USER CODE BEGIN Callback 0 */
    
      /* USER CODE END Callback 0 */
      if (htim->Instance == TIM14) {
        HAL_IncTick();
      }
      /* USER CODE BEGIN Callback 1 */
    
      /* USER CODE END Callback 1 */
    }
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      __disable_irq();
      while (1)
      {
      }
      /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    

    Also, the TM320F2879D slave device is not sending data to the STM32F7 master device.

    Regards,

    Sinan.

  • Hi Sinan,

    Also check the polarity and phase configuration. The definition might vary for different manufacturers. Please check the waveforms on the scopr and confirm that the phase and polarity of the data sent by STM is matching with what is configured in TM320F2879D device.

    You can check SPI Clocking Schemes section in TRM for more details.

    Regards,

    Veena

  • Hi, Veena:

    I checked the polarity and phase configuration. There is no problem with these settings.

    I am able to send data from STM32F master device to my TI slave device. I changed the STE (CS) pin of the STM32F master device and the problem was solved.

    TI slave device is not sending data to STM32F master device. I don't see any output signal on SPI GPIO pins when TI device is in slave mode. I can get output signals from SPI GPIO pins when my TI is in master mode.

    Why won't my TI send data when in slave mode?

    Thanks,

    Sinan.

  • Hi Sinan,

    The slave device cannot initiate a data transfer. Once you write to the TX buffer, it will remain in the buffer till the master device initiates a transfer. You can make the master device send some dummy data to receive data from slave device.

    Regards,

    Veena

  • Hi, Veena:

    Can't I send data from TI Slave device to master STM32F device?

    I didn't fully understand this.

    You can make the master device send some dummy data to receive data from slave device.

    Thanks,

    Sinan.

  • Hi Sinan,

    As per the SPI protocol, the data is shifted out on the SPI lines based on SPICLK and the SPICLK is generated by the master device only. Both devices send and receive data at the same time. In case master requires the slave to send a data but master doesn't wish to send any new data, it can initiate a dummy data transfer. Eg: Write 0 to master TX, so that the the SPICLK is generated and slave can shift out the data to be sent. 

    Please refer to the SPI Operation chapter in TRM for more information

    Regards,

    Veena

  • Hi, Veena:

    I wrote 0 to the master TX, but the master device could not receive the data sent by the TI slave device. I also checked the SPI section in TRM.

    Sinan.

  • Hi, Veena:

    The TI device does not operate as a slave. Could the TI device have a Silicon Errata condition?

    The spi instance in drivelib didn't run as a slave either. (Failed to send data to STM32F master device.)

    Thanks,

    Sinan.

  • Hi Sinan,

    We do have an example in C2000ware (external loopback example) which configures one SPI instance as master and another as slave, which is running as expected. Can you share the code snippet where the slave is sending and receiving data?

    Regards,

    Veena

  • Hi, Veena:

    Can you share the code snippet where the slave is sending and receiving data?

    The drivelib example I'm using:

    /cfs-file/__key/communityserver-discussions-components-files/171/0435.spi_5F00_ex1_5F00_loopback.rar

    Thanks,

    Sinan.

  • Hi, Veena:

    Were you able to examine the snippet of code I shared with you? Is there any progress in solving this problem?

    I wrote 0 to the master TX, but the master device could not receive the data sent by the TI slave device. I also checked the SPI section in TRM.

    Thanks and best regards,
    Sinan.

  • Hi Sinan,

    I dont see any issues with the shared code. After writeData and before readData can you check the TXBUF register and the SPISTS.BUFFULL_FLAG. The TXBUF should contain the data to be sent and BUFFLL_FLAG should be 1.

    Regards,

    Veena

  • Hi, Veena:

    After writeData and before readData can you check the TXBUF register and the SPISTS.BUFFULL_FLAG.

    The TXBUF contains data to send but BUFFULL_FLAG is not 1.

    Sinan,

    Thanks and best regards.

  • Hi Sinan,

    Just to make sure there are no hardware issues, can you try running the example from C2000ware? spi_ex3_external_loopback -> This configures one instance as master and another as slave. Both are sending data in this example. This is currently not present in F2837x, but you can reuse it from F2838x examples folder. The SPI module remains the same in both these devices.

    Regards,

    Veena

  • Hi, Veena:

    I ran the example below from C2000Ware.

    C:\C2000Ware_3_04_00_00\driverlib\f2837xd\examples\cpu1\spi\spi_ex3_external_loopback_fifo_interrupts

    The SPI A slave is receiving data from the STM32F master device. However, it does not receive the data in the order that the master device sent it.

    In this example again, SPI A slave is not sending data to STM32F master device.

    Also in this example there are two SPI configurations. The SPI B is a master and SPI A is a slave. I want to use a single SPI line as master-slave mode.

    spi_ex3_external_loopback

    Can you verify the spi example I used?

    Sinan,

    Very thanks.

  • In the spi_ex3_external_loopback_fifo_interrupts in F2837x, only the master instance is sending the data. Hence I asked to check the spi_ex3_external_loopback in F2838x which has both instances sending data from one to another. 

    Can you confirm that the data length configured in both the devices are matching?

    Regards,

    Veena

  • Hi, Veena:

    Can you confirm that the data length configured in both the devices are matching?

    The configured data length on both devices matches.

    Sinan.

  • Hi Sinan,

    It would help if you can capture the SPI lines on a logic analyzer/oscilloscope to further see what the issue is.

    Also, if it possible for you to check the spi_ex3_external_loopback from F2838x and do the same Sysconfig setting and copy the main code to your F2837x project , it would work as a functional test. (Note: We are planning to add this example to F2837x as well in the next C2000ware release). It configures one instance as master and another as slave and you will have to connect its pins externally.

    Regards,

    Veena

  • Hi, Veena:

    spi_ex3_external_loopback from F2838x

    Where is this sample located in C2000Ware? Could you please share the file path?

    Regards,

    Sinan.

  • The example is available here : \ti\c2000\C2000Ware_4_00_00_00\driverlib\f2838x\examples\c28x\spi

  • Hi, Veena:

    I was using C2000Ware_3_04_00_00. I installed C2000Ware_4_00_00_00 on my computer.

    When a new interrupt occurs, the most recent receive data remains in the SPIRXBUF content. How can I zero the contents of the SPIRX buffer.

    //
    // SPI A Receive FIFO ISR
    //
    __interrupt void spiaRxFIFOISR(void)
    {
        uint16_t i;
    
        //
        // Read data
        //
    
        for(i = 0; i < 3; i++)
        {
            rData[i] = 0;
        }
    
    
        for(i = 0; i < 3; i++)
        {
             rData[i] = SPI_readDataNonBlocking(SPIA_BASE);
        }
    
    
        if (rData[2] == 0x3344)
           Interrupt_enable(INT_SPIA_TX);
    
        //
        // Check received data
        //
        for(i = 0; i < 6; i++)
        {
            if(rData[i] != (rDataPoint + i))
            {
                // Something went wrong. rData doesn't contain expected data.
                Example_Fail = 1;
                ESTOP0;
            }
        }
    
        rDataPoint++;
    
        //
        // Clear interrupt flag and issue ACK
        //
        SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    
        Example_PassCount++;
    }
    
    //
    // End of File
    //

    The following piece of code is not recognized in this example.

    SpiaRegs.SPIRXBUF = 0;

    Thanks and best regards,

    Sinan.

  • Hi, Veena:

    \ti\c2000\C2000Ware_4_00_00_00\driverlib\f2838x\examples\c28x\spi

    I have tried many ways. But I couldn't run the example here for f2837xd.

    How can I edit this example for f2837xd?

    Thanks and best regards,

    Sinan.

  • //#############################################################################
    //
    // FILE:   spi_ex5_external_loopback.c
    //
    // TITLE:  SPI Digital Loopback without using FIFOs and Interrupts
    //
    //! \addtogroup driver_example_list
    //! <h1>SPI Digital External Loopback without FIFO Interrupts</h1>
    //!
    //! This program uses the external loopback between two SPI modules. Both
    //! the SPI FIFOs and interrupts are not used in this example. SPIA is
    //! configured as a slave and SPI B is configured as master. This example
    //! demonstrates full duplex communication where both master and slave transmits
    //! and receives data simultaneously.
    //!
    //!
    //! \b External \b Connections \n
    //!  -GPIO25 and GPIO17 - SPISOMI
    //!  -GPIO24 and GPIO16 - SPISIMO
    //!  -GPIO27 and GPIO19 - SPISTE
    //!  -GPIO26 and GPIO18 - SPICLK
    //!
    //! \b Watch \b Variables \n
    //!  - \b TxData_SPIA - Data send from SPIA (slave)
    //!  - \b TxData_SPIB - Data send from SPIB (master)
    //!  - \b RxData_SPIA - Data received by SPIA (slave)
    //!  - \b RxData_SPIB - Data received by SPIB (master)
    //!
    //
    //#############################################################################
    // $TI Release:  $
    // $Release Date:  $
    // $Copyright:  $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Function Prototypes
    //
    void initSPIBMaster(void);
    void initSPIASlave(void);
    void configGPIOs(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint8_t i;
    
        uint16_t TxData_SPIA[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
        uint16_t RxData_SPIA[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        uint16_t TxData_SPIB[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
        uint16_t RxData_SPIB[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Configure GPIOs for external loopback.
        //
        configGPIOs();
    
        //
        // Set up SPI B as master, initializing it for FIFO mode
        //
        initSPIBMaster();
    
        //
        // Set up SPI A as slave, initializing it for FIFO mode
        //
        initSPIASlave();
    
        //
        // Loop forever. Suspend or place breakpoints to observe the buffers.
        //
        for(i = 0; i < 16; i++)
        {
            //
            // Set the TX buffer of slave SPI.
            //
            SPI_writeDataNonBlocking(SPIA_BASE, TxData_SPIA[i]);
    
            //
            // Set the the master TX buffer. This triggers the data trasnmission
            //
            SPI_writeDataNonBlocking(SPIB_BASE, TxData_SPIB[i]);
    
            //
            // Read the received data
            //
            RxData_SPIA[i] = SPI_readDataBlockingNonFIFO(SPIA_BASE);
            RxData_SPIB[i] = SPI_readDataBlockingNonFIFO(SPIB_BASE);
    
            //
            // Check the received data
            //
            if(RxData_SPIA[i] != TxData_SPIB[i])
            {
                ESTOP0;
            }
            if(RxData_SPIB[i] != TxData_SPIA[i])
            {
                ESTOP0;
            }
        }
    
        //
        // Loop forever
        //
        while(1);
    }
    
    //
    // Function to configure SPI B as master with FIFO enabled.
    //
    void initSPIBMaster(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIB_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_MASTER, 500000, 16);
        SPI_disableLoopback(SPIB_BASE);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIB_BASE);
    }
    
    //
    // Function to configure SPI A as slave with FIFO enabled.
    //
    void initSPIASlave(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIA_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_SLAVE, 500000, 16);
        SPI_disableLoopback(SPIA_BASE);
        SPI_setEmulationMode(SPIA_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIA_BASE);
    }
    
    //
    // Configure GPIOs for external loopback.
    //
    void configGPIOs(void)
    {
        //
        // This test is designed for an external loopback between SPIA
        // and SPIB.
        // External Connections:
        // -GPIO25 and GPIO17 - SPISOMI
        // -GPIO24 and GPIO16 - SPISIMO
        // -GPIO27 and GPIO19 - SPISTE
        // -GPIO26 and GPIO18 - SPICLK
        //
    
        //
        // GPIO17 is the SPISOMIA.
        //
        GPIO_setMasterCore(17, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_17_SPISOMIA);
        GPIO_setPadConfig(17, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(17, GPIO_QUAL_ASYNC);
    
        //
        // GPIO16 is the SPISIMOA clock pin.
        //
        GPIO_setMasterCore(16, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_16_SPISIMOA);
        GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(16, GPIO_QUAL_ASYNC);
    
        //
        // GPIO19 is the SPISTEA.
        //
        GPIO_setMasterCore(19, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_19_SPISTEA);
        GPIO_setPadConfig(19, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(19, GPIO_QUAL_ASYNC);
    
        //
        // GPIO18 is the SPICLKA.
        //
        GPIO_setMasterCore(18, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_18_SPICLKA);
        GPIO_setPadConfig(18, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(18, GPIO_QUAL_ASYNC);
    
        //
        // GPIO25 is the SPISOMIB.
        //
        GPIO_setMasterCore(25, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_25_SPISOMIB);
        GPIO_setPadConfig(25, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC);
    
        //
        // GPIO24 is the SPISIMOB clock pin.
        //
        GPIO_setMasterCore(24, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_24_SPISIMOB);
        GPIO_setPadConfig(24, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC);
    
        //
        // GPIO27 is the SPISTEB.
        //
        GPIO_setMasterCore(27, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_27_SPISTEB);
        GPIO_setPadConfig(27, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(27, GPIO_QUAL_ASYNC);
    
        //
        // GPIO26 is the SPICLKB.
        //
        GPIO_setMasterCore(26, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_26_SPICLKB);
        GPIO_setPadConfig(26, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC);
    }
    

    Please use the attached main file.

    Regards,

    Veena

  • Hi, Veena:

    Please use the attached main file.

    I am using this file. I am successfully receiving data from STM32F7 master device. But I can't send data from my DSP slave device to master device.

    The master device performs the process in the picture below to receive data from the slave device:

    My DSP slave device code is as follows:

    //#############################################################################
    //
    // FILE:   spi_ex5_external_loopback.c
    //
    // TITLE:  SPI Digital Loopback without using FIFOs and Interrupts
    //
    //! \addtogroup driver_example_list
    //! <h1>SPI Digital External Loopback without FIFO Interrupts</h1>
    //!
    //! This program uses the external loopback between two SPI modules. Both
    //! the SPI FIFOs and interrupts are not used in this example. SPIA is
    //! configured as a slave and SPI B is configured as master. This example
    //! demonstrates full duplex communication where both master and slave transmits
    //! and receives data simultaneously.
    //!
    //!
    //! \b External \b Connections \n
    //!  -GPIO25 and GPIO17 - SPISOMI
    //!  -GPIO24 and GPIO16 - SPISIMO
    //!  -GPIO27 and GPIO19 - SPISTE
    //!  -GPIO26 and GPIO18 - SPICLK
    //!
    //! \b Watch \b Variables \n
    //!  - \b TxData_SPIA - Data send from SPIA (slave)
    //!  - \b TxData_SPIB - Data send from SPIB (master)
    //!  - \b RxData_SPIA - Data received by SPIA (slave)
    //!  - \b RxData_SPIB - Data received by SPIB (master)
    //!
    //
    //#############################################################################
    // $TI Release:  $
    // $Release Date:  $
    // $Copyright:  $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Function Prototypes
    //
    void initSPIBMaster(void);
    void initSPIASlave(void);
    void configGPIOs(void);
    
    //
    // Main
    //
    
    uint16_t TxData_SPIA[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    uint16_t RxData_SPIA[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    void main(void)
    {
        uint8_t i;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Configure GPIOs for external loopback.
        //
        configGPIOs();
    
        //
        // Set up SPI B as master, initializing it for FIFO mode
        //
        //initSPIBMaster();
    
        //
        // Set up SPI A as slave, initializing it for FIFO mode
        //
        initSPIASlave();
    
        //
        // Loop forever. Suspend or place breakpoints to observe the buffers.
        //
        while(1)
        {
            for(i = 0; i < 6; i++)
            {
                RxData_SPIA[i] = SPI_readDataBlockingNonFIFO(SPIA_BASE) << 8;
    
                SPI_writeDataNonBlocking(SPIA_BASE, TxData_SPIA[i] << 8);
    
            }
        }
    }
    
    //
    // Function to configure SPI B as master with FIFO enabled.
    //
    void initSPIBMaster(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIB_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_MASTER, 500000, 16);
        SPI_disableLoopback(SPIB_BASE);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIB_BASE);
    }
    
    //
    // Function to configure SPI A as slave with FIFO enabled.
    //
    void initSPIASlave(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIA_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_SLAVE, 500000, 8);
        SPI_disableLoopback(SPIA_BASE);
        SPI_setEmulationMode(SPIA_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIA_BASE);
    }
    
    //
    // Configure GPIOs for external loopback.
    //
    void configGPIOs(void)
    {
        //
        // This test is designed for an external loopback between SPIA
        // and SPIB.
        // External Connections:
        // -GPIO25 and GPIO17 - SPISOMI
        // -GPIO24 and GPIO16 - SPISIMO
        // -GPIO27 and GPIO19 - SPISTE
        // -GPIO26 and GPIO18 - SPICLK
        //
    
        /*
        //
        // GPIO17 is the SPISOMIA.
        //
        GPIO_setMasterCore(17, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_17_SPISOMIA);
        GPIO_setPadConfig(17, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(17, GPIO_QUAL_ASYNC);
    
        //
        // GPIO16 is the SPISIMOA clock pin.
        //
        GPIO_setMasterCore(16, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_16_SPISIMOA);
        GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(16, GPIO_QUAL_ASYNC);
    
        //
        // GPIO19 is the SPISTEA.
        //
        GPIO_setMasterCore(19, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_19_SPISTEA);
        GPIO_setPadConfig(19, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(19, GPIO_QUAL_ASYNC);
    
        //
        // GPIO18 is the SPICLKA.
        //
        GPIO_setMasterCore(18, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_18_SPICLKA);
        GPIO_setPadConfig(18, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(18, GPIO_QUAL_ASYNC);
    
    
        //
        // GPIO25 is the SPISOMIB.
        //
        GPIO_setMasterCore(25, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_25_SPISOMIB);
        GPIO_setPadConfig(25, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC);
    
        //
        // GPIO24 is the SPISIMOB clock pin.
        //
        GPIO_setMasterCore(24, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_24_SPISIMOB);
        GPIO_setPadConfig(24, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC);
    
        //
        // GPIO27 is the SPISTEB.
        //
        GPIO_setMasterCore(27, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_27_SPISTEB);
        GPIO_setPadConfig(27, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(27, GPIO_QUAL_ASYNC);
    
        //
        // GPIO26 is the SPICLKB.
        //
        GPIO_setMasterCore(26, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_26_SPICLKB);
        GPIO_setPadConfig(26, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC);
        */
    
        //
        // GPIO59 is the SPISOMIA.
        //
        GPIO_setMasterCore(59, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_59_SPISOMIA);
        GPIO_setPadConfig(59, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(59, GPIO_QUAL_ASYNC);
    
        //
        // GPIO58 is the SPISIMOA clock pin.
        //
        GPIO_setMasterCore(58, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_58_SPISIMOA);
        GPIO_setPadConfig(58, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(58, GPIO_QUAL_ASYNC);
    
        //
        // GPIO61 is the SPISTEA.
        //
        GPIO_setMasterCore(61, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_61_SPISTEA);
        GPIO_setPadConfig(61, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(61, GPIO_QUAL_ASYNC);
    
        //
        // GPIO60 is the SPICLKA.
        //
        GPIO_setMasterCore(60, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_60_SPICLKA);
        GPIO_setPadConfig(60, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(60, GPIO_QUAL_ASYNC);
    }
    

    Happy your Thanksgiving.

    Thanks and best regards.

    Sinan.

  • Hi Sinan,

    The example is data transfer between SPIA and SPIB instances. Please rin the examples as-is with SPI and SPIB connected (without STM) to make sure there are no hardware issues.

    Regards,

    Veena

  • Hi, Veena:

    Please use the attached main file.

    I ran the example you sent me while SPIA and SPIB were connected (without the STM32 master device). The example ran without any problems. However, as I mentioned before, the DSP slave device does not send data to the STM32 master device.

    It is very interesting that I cannot send data to the STM32 master device.

    Do you have the possibility to try the problem on any STM32 device? This issue is a very important part of our project.

    Regards,

    Sinan.

  • Hi Sinan,

    The example ran without any problems.

    That means the SPI slave is able to send the data.

    Do you have the possibility to try the problem on any STM32 device

    Unfortunately, I do not have a STM device with me to test it out.

    What I would do is, disconnect the SOMI pin connection to STM device, and observe it using a logic analyzer/oscilloscope. This is to make sure if the DSP is sending out the data on the SOMI pin. 

    Regards,

    Veena

  • Hi, Veena:

    I succeed to send data from DSP slave device to STM32 master device. However, the correct data is not going to the master device. For example, I am sending data 0xABCD from DSP slave device and STM32 master device receives data 0xD5E6.

    As I mentioned before, there is no problem in sending data from the STM32 master device to the DSP slave device.

    My CPOL and CPHA parameters for Master and Slave devices are correct. I also checked other SPI parameters.

    How we can solve this problem?

    Thanks,

    Sinan.

  • Hi Sinan,

    It would help if you could probe the pins and check what data is available on the SPI lines.

    Regards,

    Veena

  • Hi, Veena:

    I probed the pins on the SPI lines. The Master STM32 device is not receiving the data sent by the Slave DSP correctly.

    But I don't know how to solve this problem.

    Thanks,

    Sinan.

  • Hi, Veena:

    Should I open another case to solve this problem?

    Sinan,

    Thanks and best regards.

  • Hi Sinan,

    The data sent from the DSP looks correct. There must been some configuration issue on the STM side.

    Regards,

    Veena

  • Hi, Veena:

    There must been some configuration issue on the STM side.

    I looked at the config settings on the STM side. There is nothing wrong.

    Could it be a synchronization problem between master and slave devices? 

    Is there an example of SPI communication between Texas DSP and a different DSP or MCU?

    Sinan,
    Thanks and best regards.

  • Hi Sinan,

    Unfortunately, we do not have such an example.

    We have one which interfaces the external EEPROM module AT25128.

    Regards,

    Veena

  • Hi, Veena:

    We have one which interfaces the external EEPROM module AT25128.

    Where is this example in C2000Ware?

    Sinan,
    Thanks.