SPI transfers fail once clock rate is set higher than 6Mhz
stephendpmurphy opened this issue Β· comments
Hi there π First off, thank you for all of your work in updating and maintaining this lib. It's been easy to integrate and I appreciate the open-source aspect of it.
However, I am having some issues. I am integrating this lib into my C application and attempting to send SPI communications with a FT2232HL bridge and verifying the output using a Salae Logic analyzer. My issues are as follows
- SPI Writes give what just looks like erratic bouncing lines (Actually very similar results to my next issue) - I have had to replace my Writes with a Transfer call in order for it to work properly
- SPI transactions (Read/Write/Transfer) can not exceed 6Mhz. Otherwise the IO lines appear erratic and unpredictable.
Below is a snippet of the code used to initiate a transfer. The _write
function opens up the channel with our SPI configuration retrieved from my defined xfer_t
which then calls the spi_write
function where the transfer is actually initiated and then cleaned up.
void SPI::_write(shost_xfer_t *xfer) {
int ret = 0;
// Open an MPSSE instance for SPI0 and store the context
this->mpsse = MPSSE(modes::SPI0, xfer->clk, MSB);
// Ensure the context is not NULL and and the mpsse channel is open
if (this->mpsse != NULL && !this->mpsse->open) {
// TODO what should be something like: "Failed to initialize MPSSE: %s\n", ErrorString(this->mpsse)
throw std::system_error(EIO, std::generic_category(), ErrorString(this->mpsse));
}
ret = spi_write(xfer->buff, xfer->len);
Close(this->mpsse);
switch (ret) {
case 1:
// TODO printing address whould be nice
throw std::system_error(ENXIO, std::generic_category(), "No response from peripheral.");
break;
case 2:
throw std::system_error(EIO, std::generic_category(), "Hardware failure.");
break;
default:
// all is good, no need to do anything.
break;
}
xfer->bytesTranferred = xfer->len;
}
int8_t SPI::spi_write(uint8_t *src_buffer, size_t buffer_len) {
int8_t retVal = 0;
char *writeBuffer = (char *) malloc(buffer_len);
char *readBuffer = (char *) malloc(buffer_len+1);
memcpy((void*)writeBuffer, (const void*)src_buffer, buffer_len);
// Send the start condition for SPI
if( MPSSE_OK != Start(mpsse) ) {
retVal = 1;
goto CLEANUP;
}
// Write our buffer
readBuffer = Transfer(mpsse, writeBuffer, buffer_len);
// Send the stop condition for SPI
Stop(mpsse);
CLEANUP:
// Free the write buffer we created
free(writeBuffer);
free(readBuffer);
return retVal;
}
Here is a preview of a Read transaction at what is supposed to be 12Mhz.
1.) As a sanity check, do you see anything off in the transfer code.
2.) Have you seen related issues to pushing the clock rate too far on certain hardware?