-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Improve SPI interface (GIT8266O-397) #723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
For the alignment issue, I realized I am not using |
I haved noticed problems what you meet, so we are refactoring the SPI driver, main work is about what your mentioned. And the other work is to increase the throughput of the SPI. So when version |
I see you made some changes in
ESP_LOGW(TAG,"Using unaligned data may reduce transmission efficiency");
memset(spi_object[host]->buf, 0, sizeof(uint32_t) * 16);
memcpy(spi_object[host]->buf, trans->mosi, trans->bits.mosi / 8 + (trans->bits.mosi % 8) ? 1 : 0);
for (x = 0; x < trans->bits.mosi; x += 32) {
y = x / 32;
SPI[host]->data_buf[y] = spi_object[host]->buf[y];
} ... does it mean the |
I'd like to point out an operator precedence problem with the trans->bits.mosi / 8 + (trans->bits.mosi % 8) ? 1 : 0 part too. The current code will copy only exactly 1 byte no matter what is the content of trans->bits.mosi. |
I found another bit more serious issue at the miso part. The alignment check should also check the transfer length like this: |
…e SPI interface (GIT8266O-397)"
…e SPI interface (GIT8266O-397)"
…e SPI interface (GIT8266O-397)"
Environment
Problem Description
There are several issues that make the SPI driver difficult to use:
spi_trans
(drivers/spi.c) requires 32bit-aligned buffers for miso and mosi dataThis is not a big deal when the buffer is allocated for SPI, but when a longer buffer is sent piecewise, the necessary alignment becomes a burden. Consider the following scenario (SPI master):
... unless each time a multiple of 4 bytes is transferred, this explodes due to wrong alignment in spi_master_trans(). So the only solution currently is for user code to keep copying the data to a properly aligned buffer before it's passed to
spi_trans()
. So it's 1 copy beforespi_trans()
is called and another copy of the same data insidespi_master_trans()
.The same issue happens with miso data.
Furthermore, making the type
uint32_t*
makes life difficult in all situations when the user doesn't want to transfer an array ofuint32_t
s. Anuint8_t*
or justvoid*
would be more obvious. There is no data structure on this level - it's just bytes, or in fact just bits, asbits.mosi
is actually the number of bits to transfer. So why force multiples of 4 bytes while the actual transfer size is bits?I see that the actual SPI data buffer is defined as
uint32_t
(in spi_struct.h). I was not successful in finding any details on how should the HW buffer be accessed. But looking at how esp-open-rtos handles this (esp_spi.c in esp-open-rtos), it seems that a simplememcpy()
(from a source address w/o any necessary alignment) is sufficient. It just seems that the last write has to make sure it ends on a multiple of 4 bytes. Alternatively, even if the SPI data buffer had to be accessed asuint32_t
, it could still be handled insidespi_master_trans()
.The size of
spi_trans_t
is 20 bytes yetspi_trans()
accepts it by valueThis means it's copied to stack. And then
spi_trans()
callsspi_trans_static()
which calls one ofspi_master_trans()
orspi_slave_trans()
. If the calls are not inlined, that's 3 unneeded copies ofspi_trans_t
. I thinkspi_trans()
,spi_trans_static()
,spi_master_trans()
andspi_slave_trans()
should accept a pointer to thespi_trans_t
to spare stack space.Making
spi_trans_t
cmd
andaddr
pointers makes the usage for SPI master more difficultWhen
cmd
oraddr
are an expression, a local variable has to be created. I understand why these were made pointers - for SPI slave. But why not just store the received values in the SPI slave scenario inside thespi_trans_t
and let the caller then take the values and process them as needed? Of course this would only work if thespi_trans_t
is passed via pointer, so thatspi_slave_trans()
can modify these.The text was updated successfully, but these errors were encountered: