Skip to content

Commit 17cf18b

Browse files
committed
T4.x - Software SPI - don't use FAST_PINIO
The original problem was that the code defined the registers and mask as 8 bits, when the T4.x ones are 32 bits. So it only worked on a subset of pins. So first fix would be to simply define these values as 32 bits. But doing so leaves you code at risk as the Set/Clear code in this library is not atomic, Example: *clkPort |= clkPinMask; So if something happens in the small time window after the time the register is retrieved and then manipulated and written back, such as an interrupt. Or maybe if other hardware is driving the pin. These changes would be clobbered by the above code. Not sure how many other boards (if any) may be hit by the same issue. It is not an issue with T3.x as the Teensy code uses the M3/M4 bitband support, so for each pin there is a unique memory address for it and these operations are atomic. Note: the Arm M7 does not support bitbands. However in these caseAtomic code can be written for the T4.x by instead using the DR register of the IO port, you use the DR_SET, DR_CLEAR, DR_TOGGLE registers instead which do as the names imply the do that operation only those pins who have a 1 bit set to the value...
1 parent 4ca0493 commit 17cf18b

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

Adafruit_SPIDevice.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ typedef enum _BitOrder {
3939
typedef BitOrder BusIOBitOrder;
4040
#endif
4141

42-
#if defined(__AVR__) || defined(TEENSYDUINO)
42+
#if defined(__IMXRT1062__) // Teensy 4.x
43+
// *Warning* I disabled the usage of FAST_PINIO as the set/clear operations
44+
// used in the cpp file are not atomic and can effect multiple IO pins
45+
// and if an interrupt happens in between the time the code reads the register
46+
// and writes out the updated value, that changes one or more other IO pins
47+
// on that same IO port, those change will be clobbered when the updated
48+
// values are written back. A fast version can be implemented that uses the
49+
// ports set and clear registers which are atomic.
50+
// typedef volatile uint32_t BusIO_PortReg;
51+
// typedef uint32_t BusIO_PortMask;
52+
//#define BUSIO_USE_FAST_PINIO
53+
54+
#elif defined(__AVR__) || defined(TEENSYDUINO)
4355
typedef volatile uint8_t BusIO_PortReg;
4456
typedef uint8_t BusIO_PortMask;
4557
#define BUSIO_USE_FAST_PINIO

0 commit comments

Comments
 (0)