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.

MCSPI Speed / Operation

We are using all of the CS's out of the McSPI and are currently driving the device from user space rather than using the driver directly.  We are not getting great performance results---see graph below that shows with nothing else running on the processor our SPI requests are ~1ms apart.  We are currently enabling/disabling the channel in between reads/writes as this seemed necessary in order to get it to actually clock out data.  Has anyone else see this problem?

Here's the code we are using for this read:

uint32 hwl_Spi_Read(uint8 bus, uint8* buf, uint32 num_bytes)
{
uint32 ret_val = NO_ERROR;
uint32 stat_reg = MCSPI_CH0STAT;
uint32 rx_reg = MCSPI_RX0;
uint32 tx_reg = MCSPI_TX0;
uint32 ctrl_reg = MCSPI_CH0CTRL;
uint32 conf_reg = MCSPI_CH0CONF;
uint32 conf_shadow = 0;
uint32 bytes_read = 0;
uint8* ptr = buf;
uint32 temp;

Log_Func_Begin(LOG_MODULE_SPI);
Log(LOG_SEVERITY_DEBUG, "spi_read(%u, %X, %u)\n", bus, buf, num_bytes);

if(bus > 3)
{
ret_val = ERROR_SPI_INVALID_BUS;
Log(LOG_SEVERITY_ERROR, "Invalid SPI Bus (%u)\n", bus);
goto end;
}

if(bus > 0)
{
stat_reg += bus*0x14;
rx_reg += bus*0x14;
tx_reg += bus*0x14;
ctrl_reg += bus*0x14;
conf_reg += bus*0x14;
}

// enable the SPI channel
ret_val += hwl_ti816x_write(ctrl_reg, 1);

//TODO: Fix this 103D8 which is not nice with the bits
ret_val += hwl_ti816x_write(conf_reg, 0x103D8); // set output on D1
ret_val += hwl_ti816x_read(conf_reg, &conf_shadow);

while(bytes_read < num_bytes)
{
// limit bits to 32 since we can only send up to 4 bytes at a time
uint32 bits = MIN(4, num_bytes - bytes_read) * 8;

// Check to see whether the WL (bits 7-11) has the proper value already
if(bits-1 != ((conf_shadow>>7)&0x1F)) // the 5 bits in the middle of the register are the key bits
{
// no match -- set it
conf_shadow = (conf_shadow & 0xFFFFF07F) | ((bits-1) << 7);
ret_val += hwl_ti816x_write(conf_reg, conf_shadow);
}

// verify nothing is stuck in the TX register
if(_hwl_Spi_WaitForBit(bus, MCSPI_CHnSTAT_TXS, SPI_WAIT_DIR_HIGH) != NO_ERROR)
{
ret_val = ERROR_SPI_TIMEOUT;
Log(LOG_SEVERITY_ERROR, "SPI Timeout\n");
goto end;

}

hwl_ti816x_write(tx_reg, 0); // dummy write to force clocks

hwl_ti816x_read(rx_reg, &temp); // read the RX register

switch(bits)
{
case 8: *ptr = temp&0xFF; break;
case 16: *ptr = (temp>>8)&0xFF; *(ptr+1) = temp&0xFF; break;
case 24: *ptr = (temp>>16)&0xFF; *(ptr+1) = (temp>>8)&0xFF; *(ptr+2) = temp&0xFF; break;
case 32: *ptr = (temp>>24)&0xFF; *(ptr+1) = (temp>>16)&0xFF; *(ptr+2) = (temp>>8)&0xFF; *(ptr+3) = temp&0xFF; break;
}

// if channel was enabled, disable it to flush RX, then enable
//ret_val += hwl_ti816x_read(ctrl_reg, &temp);
/*if(temp) ret_val += hwl_ti816x_write(ctrl_reg, 0);
ret_val += hwl_ti816x_write(ctrl_reg, 1); // enable channel*/

ptr += bits/8;
bytes_read += bits/8;
}

end:
ret_val += hwl_ti816x_write(conf_reg, 0x203D8); // set output back to D0

// disable the SPI channel
ret_val += hwl_ti816x_write(ctrl_reg, 0);

Log_Func_End();
return ret_val;
}