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.

MSP430F5529: How to config SPI using DMA on TI-RTOS

Part Number: MSP430F5529

Hi All,

I have some questions:

1. My project run on TI-RTOS system. I setting SPI with DMA function, but after my code execute to SPI_transfer() that will stay here. Not continue to execute. Can anyone tell me how to solve it?

In .cfg:

var hwiParams = new halHwi.Params();
/* DMA Hwi for the SPIUSCI driver */
hwiParams.arg = 0;
halHwi.create(50, "&MSP_EXP430F5529LP_isrDMA", hwiParams);

--------------------------------------------

In MSP_EXP430F5529LP.c:

Void MSP_EXP430F5529LP_isrDMA(UArg arg)
{
/* Call the SPI DMA function, passing the SPI handle used for WiFi */
SPI_serviceISR((SPI_Handle) &(SPI_config[0]));
}

/*
* =============================== SPI ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(SPI_config, ".const:SPI_config")
#pragma DATA_SECTION(spiUSCIBDMAHWAttrs, ".const:spiUSCIBDMAHWAttrs")
#endif

#include <ti/drivers/SPI.h>
#include <ti/drivers/spi/SPIUSCIBDMA.h>

SPIUSCIBDMA_Object spiUSCIBDMAObjects[MSP_EXP430F5529LP_SPICOUNT];
uint8_t spiUSCIBDMAscratchBuf[MSP_EXP430F5529LP_SPICOUNT];

const SPIUSCIBDMA_HWAttrs spiUSCIBDMAHWAttrs[MSP_EXP430F5529LP_SPICOUNT] = {
{
.baseAddr = USCI_B0_BASE,
.clockSource = USCI_B_SPI_CLOCKSOURCE_SMCLK,
.bitOrder = USCI_B_SPI_MSB_FIRST,
.scratchBufPtr = &spiUSCIBDMAscratchBuf[0],
.defaultTxBufValue = 0,

/* DMA */
.dmaBaseAddr = DMA_BASE,
/* Rx Channel */
.rxDMAChannelIndex = DMA_CHANNEL_1,
.rxDMASourceTrigger = DMA_TRIGGERSOURCE_18,
/* Tx Channel */
.txDMAChannelIndex = DMA_CHANNEL_0,
.txDMASourceTrigger = DMA_TRIGGERSOURCE_19
}
};

const SPI_Config SPI_config[] = {
{
.fxnTablePtr = &SPIUSCIBDMA_fxnTable,
.object = &spiUSCIBDMAObjects[0],
.hwAttrs = &spiUSCIBDMAHWAttrs[0]
},
{NULL, NULL, NULL},
};

/*
* ======== MSP_EXP430F5529LP_initSPI ========
*/
void MSP_EXP430F5529LP_initSPI(void)
{
/*
* NOTE: TI-RTOS examples configure USCIB0 as either SPI or I2C. Thus,
* a conflict occurs when the I2C & SPI drivers are used simultaneously in
* an application. Modify the pin mux settings in this file and resolve the
* conflict before running your the application.
*/

/* SPI CLK */
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN2);
/* MOSI/SIMO */
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN0);
/* MISO/SOMI */
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN1);

SPI_init();
}

--------------------------------------------

In main.c:

Void spi_master_taskFxn(UArg arg0, UArg arg1)
{
SPI_Handle spi_master;
SPI_Params spi_master_Params;
/* Create I2C for usage */
SPI_Params_init(&spi_master_Params);
spi_master_Params.transferMode = SPI_MODE_CALLBACK;
spi_master_Params.mode = SPI_MASTER;
spi_master_Params.bitRate = 1000000,
spi_master_Params.dataSize = 8;
//spi_master_Params.frameFormat = SPI_POL0_PHA0;
spi_master = SPI_open(Board_SPI0, &spi_master_Params);
if (spi_master == NULL) System_abort("Error Initializing SPI\n");
else System_printf("SPI Initialized!\n");
System_flush();

uint8_t txBuffer[16] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
SPI_Transaction spiTransaction;
spiTransaction.txBuf = txBuffer;
spiTransaction.rxBuf = NULL;
spiTransaction.count = 16;

while(1) {
if(SPI_transfer(spi_master, &spiTransaction) == NULL) System_printf("SPI_transfer error\n");
else System_printf("SPI_transfer success!\n");
System_flush();
}
}

2. When I setting spi_master_Params.bitRate = 1000000, I can measure SPI CLK about 1MHz.

But when I setting to 3000000, it will become 4MHz. Does the limit is 1MHz on TI-RTOS system?

Thanks.

  • Hi there,

    1. Have you set any endless loop in SPI_transfer()? it may be the stop at it when the condition judgement is not suitable.

    2. I suggest you check bit 6-7 of UCB0CTL1 Register for the source clock, and then you can calculate the clock frequency as shown in following picture:

    Best Regards

    Sal

  • Hi Sal,

    1. I find if I setting spi_master_Params.transferMode  = SPI_MODE_BLOCKING, it will be ok.

    But setting SPI_MODE_CALLBACK will stay here. Not continue to execute.

    2. My clock setting:  MCLK = 8192000  , ACLK = 32768  , SMCLK = 8192000.

       and SMCLK used as SPI clock. (.clockSource = USCI_B_SPI_CLOCKSOURCE_SMCLK)

       DCO FLL and ACLK are reference = REFO.

  • Hi there,

    As lacking the information of function internal details, I have some suggestion for you:

    1. There is no mode of "blocking or callback" in SPI peripheral, so it is a customized function on TI-RTOS, so I suggest you find the definition of these two mode and check the behavior under different mode. According to the mode name, I guess callback mode will be waiting for receiving data so it stays here

    2.As the spi clock is about 8MHz, it cannot be evenly divisible by 3MHz, so it will not be your expectation. Please check how "spi_master_Params.bitRate" is used, I think it will do a division like "(int) 8MHz/3MHz=2", then set  UCBRx =2, so the real frequency is about 4MHz.

    Best Regards

    Sal

  • Hi Sal,

    Thanks for your teaching. Now, I understand why spi_master_Params.bitRate set 3000000 will become 4MHz ,not 3MHz.
    Does the SMCLK can change to 24MHz on TI-RTOS system? It will affect tasks on system?

    Thanks.

  • Hi there,

    Surely yes, the max frequency of MCLK / SMCLK is 25MHz.

    I am not familiar with RTOS system, and in my opinion it mainly includes the execution method of multiply tasks. So improved CPU clock will improve system performance, and then time cost of tasks will decreased. You should check each task time cost and do evaluation if necessary.

    You can refer to the section 5.2.6 of use's guide for clock setting.

    Here is the general instructions:

    For example, set FLLN=22, and FFD=32, then the DCOCLKDIV is about 24MHz.

    Best Regards

    Sal

**Attention** This is a public forum