Browse Source

Add SPI_TRANSACTION_MISMATCH_LED option

main
PaulStoffregen 10 years ago
parent
commit
af21fcd6a8
2 changed files with 57 additions and 4 deletions
  1. +13
    -0
      SPI.cpp
  2. +44
    -4
      SPI.h

+ 13
- 0
SPI.cpp View File

uint8_t SPIClass::interruptMode = 0; uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0; uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0; uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif


void SPIClass::begin() void SPIClass::begin()
{ {
uint8_t SPIClass::interruptMasksUsed = 0; uint8_t SPIClass::interruptMasksUsed = 0;
uint32_t SPIClass::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32]; uint32_t SPIClass::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
uint32_t SPIClass::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32]; uint32_t SPIClass::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif


void SPIClass::begin() void SPIClass::begin()
{ {
uint32_t n = (uint32_t)interruptName; uint32_t n = (uint32_t)interruptName;


if (n >= NVIC_NUM_INTERRUPTS) return; if (n >= NVIC_NUM_INTERRUPTS) return;

Serial.print("usingInterrupt ");
Serial.println(n);
interruptMasksUsed |= (1 << (n >> 5)); interruptMasksUsed |= (1 << (n >> 5));
interruptMask[n >> 5] |= (1 << (n & 0x1F)); interruptMask[n >> 5] |= (1 << (n & 0x1F));
Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
} }


const uint16_t SPISettings::ctar_div_table[23] = { const uint16_t SPISettings::ctar_div_table[23] = {

+ 44
- 4
SPI.h View File

// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1 #define SPI_HAS_TRANSACTION 1


// Uncomment this line to add detection of mismatched begin/end transactions.
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
// each SPI.beginTransaction(). Connect a LED to this pin. The LED will turn
// on if any mismatch is ever detected.
//#define SPI_TRANSACTION_MISMATCH_LED 5

#ifndef __SAM3X8E__ #ifndef __SAM3X8E__
#ifndef LSBFIRST #ifndef LSBFIRST
#define LSBFIRST 0 #define LSBFIRST 0
cli(); cli();
} }
} }
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 1;
#endif
SPCR = settings.spcr; SPCR = settings.spcr;
SPSR = settings.spsr; SPSR = settings.spsr;
} }
// After performing a group of transfers and releasing the chip select // After performing a group of transfers and releasing the chip select
// signal, this function allows others to access the SPI bus // signal, this function allows others to access the SPI bus
inline static void endTransaction(void) { inline static void endTransaction(void) {
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (!inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 0;
#endif
if (interruptMode > 0) { if (interruptMode > 0) {
#ifdef SPI_AVR_EIMSK #ifdef SPI_AVR_EIMSK
if (interruptMode == 1) { if (interruptMode == 1) {
static uint8_t interruptMode; // 0=none, 1=mask, 2=global static uint8_t interruptMode; // 0=none, 1=mask, 2=global
static uint8_t interruptMask; // which interrupts to mask static uint8_t interruptMask; // which interrupts to mask
static uint8_t interruptSave; // temp storage, to restore state static uint8_t interruptSave; // temp storage, to restore state
#ifdef SPI_TRANSACTION_MISMATCH_LED
static uint8_t inTransactionFlag;
#endif
}; };




if (interruptMasksUsed) { if (interruptMasksUsed) {
if (interruptMasksUsed & 0x01) { if (interruptMasksUsed & 0x01) {
interruptSave[0] = NVIC_ICER0 & interruptMask[0]; interruptSave[0] = NVIC_ICER0 & interruptMask[0];
NVIC_ICER0 = interruptMask[0];
NVIC_ICER0 = interruptSave[0];
} }
#if NVIC_NUM_INTERRUPTS > 32 #if NVIC_NUM_INTERRUPTS > 32
if (interruptMasksUsed & 0x02) { if (interruptMasksUsed & 0x02) {
interruptSave[1] = NVIC_ICER1 & interruptMask[1]; interruptSave[1] = NVIC_ICER1 & interruptMask[1];
NVIC_ICER1 = interruptMask[1];
NVIC_ICER1 = interruptSave[1];
} }
#endif #endif
#if NVIC_NUM_INTERRUPTS > 64 && defined(NVIC_ISER2) #if NVIC_NUM_INTERRUPTS > 64 && defined(NVIC_ISER2)
if (interruptMasksUsed & 0x04) { if (interruptMasksUsed & 0x04) {
interruptSave[2] = NVIC_ICER2 & interruptMask[2]; interruptSave[2] = NVIC_ICER2 & interruptMask[2];
NVIC_ICER2 = interruptMask[2];
NVIC_ICER2 = interruptSave[2];
} }
#endif #endif
#if NVIC_NUM_INTERRUPTS > 96 && defined(NVIC_ISER3) #if NVIC_NUM_INTERRUPTS > 96 && defined(NVIC_ISER3)
if (interruptMasksUsed & 0x08) { if (interruptMasksUsed & 0x08) {
interruptSave[3] = NVIC_ICER3 & interruptMask[3]; interruptSave[3] = NVIC_ICER3 & interruptMask[3];
NVIC_ICER3 = interruptMask[3];
NVIC_ICER3 = interruptSave[3];
} }
#endif #endif
} }
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 1;
#endif
if (SPI0_CTAR0 != settings.ctar) { if (SPI0_CTAR0 != settings.ctar) {
SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
SPI0_CTAR0 = settings.ctar; SPI0_CTAR0 = settings.ctar;
// After performing a group of transfers and releasing the chip select // After performing a group of transfers and releasing the chip select
// signal, this function allows others to access the SPI bus // signal, this function allows others to access the SPI bus
inline static void endTransaction(void) { inline static void endTransaction(void) {
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (!inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 0;
#endif
if (interruptMasksUsed) { if (interruptMasksUsed) {
if (interruptMasksUsed & 0x01) { if (interruptMasksUsed & 0x01) {
NVIC_ISER0 = interruptSave[0]; NVIC_ISER0 = interruptSave[0];
static uint8_t interruptMasksUsed; static uint8_t interruptMasksUsed;
static uint32_t interruptMask[(NVIC_NUM_INTERRUPTS+31)/32]; static uint32_t interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
static uint32_t interruptSave[(NVIC_NUM_INTERRUPTS+31)/32]; static uint32_t interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
#ifdef SPI_TRANSACTION_MISMATCH_LED
static uint8_t inTransactionFlag;
#endif
}; };





Loading…
Cancel
Save