The code would fail if the user did an SPI.transfer without calling SPI.beginTransaction. So begin now calls beginTransaction with default parameters. Also put in an implemention for SPI.setClockDivider as well as SPI.setDataMode They appear to work OK... Tried to do with out changing any of the current functionality other than to call begin/end transaction in begin to get to a stable state.main
// 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); | ||||
// We should initialize the SPI to be in a known default state. | |||||
beginTransaction(SPISettings()); | |||||
endTransaction(); | |||||
} | |||||
void SPIClass::setClockDivider_noInline(uint32_t clk) { | |||||
// Again depreciated, but... | |||||
hardware().clock_gate_register |= hardware().clock_gate_mask; | |||||
if (clk != _clock) { | |||||
static const uint32_t clk_sel[4] = {664615384, // PLL3 PFD1 | |||||
720000000, // PLL3 PFD0 | |||||
528000000, // PLL2 | |||||
396000000}; // PLL2 PFD2 | |||||
// First save away the new settings.. | |||||
_clock = clk; | |||||
uint32_t cbcmr = CCM_CBCMR; | |||||
uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1); // LPSPI peripheral clock | |||||
uint32_t d, div; | |||||
d = _clock ? clkhz/_clock : clkhz; | |||||
if (d && clkhz/d > _clock) d++; | |||||
if (d > 257) d= 257; // max div | |||||
if (d > 2) { | |||||
div = d-2; | |||||
} else { | |||||
div =0; | |||||
} | |||||
_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2); | |||||
} | |||||
//Serial.printf("SPI.setClockDivider_noInline CCR:%x TCR:%x\n", _ccr, port().TCR); | |||||
port().CR = 0; | |||||
port().CFGR1 = LPSPI_CFGR1_MASTER | LPSPI_CFGR1_SAMPLE; | |||||
port().CCR = _ccr; | |||||
port().CR = LPSPI_CR_MEN; | |||||
} | } | ||||
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++) { | for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) { | ||||
{ | { | ||||
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; | ||||
// Handle Data Mode | |||||
uint32_t tcr = port().TCR & ~(LPSPI_TCR_CPOL | LPSPI_TCR_CPHA); | |||||
if (dataMode & 0x08) tcr |= LPSPI_TCR_CPOL; | |||||
// Note: On T3.2 when we set CPHA it also updated the timing. It moved the | |||||
// PCS to SCK Delay Prescaler into the After SCK Delay Prescaler | |||||
if (dataMode & 0x04) tcr |= LPSPI_TCR_CPHA; | |||||
// Save back out | |||||
port().TCR = tcr; | |||||
} | } | ||||
void _spi_dma_rxISR0(void) {SPI.dma_rxisr();} | void _spi_dma_rxISR0(void) {SPI.dma_rxisr();} |
// beginTransaction() to configure SPI settings. | // beginTransaction() to configure SPI settings. | ||||
void setClockDivider(uint8_t clockDiv) { | void setClockDivider(uint8_t clockDiv) { | ||||
if (clockDiv == SPI_CLOCK_DIV2) { | if (clockDiv == SPI_CLOCK_DIV2) { | ||||
//setClockDivider_noInline(SPISettings(12000000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(12000000); | |||||
} else if (clockDiv == SPI_CLOCK_DIV4) { | } else if (clockDiv == SPI_CLOCK_DIV4) { | ||||
//setClockDivider_noInline(SPISettings(4000000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(4000000); | |||||
} else if (clockDiv == SPI_CLOCK_DIV8) { | } else if (clockDiv == SPI_CLOCK_DIV8) { | ||||
//setClockDivider_noInline(SPISettings(2000000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(2000000); | |||||
} else if (clockDiv == SPI_CLOCK_DIV16) { | } else if (clockDiv == SPI_CLOCK_DIV16) { | ||||
//setClockDivider_noInline(SPISettings(1000000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(1000000); | |||||
} else if (clockDiv == SPI_CLOCK_DIV32) { | } else if (clockDiv == SPI_CLOCK_DIV32) { | ||||
//setClockDivider_noInline(SPISettings(500000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(500000); | |||||
} else if (clockDiv == SPI_CLOCK_DIV64) { | } else if (clockDiv == SPI_CLOCK_DIV64) { | ||||
//setClockDivider_noInline(SPISettings(250000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(250000); | |||||
} else { /* clockDiv == SPI_CLOCK_DIV128 */ | } else { /* clockDiv == SPI_CLOCK_DIV128 */ | ||||
//setClockDivider_noInline(SPISettings(125000, MSBFIRST, SPI_MODE0).ctar); | |||||
setClockDivider_noInline(125000); | |||||
} | } | ||||
} | } | ||||
void setClockDivider_noInline(uint32_t clk); | void setClockDivider_noInline(uint32_t clk); |