浏览代码

Fix transfer(buf, size) with LSBFIRST on Teensy 3.x

main
PaulStoffregen 8 年前
父节点
当前提交
22b7dbd0d0
共有 1 个文件被更改,包括 21 次插入12 次删除
  1. +21
    -12
      SPI.cpp

+ 21
- 12
SPI.cpp 查看文件

} }




void SPIClass::transfer(void *buf, size_t count) {
void SPIClass::transfer(void *buf, size_t count)
{
if (count == 0) return; if (count == 0) return;
uint8_t *p_write = (uint8_t *)buf; uint8_t *p_write = (uint8_t *)buf;
uint8_t *p_read = p_write; uint8_t *p_read = p_write;
size_t count_read = count; size_t count_read = count;
bool lsbfirst = (SPI0_CTAR0 & SPI_CTAR_LSBFE) ? true : false;


// Lets clear the reader queue // Lets clear the reader queue
SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
} }


while (count > 0) { while (count > 0) {

// Push out the next byte; // Push out the next byte;
uint16_t w = (*p_write++) << 8;
uint16_t w = (*p_write++) << 8;
w |= *p_write++; w |= *p_write++;
if (lsbfirst) w = __builtin_bswap16(w);
if (count == 2) if (count == 2)
KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CTAS(1); KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CTAS(1);
else else
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;
} }
} }
} while ((sr & (15 << 12)) > (3 << 12)); } while ((sr & (15 << 12)) > (3 << 12));

} }


// now lets wait for all of the read bytes to be returned... // now lets wait for all of the read bytes to be returned...
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;
return 0; return 0;
} }


void SPI1Class::transfer(void *buf, size_t count) {
void SPI1Class::transfer(void *buf, size_t count)
{
if (count == 0) return; if (count == 0) return;
uint8_t *p_write = (uint8_t *)buf; uint8_t *p_write = (uint8_t *)buf;
uint8_t *p_read = p_write; uint8_t *p_read = p_write;
size_t count_read = count; size_t count_read = count;
bool lsbfirst = (SPI1_CTAR0 & SPI_CTAR_LSBFE) ? true : false;


// Lets clear the reader queue // Lets clear the reader queue
SPI1_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); SPI1_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
} }


while (count > 0) { while (count > 0) {

// Push out the next byte; // Push out the next byte;
uint16_t w = (*p_write++) << 8;
uint16_t w = (*p_write++) << 8;
w |= *p_write++; w |= *p_write++;
if (lsbfirst) w = __builtin_bswap16(w);
KINETISK_SPI1.PUSHR = w | SPI_PUSHR_CTAS(1); KINETISK_SPI1.PUSHR = w | SPI_PUSHR_CTAS(1);
count -= 2; // how many bytes to output. count -= 2; // how many bytes to output.
// Make sure queue is not full before pushing next byte out // Make sure queue is not full before pushing next byte out
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;
} }
} }
} while ((sr & (15 << 12)) > (0 << 12)); // SPI1 and 2 only have 1 item queue } while ((sr & (15 << 12)) > (0 << 12)); // SPI1 and 2 only have 1 item queue

} }


// now lets wait for all of the read bytes to be returned... // now lets wait for all of the read bytes to be returned...
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;
return 0; return 0;
} }


void SPI2Class::transfer(void *buf, size_t count) {
void SPI2Class::transfer(void *buf, size_t count)
{
if (count == 0) return; if (count == 0) return;
uint8_t *p_write = (uint8_t *)buf; uint8_t *p_write = (uint8_t *)buf;
uint8_t *p_read = p_write; uint8_t *p_read = p_write;
size_t count_read = count; size_t count_read = count;
bool lsbfirst = (SPI2_CTAR0 & SPI_CTAR_LSBFE) ? true : false;


// Lets clear the reader queue // Lets clear the reader queue
SPI2_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); SPI2_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
} }


while (count > 0) { while (count > 0) {

// Push out the next byte; // Push out the next byte;
uint16_t w = (*p_write++) << 8;
uint16_t w = (*p_write++) << 8;
w |= *p_write++; w |= *p_write++;
if (lsbfirst) w = __builtin_bswap16(w);
KINETISK_SPI2.PUSHR = w | SPI_PUSHR_CTAS(1); KINETISK_SPI2.PUSHR = w | SPI_PUSHR_CTAS(1);
count -= 2; // how many bytes to output. count -= 2; // how many bytes to output.
// Make sure queue is not full before pushing next byte out // Make sure queue is not full before pushing next byte out
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;
} }
} }
} while ((sr & (15 << 12)) > (0 << 12)); // SPI2 and 2 only have 1 item queue } while ((sr & (15 << 12)) > (0 << 12)); // SPI2 and 2 only have 1 item queue

} }


// now lets wait for all of the read bytes to be returned... // now lets wait for all of the read bytes to be returned...
*p_read++ = w; // Read any pending RX bytes in *p_read++ = w; // Read any pending RX bytes in
count_read--; count_read--;
} else { } else {
if (lsbfirst) w = __builtin_bswap16(w);
*p_read++ = w >> 8; *p_read++ = w >> 8;
*p_read++ = (w & 0xff); *p_read++ = (w & 0xff);
count_read -= 2; count_read -= 2;

正在加载...
取消
保存