Hey!
I'm working on the WiFly and needed to use the SPI-Interface… Because I had some unexpected behavior I looked into the SPI-Interface code and come upon two things I would like to discuss…
first the one in HardwareSpi.cpp
<br />
void HardwareSPI::write(const uint8 *data, uint32 length) {<br />
uint32 txed = 0;<br />
while (txed < length) {<br />
txed += spi_tx(this->spi_d, data + txed, length - txed);<br />
}<br />
}<br />
Firs use the supplied function from spi.c this should avoid some overhead actually.
But the more important one. For me it seemed quiet crucial to read from the transmit register once after transmitting all data Because even though the other side doesn't send data there seems to be data in the TX-buffer
void HardwareSPI::write(const void *data, uint32 length) {
// use the offered function from spi.c
spi_tx(this->spi_d, data, length);
spi_rx_reg(this->spi_d);
}
the other is the spi.c directly <i>libmaple's spi.c</i>
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
uint32 txed = 0;
uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT;
while (spi_is_tx_empty(dev) && (txed < len)) {
if (byte_frame) {
dev->regs->DR = ((const uint8*)buf)[txed++];
} else {
dev->regs->DR = ((const uint16*)buf)[txed++];
}
}
return txed;
}
<i>changed spi.c</i>
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
uint32 txed = 0;
uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT;
while ((txed < len)) {
while(!spi_is_tx_empty(dev))
;
if (byte_frame) {
//spi_tx_reg((((const uint8*)buf)[txed++] & 0X0000) );
dev->regs->DR = ((const uint8*)buf)[txed++];
} else {
//spi_tx_reg(((const uint16*)buf)[txed++]);
dev->regs->DR = ((const uint16*)buf)[txed++];
}
}
return txed;
}
I think the original code will just work with transfering one byte. Because after the first round through the while loop (equal to the first byte send over spi). The function spi_is_tx_empty() might return true (and therefor the 2nd byte can be put into the buffer) but thats not certain. But it becomes obvious if we want to transmit the 3rd byte. because now we have to WAIT till the TXE-flag turns and this will never be captured be the libmaple while loop.
Therefore I thing it needs to be this "blocking" transfer if we want to transmit more than one byte. (see fig. 239 in the documentation)
BUT because I'm not 100% certain I would like to discuss my changes ;)