Browse Source

Merge pull request #48 from KurtE/T4_SPISettings_calc

T4 SPISettings - just hold values passed in
main
Paul Stoffregen 5 years ago
parent
commit
ab5b6b29a5
No account linked to committer's email address
1 changed files with 52 additions and 47 deletions
  1. +52
    -47
      SPI.h

+ 52
- 47
SPI.h View File

@@ -1033,60 +1033,35 @@ private:

//#include "debug/printf.h"

// TODO......
//#undef SPI_HAS_TRANSFER_ASYNC

class SPISettings {
public:
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
SPISettings(uint32_t clockIn, uint8_t bitOrderIn, uint8_t dataModeIn) : _clock(clockIn) {
init_AlwaysInline(bitOrderIn, dataModeIn);
}
SPISettings() {
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);

SPISettings() : _clock(4000000) {
init_AlwaysInline(MSBFIRST, SPI_MODE0);
}
private:
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
void init_AlwaysInline(uint8_t bitOrder, uint8_t dataMode)
__attribute__((__always_inline__)) {
// TODO: Need to check timings as related to chip selects?
const uint32_t clk_sel[4] = {664615384, // PLL3 PFD1
720000000, // PLL3 PFD0
528000000, // PLL2
396000000}; // PLL2 PFD2
uint32_t cbcmr = CCM_CBCMR;
uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1); // LPSPI peripheral clock
uint32_t d, div;
if (clock == 0) clock =1;
d= clkhz/clock;
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);
tcr = LPSPI_TCR_FRAMESZ(7); // TCR has polarity and bit order too
tcr = LPSPI_TCR_FRAMESZ(7); // TCR has polarity and bit order too

// handle LSB setup
if (bitOrder == LSBFIRST) tcr |= LPSPI_TCR_LSBF;
// handle LSB setup
if (bitOrder == LSBFIRST) tcr |= LPSPI_TCR_LSBF;

// Handle Data Mode
if (dataMode & 0x08) tcr |= LPSPI_TCR_CPOL;
// Handle Data Mode
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;
// 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;
}
uint32_t ccr; // clock config, pg 2660 (RT1050 ref, rev 2)

inline uint32_t clock() {return _clock;}

uint32_t _clock;
uint32_t tcr; // transmit command, pg 2664 (RT1050 ref, rev 2)
friend class SPIClass;
};
@@ -1203,13 +1178,39 @@ public:
#endif

//printf("trans\n");
if (settings.clock() != _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 = settings.clock();

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.beginTransaction CCR:%x TCR:%x\n", _ccr, settings.tcr);
port().CR = 0;
port().CFGR1 = LPSPI_CFGR1_MASTER | LPSPI_CFGR1_SAMPLE;
port().CCR = settings.ccr;
port().CCR = _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)
@@ -1264,6 +1265,7 @@ public:
if (interruptMasksUsed & 0x08) NVIC_ISER3 = interruptSave[3];
if (interruptMasksUsed & 0x10) NVIC_ISER4 = interruptSave[4];
}
//Serial.printf("SPI.endTransaction CCR:%x TCR:%x\n", port().CCR, port().TCR);
}

// Disable the SPI bus
@@ -1327,10 +1329,13 @@ private:
const SPI_Hardware_t & hardware() { return *(const SPI_Hardware_t *)hardware_addr; }
uintptr_t port_addr;
uintptr_t hardware_addr;

uint32_t _clock = 0;
uint32_t _ccr = 0;

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

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

Loading…
Cancel
Save