Browse Source

Merge pull request #42 from KurtE/T4-SerialFlash-fix

T4- Switch to port() and hardware() like T3.x
main
Paul Stoffregen 5 years ago
parent
commit
2b4b27a066
No account linked to committer's email address
2 changed files with 69 additions and 63 deletions
  1. +40
    -43
      SPI.cpp
  2. +29
    -20
      SPI.h

+ 40
- 43
SPI.cpp View File

// CBCMR[LPSPI_PODF] - div4 = 132 MHz // CBCMR[LPSPI_PODF] - div4 = 132 MHz




hardware->clock_gate_register &= ~hardware->clock_gate_mask;
hardware().clock_gate_register &= ~hardware().clock_gate_mask;


CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) | CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) |
CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714 CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714


uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3); uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
//uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3); //uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware->miso_pin[miso_pin_index], hardware->mosi_pin[mosi_pin_index], hardware->sck_pin[sck_pin_index]);
*(portControlRegister(hardware->miso_pin[miso_pin_index])) = fastio;
*(portControlRegister(hardware->mosi_pin[mosi_pin_index])) = fastio;
*(portControlRegister(hardware->sck_pin[sck_pin_index])) = fastio;
Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware().miso_pin[miso_pin_index], hardware().mosi_pin[mosi_pin_index], hardware().sck_pin[sck_pin_index]);
*(portControlRegister(hardware().miso_pin[miso_pin_index])) = fastio;
*(portControlRegister(hardware().mosi_pin[mosi_pin_index])) = fastio;
*(portControlRegister(hardware().sck_pin[sck_pin_index])) = fastio;


//printf("CBCMR = %08lX\n", CCM_CBCMR); //printf("CBCMR = %08lX\n", CCM_CBCMR);
hardware->clock_gate_register |= hardware->clock_gate_mask;
*(portConfigRegister(hardware->miso_pin[miso_pin_index])) = hardware->miso_mux[miso_pin_index];
*(portConfigRegister(hardware->mosi_pin [mosi_pin_index])) = hardware->mosi_mux[mosi_pin_index];
*(portConfigRegister(hardware->sck_pin [sck_pin_index])) = hardware->sck_mux[sck_pin_index];
hardware().clock_gate_register |= hardware().clock_gate_mask;
*(portConfigRegister(hardware().miso_pin[miso_pin_index])) = hardware().miso_mux[miso_pin_index];
*(portConfigRegister(hardware().mosi_pin [mosi_pin_index])) = hardware().mosi_mux[mosi_pin_index];
*(portConfigRegister(hardware().sck_pin [sck_pin_index])) = hardware().sck_mux[sck_pin_index];


//digitalWriteFast(10, HIGH); //digitalWriteFast(10, HIGH);
//pinMode(10, OUTPUT); //pinMode(10, OUTPUT);
//digitalWriteFast(10, HIGH); //digitalWriteFast(10, HIGH);
port->CR = LPSPI_CR_RST;
port().CR = LPSPI_CR_RST;


// Lets initialize the Transmit FIFO watermark to FIFO size - 1... // Lets initialize the Transmit FIFO watermark to FIFO size - 1...
// BUGBUG:: I assume queue of 16 for now... // BUGBUG:: I assume queue of 16 for now...
port->FCR = LPSPI_FCR_TXWATER(15);
port().FCR = LPSPI_FCR_TXWATER(15);
} }


uint8_t SPIClass::pinIsChipSelect(uint8_t pin) uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
{ {
for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
if (pin == hardware().cs_pin[i]) return 1;
}
return 0; return 0;
} }


bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2) bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
{ {
uint8_t pin1_mask, pin2_mask;
if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
//Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
if ((pin1_mask & pin2_mask) != 0) return false;
return true;
return false; // only one CS defined
} }


bool SPIClass::pinIsMOSI(uint8_t pin) bool SPIClass::pinIsMOSI(uint8_t pin)
{ {
for (unsigned int i = 0; i < sizeof(hardware->mosi_pin); i++) {
if (pin == hardware->mosi_pin[i]) return true;
for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
if (pin == hardware().mosi_pin[i]) return true;
} }
return false; return false;
} }


bool SPIClass::pinIsMISO(uint8_t pin) bool SPIClass::pinIsMISO(uint8_t pin)
{ {
for (unsigned int i = 0; i < sizeof(hardware->miso_pin); i++) {
if (pin == hardware->miso_pin[i]) return true;
for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
if (pin == hardware().miso_pin[i]) return true;
} }
return false; return false;
} }


bool SPIClass::pinIsSCK(uint8_t pin) bool SPIClass::pinIsSCK(uint8_t pin)
{ {
for (unsigned int i = 0; i < sizeof(hardware->sck_pin); i++) {
if (pin == hardware->sck_pin[i]) return true;
for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
if (pin == hardware().sck_pin[i]) return true;
} }
return false; return false;
} }
// setCS() is not intended for use from normal Arduino programs/sketches. // setCS() is not intended for use from normal Arduino programs/sketches.
uint8_t SPIClass::setCS(uint8_t pin) uint8_t SPIClass::setCS(uint8_t pin)
{ {
/*
for (unsigned int i = 0; i < sizeof(hardware->cs_pin); i++) {
if (pin == hardware->cs_pin[i]) {
volatile uint32_t *reg = portConfigRegister(pin);
*reg = hardware->cs_mux[i];
return hardware->cs_mask[i];
for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
if (pin == hardware().cs_pin[i]) {
*(portConfigRegister(pin)) = hardware().sck_mux[i];
return 1;
} }
} */
}
return 0; return 0;
} }




void SPIClass::setBitOrder(uint8_t bitOrder) void SPIClass::setBitOrder(uint8_t bitOrder)
{ {
hardware->clock_gate_register |= hardware->clock_gate_mask;
hardware().clock_gate_register |= hardware().clock_gate_mask;


if (bitOrder == LSBFIRST) { if (bitOrder == LSBFIRST) {
port->TCR |= LPSPI_TCR_LSBF;
port().TCR |= LPSPI_TCR_LSBF;
} else { } else {
port->TCR &= ~LPSPI_TCR_LSBF;
port().TCR &= ~LPSPI_TCR_LSBF;
} }
} }


void SPIClass::setDataMode(uint8_t dataMode) void SPIClass::setDataMode(uint8_t dataMode)
{ {
hardware->clock_gate_register |= hardware->clock_gate_mask;
hardware().clock_gate_register |= hardware().clock_gate_mask;
//SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
} }


const SPIClass::SPI_Hardware_t spiclass_lpspi4_hardware = {
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON), CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
12, 12,
3 | 0x10, 3 | 0x10,
10, 10,
3 | 0x10, 3 | 0x10,
}; };
SPIClass SPI(&IMXRT_LPSPI4_S, &spiclass_lpspi4_hardware);
SPIClass SPI((uintptr_t)&IMXRT_LPSPI4_S, (uintptr_t)&SPIClass::spiclass_lpspi4_hardware);
//SPIClass SPI(&IMXRT_LPSPI4_S, &spiclass_lpspi4_hardware);


void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName) void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
{ {


// Pass 1 keep it simple and don't try packing 8 bits into 16 yet.. // Pass 1 keep it simple and don't try packing 8 bits into 16 yet..
// Lets clear the reader queue // Lets clear the reader queue
//port->CR = LPSPI_CR_RRF;
//port().CR = LPSPI_CR_RRF;


while (count > 0) { while (count > 0) {
// Push out the next byte; // Push out the next byte;
port->TDR = p_write? *p_write++ : _transferWriteFill;
port().TDR = p_write? *p_write++ : _transferWriteFill;
count--; // how many bytes left to output. count--; // how many bytes left to output.
// Make sure queue is not full before pushing next byte out // Make sure queue is not full before pushing next byte out
do { do {
if ((port->RSR & LPSPI_RSR_RXEMPTY) == 0) {
uint8_t b = port->RDR; // Read any pending RX bytes in
if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
uint8_t b = port().RDR; // Read any pending RX bytes in
if (p_read) *p_read++ = b; if (p_read) *p_read++ = b;
count_read--; count_read--;
} }
} while ((port->SR & LPSPI_SR_TDF) == 0) ;
} while ((port().SR & LPSPI_SR_TDF) == 0) ;


} }


// now lets wait for all of the read bytes to be returned... // now lets wait for all of the read bytes to be returned...
while (count_read) { while (count_read) {
if ((port->RSR & LPSPI_RSR_RXEMPTY) == 0) {
uint8_t b = port->RDR; // Read any pending RX bytes in
if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
uint8_t b = port().RDR; // Read any pending RX bytes in
if (p_read) *p_read++ = b; if (p_read) *p_read++ = b;
count_read--; count_read--;
} }

+ 29
- 20
SPI.h View File

const uint8_t cs_pin[CNT_CS_PINS]; const uint8_t cs_pin[CNT_CS_PINS];
const uint32_t cs_mux[CNT_CS_PINS]; const uint32_t cs_mux[CNT_CS_PINS];
} SPI_Hardware_t; } SPI_Hardware_t;
static const SPI_Hardware_t spiclass_lpspi4_hardware;


public: public:
constexpr SPIClass(IMXRT_LPSPI_t *myport, const SPI_Hardware_t *myhardware)
: port(myport), hardware(myhardware) {
constexpr SPIClass(uintptr_t myport, uintptr_t myhardware)
: port_addr(myport), hardware_addr(myhardware) {
} }
// constexpr SPIClass(IMXRT_LPSPI_t *myport, const SPI_Hardware_t *myhardware)
// : port(myport), hardware(myhardware) {
// }
// Initialize the SPI library // Initialize the SPI library
void begin(); void begin();


#endif #endif


//printf("trans\n"); //printf("trans\n");
port->CR = 0;
port->CFGR1 = LPSPI_CFGR1_MASTER | LPSPI_CFGR1_SAMPLE;
port->CCR = settings.ccr;
port->TCR = settings.tcr;
//port->CCR = LPSPI_CCR_SCKDIV(4);
//port->TCR = LPSPI_TCR_FRAMESZ(7);
port->CR = LPSPI_CR_MEN;
port().CR = 0;
port().CFGR1 = LPSPI_CFGR1_MASTER | LPSPI_CFGR1_SAMPLE;
port().CCR = settings.ccr;
port().TCR = settings.tcr;
//port().CCR = LPSPI_CCR_SCKDIV(4);
//port().TCR = LPSPI_TCR_FRAMESZ(7);
port().CR = LPSPI_CR_MEN;
} }


// Write to the SPI bus (MOSI pin) and also receive (MISO pin) // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
uint8_t transfer(uint8_t data) { uint8_t transfer(uint8_t data) {
// TODO: check for space in fifo? // TODO: check for space in fifo?
port->TDR = data;
port().TDR = data;
while (1) { while (1) {
uint32_t fifo = (port->FSR >> 16) & 0x1F;
if (fifo > 0) return port->RDR;
uint32_t fifo = (port().FSR >> 16) & 0x1F;
if (fifo > 0) return port().RDR;
} }
//port().SR = SPI_SR_TCF; //port().SR = SPI_SR_TCF;
//port().PUSHR = data; //port().PUSHR = data;
//return port().POPR; //return port().POPR;
} }
uint16_t transfer16(uint16_t data) { uint16_t transfer16(uint16_t data) {
uint32_t tcr = port->TCR;
port->TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ(15); // turn on 16 bit mode
port->TDR = data; // output 16 bit data.
while ((port->RSR & LPSPI_RSR_RXEMPTY)) ; // wait while the RSR fifo is empty...
port->TCR = tcr; // restore back
return port->RDR;
uint32_t tcr = port().TCR;
port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ(15); // turn on 16 bit mode
port().TDR = data; // output 16 bit data.
while ((port().RSR & LPSPI_RSR_RXEMPTY)) ; // wait while the RSR fifo is empty...
port().TCR = tcr; // restore back
return port().RDR;
} }


void inline transfer(void *buf, size_t count) {transfer(buf, buf, count);} void inline transfer(void *buf, size_t count) {transfer(buf, buf, count);}
uint8_t setCS(uint8_t pin); uint8_t setCS(uint8_t pin);


private: private:
private:
IMXRT_LPSPI_t & port() { return *(IMXRT_LPSPI_t *)port_addr; }
const SPI_Hardware_t & hardware() { return *(const SPI_Hardware_t *)hardware_addr; }
uintptr_t port_addr;
uintptr_t hardware_addr;
//KINETISK_SPI_t & port() { return *(KINETISK_SPI_t *)port_addr; } //KINETISK_SPI_t & port() { return *(KINETISK_SPI_t *)port_addr; }
IMXRT_LPSPI_t * const port;
const SPI_Hardware_t * const hardware;
// IMXRT_LPSPI_t * const port;
// const SPI_Hardware_t * const hardware;


void updateCTAR(uint32_t ctar); void updateCTAR(uint32_t ctar);
uint8_t miso_pin_index = 0; uint8_t miso_pin_index = 0;

Loading…
Cancel
Save