Browse Source

Add Teensy 3.x chip select pin functions and transfer16() for AVR

main
PaulStoffregen 10 years ago
parent
commit
467f99149d
2 changed files with 59 additions and 1 deletions
  1. +33
    -0
      SPI.cpp
  2. +26
    -1
      SPI.h

+ 33
- 0
SPI.cpp View File

@@ -213,6 +213,39 @@ void SPIClass::setClockDivider_noInline(uint32_t clk)
updateCTAR(ctar);
}

bool SPIClass::pinIsChipSelect(uint8_t pin)
{
if (pin == 10 || pin == 9 || pin == 6 || pin == 2 || pin == 15) return true;
if (pin >= 20 && pin <= 23) return true;
return false;
}

bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
{
if (!pinIsChipSelect(pin1) || !pinIsChipSelect(pin2)) return false;
if ((pin1 == 2 && pin2 == 10) || (pin1 == 10 && pin2 == 2)) return false;
if ((pin1 == 6 && pin2 == 9) || (pin1 == 9 && pin2 == 6)) return false;
if ((pin1 == 20 && pin2 == 23) || (pin1 == 23 && pin2 == 20)) return false;
if ((pin1 == 21 && pin2 == 22) || (pin1 == 22 && pin2 == 21)) return false;
return true;
}

uint8_t SPIClass::setCS(uint8_t pin)
{
switch (pin) {
case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
case 9: CORE_PIN9_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTC3
case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTD4
case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTD5
case 23: CORE_PIN23_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTC2
case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTD6
case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1
case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0
}
return 0;
}


#endif


+ 26
- 1
SPI.h View File

@@ -183,6 +183,26 @@ public:
while (!(SPSR & _BV(SPIF))) ; // wait
return SPDR;
}
inline static uint16_t transfer16(uint16_t data) {
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
if (!(SPCR & _BV(DORD))) {
SPDR = in.msb;
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
SPDR = in.lsb;
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
} else {
SPDR = in.lsb;
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
SPDR = in.msb;
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
}
return out.val;
}
inline static void transfer(void *buf, size_t count) {
if (count == 0) return;
uint8_t *p = (uint8_t *)buf;
@@ -423,7 +443,6 @@ public:
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
inline static uint8_t transfer(uint8_t data) {
SPDR = data;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ; // wait
return SPDR;
}
@@ -505,6 +524,12 @@ public:
inline static void setSCK(uint8_t pin) __attribute__((always_inline)) {
SPCR.setSCK(pin);
}
// return true if "pin" has special chip select capability
static bool pinIsChipSelect(uint8_t pin);
// return true if both pin1 and pin2 have independent chip select capability
static bool pinIsChipSelect(uint8_t pin1, uint8_t pin2);
// configure a pin for chip select and return its SPI_MCR_PCSIS bitmask
static uint8_t setCS(uint8_t pin);

private:
static uint8_t interruptMode; // 0=none, 1=mask, 2=global

Loading…
Cancel
Save