Parcourir la source

Merge pull request #57 from KurtE/T41-T40-Pin-Diffs

T4.1 - Pins different than T4.0 and SPI2
main
Paul Stoffregen il y a 4 ans
Parent
révision
5d389037ab
Aucun compte lié à l'adresse e-mail de l'auteur
2 fichiers modifiés avec 196 ajouts et 36 suppressions
  1. +162
    -18
      SPI.cpp
  2. +34
    -18
      SPI.h

+ 162
- 18
SPI.cpp Voir le fichier

@@ -1297,9 +1297,9 @@ void SPIClass::begin()

// Set the Mux pins
//Serial.println("SPI: Set Input select registers");
hardware().sck_select_input_register = hardware().sck_select_val;
hardware().sdi_select_input_register = hardware().sdi_select_val;
hardware().sdo_select_input_register = hardware().sdo_select_val;
hardware().sck_select_input_register = hardware().sck_select_val[sck_pin_index];
hardware().miso_select_input_register = hardware().miso_select_val[miso_pin_index];
hardware().mosi_select_input_register = hardware().mosi_select_val[mosi_pin_index];

//digitalWriteFast(10, HIGH);
//pinMode(10, OUTPUT);
@@ -1341,7 +1341,7 @@ void SPIClass::setClockDivider_noInline(uint32_t clk) {
div =0;
}

_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2);
_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2) | LPSPI_CCR_PCSSCK(div/2);

}
//Serial.printf("SPI.setClockDivider_noInline CCR:%x TCR:%x\n", _ccr, port().TCR);
@@ -1355,16 +1355,22 @@ void SPIClass::setClockDivider_noInline(uint32_t clk) {
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;
if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
}
return 0;
}

bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
{
return false; // only one CS defined
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;
}


bool SPIClass::pinIsMOSI(uint8_t pin)
{
for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
@@ -1394,8 +1400,10 @@ uint8_t SPIClass::setCS(uint8_t pin)
{
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;
*(portConfigRegister(pin)) = hardware().cs_mux[i];
if (hardware().pcs_select_input_register[i])
*hardware().pcs_select_input_register[i] = hardware().pcs_select_val[i];
return hardware().cs_mask[i];
}
}
return 0;
@@ -1403,17 +1411,59 @@ uint8_t SPIClass::setCS(uint8_t pin)

void SPIClass::setMOSI(uint8_t pin)
{
// Currently only one defined so just return...
if (pin != hardware().mosi_pin[mosi_pin_index]) {
for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
if (pin == hardware().mosi_pin[i] ) {
if (hardware().clock_gate_register & hardware().clock_gate_mask) {
// BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
*(portControlRegister(hardware().mosi_pin[i])) = fastio;
*(portConfigRegister(hardware().mosi_pin [i])) = hardware().mosi_mux[i];
hardware().mosi_select_input_register = hardware().mosi_select_val[i];
}
mosi_pin_index = i;
return;
}
}
}
}

void SPIClass::setMISO(uint8_t pin)
{
// Currently only one defined so just return...
if (pin != hardware().miso_pin[miso_pin_index]) {
for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
if (pin == hardware().miso_pin[i] ) {
if (hardware().clock_gate_register & hardware().clock_gate_mask) {
// BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
*(portControlRegister(hardware().miso_pin[i])) = fastio;
*(portConfigRegister(hardware().miso_pin[i])) = hardware().miso_mux[i];
hardware().miso_select_input_register = hardware().miso_select_val[i];
}
miso_pin_index = i;
return;
}
}
}
}

void SPIClass::setSCK(uint8_t pin)
{
// Currently only one defined so just return...
if (pin != hardware().sck_pin[sck_pin_index]) {
for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
if (pin == hardware().sck_pin[i] ) {
if (hardware().clock_gate_register & hardware().clock_gate_mask) {
// BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
*(portControlRegister(hardware().sck_pin[i])) = fastio;
*(portConfigRegister(hardware().sck_pin [i])) = hardware().sck_mux[i];
hardware().sck_select_input_register = hardware().sck_select_val[i];
}
sck_pin_index = i;
return;
}
}
}
}


@@ -1449,21 +1499,53 @@ void SPIClass::setDataMode(uint8_t dataMode)

void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}

// NOTE pin definitions are in the order MISO, MOSI, SCK, CS
// With each group, having pin number[n], setting[n], INPUT_SELECT_MUX settings[n], SELECT INPUT register
#if defined(ARDUINO_TEENSY41)
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0,
12, 255, // MISO
3 | 0x10, 0,
0, 0,
IOMUXC_LPSPI4_SDI_SELECT_INPUT,
11, 255, // MOSI
3 | 0x10, 0,
0, 0,
IOMUXC_LPSPI4_SDO_SELECT_INPUT,
13, 255, // SCK
3 | 0x10, 0,
0, 0,
IOMUXC_LPSPI4_SCK_SELECT_INPUT,
10, 37, 36, // CS
3 | 0x10, 2 | 0x10, 2 | 0x10,
1, 2, 3,
0, 0, 0,
&IOMUXC_LPSPI4_PCS0_SELECT_INPUT, 0, 0
};
#else
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0,
12,
3 | 0x10,
0,
IOMUXC_LPSPI4_SDI_SELECT_INPUT,
11,
3 | 0x10,
0,
IOMUXC_LPSPI4_SDO_SELECT_INPUT,
13,
3 | 0x10,
0,
IOMUXC_LPSPI4_SCK_SELECT_INPUT,
10,
3 | 0x10,
IOMUXC_LPSPI4_SCK_SELECT_INPUT, IOMUXC_LPSPI4_SDI_SELECT_INPUT, IOMUXC_LPSPI4_SDO_SELECT_INPUT, IOMUXC_LPSPI4_PCS0_SELECT_INPUT,
0, 0, 0, 0
1,
0,
&IOMUXC_LPSPI4_PCS0_SELECT_INPUT
};

#endif

SPIClass SPI((uintptr_t)&IMXRT_LPSPI4_S, (uintptr_t)&SPIClass::spiclass_lpspi4_hardware);

@@ -1471,38 +1553,100 @@ SPIClass SPI((uintptr_t)&IMXRT_LPSPI4_S, (uintptr_t)&SPIClass::spiclass_lpspi4_h
// T4 has two other possible SPI objects...
void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}

#if defined(ARDUINO_TEENSY41)
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi3_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI3(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI3_TX, DMAMUX_SOURCE_LPSPI3_RX, _spi_dma_rxISR1,
1, 39,
7 | 0x10, 2 | 0x10,
0, 1,
IOMUXC_LPSPI3_SDI_SELECT_INPUT,
26, 255,
2 | 0x10, 0,
1, 0,
IOMUXC_LPSPI3_SDO_SELECT_INPUT,
27, 255,
2 | 0x10, 0,
1, 0,
IOMUXC_LPSPI3_SCK_SELECT_INPUT,
0, 38, 255,
7 | 0x10, 2 | 0x10, 0,
1, 1, 0,
0, 1, 0,
&IOMUXC_LPSPI3_PCS0_SELECT_INPUT, &IOMUXC_LPSPI3_PCS0_SELECT_INPUT, 0
};
#else
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi3_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI3(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI3_TX, DMAMUX_SOURCE_LPSPI3_RX, _spi_dma_rxISR1,
1,
7 | 0x10,
0,
IOMUXC_LPSPI3_SDI_SELECT_INPUT,
26,
2 | 0x10,
1,
IOMUXC_LPSPI3_SDO_SELECT_INPUT,
27,
2 | 0x10,
1,
IOMUXC_LPSPI3_SCK_SELECT_INPUT,
0,
7 | 0x10,
IOMUXC_LPSPI3_SCK_SELECT_INPUT, IOMUXC_LPSPI3_SDI_SELECT_INPUT, IOMUXC_LPSPI3_SDO_SELECT_INPUT, IOMUXC_LPSPI3_PCS0_SELECT_INPUT,
1, 0, 1, 0
1,
0,
&IOMUXC_LPSPI3_PCS0_SELECT_INPUT
};
#endif
SPIClass SPI1((uintptr_t)&IMXRT_LPSPI3_S, (uintptr_t)&SPIClass::spiclass_lpspi3_hardware);

void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}

#if defined(ARDUINO_TEENSY41)
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi1_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI1(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI1_TX, DMAMUX_SOURCE_LPSPI1_RX, _spi_dma_rxISR1,
42, 54,
4 | 0x10, 3 | 0x10,
1, 0,
IOMUXC_LPSPI1_SDI_SELECT_INPUT,
43, 50,
4 | 0x10, 3 | 0x10,
1, 0,
IOMUXC_LPSPI1_SDO_SELECT_INPUT,
45, 49,
4 | 0x10, 3 | 0x10,
1, 0,
IOMUXC_LPSPI1_SCK_SELECT_INPUT,
44, 255, 255,
4 | 0x10, 0, 0,
1, 0, 0,
0, 0, 0,
&IOMUXC_LPSPI1_PCS0_SELECT_INPUT, 0, 0
};
#else
const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi1_hardware = {
CCM_CCGR1, CCM_CCGR1_LPSPI1(CCM_CCGR_ON),
DMAMUX_SOURCE_LPSPI1_TX, DMAMUX_SOURCE_LPSPI1_RX, _spi_dma_rxISR1,
34,
4 | 0x10,
1,
IOMUXC_LPSPI1_SDI_SELECT_INPUT,
35,
4 | 0x10,
1,
IOMUXC_LPSPI1_SDO_SELECT_INPUT,
37,
4 | 0x10,
1,
IOMUXC_LPSPI1_SCK_SELECT_INPUT,
36,
4 | 0x10,
IOMUXC_LPSPI1_SCK_SELECT_INPUT, IOMUXC_LPSPI1_SDI_SELECT_INPUT, IOMUXC_LPSPI1_SDO_SELECT_INPUT, IOMUXC_LPSPI1_PCS0_SELECT_INPUT,
1, 1, 1, 0
1,
0,
&IOMUXC_LPSPI1_PCS0_SELECT_INPUT
};
#endif
SPIClass SPI2((uintptr_t)&IMXRT_LPSPI1_S, (uintptr_t)&SPIClass::spiclass_lpspi1_hardware);
#endif


+ 34
- 18
SPI.h Voir le fichier

@@ -1068,33 +1068,49 @@ private:

class SPIClass { // Teensy 4
public:
#if defined(ARDUINO_TEENSY41)
// T4.1 has SPI2 pins on memory connectors as well as SDCard
static const uint8_t CNT_MISO_PINS = 2;
static const uint8_t CNT_MOSI_PINS = 2;
static const uint8_t CNT_SCK_PINS = 2;
static const uint8_t CNT_CS_PINS = 3;
#else
static const uint8_t CNT_MISO_PINS = 1;
static const uint8_t CNT_MOSI_PINS = 1;
static const uint8_t CNT_SCK_PINS = 1;
static const uint8_t CNT_CS_PINS = 1;
#endif
typedef struct {
volatile uint32_t &clock_gate_register;
const uint32_t clock_gate_mask;
uint8_t tx_dma_channel;
uint8_t rx_dma_channel;
void (*dma_rxisr)();
const uint8_t miso_pin[CNT_MISO_PINS];
const uint32_t miso_mux[CNT_MISO_PINS];
const uint8_t mosi_pin[CNT_MOSI_PINS];
const uint32_t mosi_mux[CNT_MOSI_PINS];
const uint8_t sck_pin[CNT_SCK_PINS];
const uint32_t sck_mux[CNT_SCK_PINS];
const uint8_t cs_pin[CNT_CS_PINS];
const uint32_t cs_mux[CNT_CS_PINS];

volatile uint32_t &sck_select_input_register;
volatile uint32_t &sdi_select_input_register;
volatile uint32_t &sdo_select_input_register;
volatile uint32_t &pcs0_select_input_register;
const uint8_t sck_select_val;
const uint8_t sdi_select_val;
const uint8_t sdo_select_val;
const uint8_t pcs0_select_val;
// MISO pins
const uint8_t miso_pin[CNT_MISO_PINS];
const uint32_t miso_mux[CNT_MISO_PINS];
const uint8_t miso_select_val[CNT_MISO_PINS];
volatile uint32_t &miso_select_input_register;

// MOSI pins
const uint8_t mosi_pin[CNT_MOSI_PINS];
const uint32_t mosi_mux[CNT_MOSI_PINS];
const uint8_t mosi_select_val[CNT_MOSI_PINS];
volatile uint32_t &mosi_select_input_register;

// SCK pins
const uint8_t sck_pin[CNT_SCK_PINS];
const uint32_t sck_mux[CNT_SCK_PINS];
const uint8_t sck_select_val[CNT_SCK_PINS];
volatile uint32_t &sck_select_input_register;

// CS Pins
const uint8_t cs_pin[CNT_CS_PINS];
const uint32_t cs_mux[CNT_CS_PINS];
const uint8_t cs_mask[CNT_CS_PINS];
const uint8_t pcs_select_val[CNT_CS_PINS];
volatile uint32_t *pcs_select_input_register[CNT_CS_PINS];

} SPI_Hardware_t;
static const SPI_Hardware_t spiclass_lpspi4_hardware;
#if defined(__IMXRT1062__)
@@ -1205,7 +1221,7 @@ public:
div =0;
}
_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2);
_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2) | LPSPI_CCR_PCSSCK(div/2);

}
//Serial.printf("SPI.beginTransaction CCR:%x TCR:%x\n", _ccr, settings.tcr);

Chargement…
Annuler
Enregistrer