Add new scene controller with touch display example.
Upgraded RF24 to latest version which supports SoftSPI. Added DigitalIO and UTFT libraries to support the new example. Fix problem reported in RelayWithButtonActuator example.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#ifndef ADS7818_h
|
||||
#define ADS7871_h
|
||||
//------------------------------------------------------------------------------
|
||||
/** nop to tune soft SPI timing */
|
||||
#define nop asm volatile ("nop\n\t")
|
||||
//------------------------------------------------------------------------------
|
||||
/** doxygen can't handle __attribute__ very well */
|
||||
#define STATIC_ALWAYS_INLINE static inline __attribute__((always_inline))
|
||||
//------------------------------------------------------------------------------
|
||||
template<uint8_t ClkPin, uint8_t ConvPin, uint8_t DataPin>
|
||||
class ADS7818 {
|
||||
public:
|
||||
void begin() {
|
||||
fastPinMode(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
fastPinMode(ConvPin, 1);
|
||||
fastDigitalWrite(ConvPin, 1);
|
||||
fastPinMode(DataPin, 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
uint16_t read() {
|
||||
uint16_t v = 0;
|
||||
fastDigitalWrite(ConvPin, 0);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
fastDigitalWrite(ConvPin, 1);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
|
||||
readBitFast16(v, 11);
|
||||
readBitFast16(v, 10);
|
||||
readBitFast16(v, 9);
|
||||
readBitFast16(v, 8);
|
||||
readBitFast16(v, 7);
|
||||
readBitFast16(v, 6);
|
||||
readBitFast16(v, 5);
|
||||
readBitFast16(v, 4);
|
||||
readBitFast16(v, 3);
|
||||
readBitFast16(v, 2);
|
||||
readBitFast16(v, 1);
|
||||
readBitFast16(v, 0);
|
||||
return v;
|
||||
}
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void readBitFast16(uint16_t &v, uint8_t b) {
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
if (fastDigitalRead(DataPin)) v |= (1 << b);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
};
|
||||
#if 0
|
||||
/** initialize I/O ports */
|
||||
STATIC_ALWAYS_INLINE void adcBegin() {
|
||||
fastPinMode(ADC_CLK_PIN, 1);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 0);
|
||||
fastPinMode(ADC_CONV_PIN, 1);
|
||||
fastDigitalWrite(ADC_CONV_PIN, 1);
|
||||
fastPinMode(ADC_DATA_PIN, 0);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/** clock for don't care bits
|
||||
*\param[in] delayBefore if true, delay before raising clock*/
|
||||
STATIC_ALWAYS_INLINE void fastDummy(bool first) {
|
||||
if (!first) nop;
|
||||
fastDigitalWrite(ADC_CLK_PIN, 1);
|
||||
nop;
|
||||
fastDigitalWrite(ADC_CLK_PIN, 0);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/** read next bit fast as possible
|
||||
* \param[in] v word to receive bit
|
||||
* \param[in] b bit number to be set. v |= (1 << b) if next bit is high.
|
||||
*/
|
||||
STATIC_ALWAYS_INLINE void readBitFast16(uint16_t &v, uint8_t b) {
|
||||
fastDigitalWrite(ADC_CLK_PIN, 1);
|
||||
if (fastDigitalRead(ADC_DATA_PIN)) v |= (1 << b);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 0);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/** Read AD7680 16-bit ADC in less than 8 microseconds
|
||||
* cs is chip select pin
|
||||
*/
|
||||
STATIC_ALWAYS_INLINE uint16_t adcRead(bool centered = false) {
|
||||
uint16_t v = 0;
|
||||
fastDigitalWrite(ADC_CONV_PIN, 0);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 1);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 0);
|
||||
fastDigitalWrite(ADC_CONV_PIN, 1);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 1);
|
||||
fastDigitalWrite(ADC_CLK_PIN, 0);
|
||||
// uint16_t v = 0;
|
||||
|
||||
// fastDummy(1);
|
||||
// fastDummy(0);
|
||||
// fastDummy(0);
|
||||
// fastDummy(0);
|
||||
|
||||
// readBitFast16(v, 15);
|
||||
// readBitFast16(v, 14);
|
||||
// readBitFast16(v, 13);
|
||||
// readBitFast16(v, 12);
|
||||
readBitFast16(v, 11);
|
||||
readBitFast16(v, 10);
|
||||
readBitFast16(v, 9);
|
||||
readBitFast16(v, 8);
|
||||
readBitFast16(v, 7);
|
||||
readBitFast16(v, 6);
|
||||
readBitFast16(v, 5);
|
||||
readBitFast16(v, 4);
|
||||
readBitFast16(v, 3);
|
||||
readBitFast16(v, 2);
|
||||
readBitFast16(v, 1);
|
||||
readBitFast16(v, 0);
|
||||
return centered ? v ^ 0X8000 : v;
|
||||
}
|
||||
#endif // 0
|
||||
#endif // ADS7818_h
|
||||
@@ -0,0 +1,259 @@
|
||||
#ifndef MCP320X_h
|
||||
#define MCP320X_h
|
||||
#include <DigitalIO.h>
|
||||
//==============================================================================
|
||||
template<uint8_t CsPin, uint8_t ClkPin, uint8_t DoutPin, uint8_t UsecDelay = 0>
|
||||
class MCP3201 {
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
/** Set pin modes and initial levels. */
|
||||
void begin() {
|
||||
fastPinMode(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
fastPinMode(CsPin, 1);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
fastPinMode(DoutPin, 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** Read MCP3201 12-bit ADC
|
||||
* \return 16-bit value read.
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
uint16_t read() {
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
// Start sample.
|
||||
mcpAdcDummy(3);
|
||||
// Extra sample time.
|
||||
if (UsecDelay){
|
||||
delayMicroseconds(UsecDelay);
|
||||
}
|
||||
// End sample.
|
||||
mcpAdcDummy(3);
|
||||
// Null bit.
|
||||
mcpAdcDummy(3);
|
||||
uint16_t v = 0;
|
||||
readBit(v, 11);
|
||||
readBit(v, 10);
|
||||
readBit(v, 9);
|
||||
readBit(v, 8);
|
||||
readBit(v, 7);
|
||||
readBit(v, 6);
|
||||
readBit(v, 5);
|
||||
readBit(v, 4);
|
||||
readBit(v, 3);
|
||||
readBit(v, 2);
|
||||
readBit(v, 1);
|
||||
readBit(v, 0);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
return v;
|
||||
}
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
/** delay n nops
|
||||
* \param[in] n nops to delay, must be a constant so compiler optimizes if().
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
void delayCycles(uint8_t n) {
|
||||
if (n & 1) asm volatile("nop\n\t");
|
||||
if (n & 2) asm volatile("nop\n\t" "nop\n\t");
|
||||
if (n & 4) asm volatile("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** clock for don't care bits
|
||||
*\param[in] delayBefore if true, delay before raising clock*/
|
||||
inline __attribute__((always_inline))
|
||||
void mcpAdcDummy(uint8_t delayBefore) {
|
||||
delayCycles(delayBefore);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(3);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void readBit(uint16_t &v, uint8_t b, uint8_t delayRead = 2) {
|
||||
delayCycles(3);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(delayRead);
|
||||
if (fastDigitalRead(DoutPin)) v |= (1 << b);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
};
|
||||
//==============================================================================
|
||||
template<uint8_t CsPin, uint8_t ClkPin,
|
||||
uint8_t DoutPin, uint8_t DinPin, uint8_t UsecDelay = 0>
|
||||
class MCP3202 {
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
/** Set pin modes and initial levels. */
|
||||
void begin() {
|
||||
fastPinMode(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
fastPinMode(CsPin, 1);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
fastPinMode(DoutPin, 0);
|
||||
fastPinMode(DinPin, 1);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** Read MCP3202 12-bit ADC
|
||||
* \return 16-bit value read.
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
uint16_t read(uint8_t config) {
|
||||
uint16_t v = 0;
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
// Start bit.
|
||||
writeBit(true);
|
||||
// Mode bit.
|
||||
writeBit(config & 2);
|
||||
// Channel Selection and start sample.
|
||||
writeBit(config & 1);
|
||||
// Extra sample time.
|
||||
if (UsecDelay){
|
||||
delayMicroseconds(UsecDelay);
|
||||
}
|
||||
// MSB first format and end sample.
|
||||
writeBit(true);
|
||||
// Null bit.
|
||||
writeBit(true);
|
||||
// Data bits.
|
||||
readBit(v, 11);
|
||||
readBit(v, 10);
|
||||
readBit(v, 9);
|
||||
readBit(v, 8);
|
||||
readBit(v, 7);
|
||||
readBit(v, 6);
|
||||
readBit(v, 5);
|
||||
readBit(v, 4);
|
||||
readBit(v, 3);
|
||||
readBit(v, 2);
|
||||
readBit(v, 1);
|
||||
readBit(v, 0);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
return v;
|
||||
}
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
/** delay n nops
|
||||
* \param[in] n nops to delay, must be a constant so compiler optimizes if().
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
void delayCycles(uint8_t n) {
|
||||
if (n & 1) asm volatile("nop\n\t");
|
||||
if (n & 2) asm volatile("nop\n\t" "nop\n\t");
|
||||
if (n & 4) asm volatile("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** clock for don't care bits
|
||||
*\param[in] delayBefore if true, delay before raising clock*/
|
||||
inline __attribute__((always_inline))
|
||||
void writeBit(bool value) {
|
||||
fastDigitalWrite(DinPin, value);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(2);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void readBit(uint16_t &v, uint8_t b, uint8_t delayRead = 1) {
|
||||
delayCycles(2);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(delayRead);
|
||||
if (fastDigitalRead(DoutPin)) v |= (1 << b);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
};
|
||||
//==============================================================================
|
||||
template<uint8_t CsPin, uint8_t ClkPin,
|
||||
uint8_t DoutPin, uint8_t DinPin, uint8_t UsecDelay = 0>
|
||||
class MCP3204 {
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
/** Set pin modes and initial levels. */
|
||||
void begin() {
|
||||
fastPinMode(ClkPin, 1);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
fastPinMode(CsPin, 1);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
fastPinMode(DoutPin, 0);
|
||||
fastPinMode(DinPin, 1);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** Read MCP3204 12-bit ADC
|
||||
* \return 16-bit value read.
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
uint16_t read(uint8_t config) {
|
||||
uint16_t v = 0;
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
// Start bit.
|
||||
writeBit(true);
|
||||
// Mode bit.
|
||||
writeBit(config & 8);
|
||||
// D2 channel bit.
|
||||
writeBit(config & 4);
|
||||
// D1 channel bit.
|
||||
writeBit(config & 2);
|
||||
// D0 channel bit and start sample.
|
||||
writeBit(config & 1);
|
||||
// Extra sample time.
|
||||
if (UsecDelay){
|
||||
delayMicroseconds(UsecDelay);
|
||||
}
|
||||
// End sample cycle.
|
||||
writeBit(true);
|
||||
// Null bit.
|
||||
writeBit(true);
|
||||
// Data bits.
|
||||
readBit(v, 11);
|
||||
readBit(v, 10);
|
||||
readBit(v, 9);
|
||||
readBit(v, 8);
|
||||
readBit(v, 7);
|
||||
readBit(v, 6);
|
||||
readBit(v, 5);
|
||||
readBit(v, 4);
|
||||
readBit(v, 3);
|
||||
readBit(v, 2);
|
||||
readBit(v, 1);
|
||||
readBit(v, 0);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
return v;
|
||||
}
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
/** delay n nops
|
||||
* \param[in] n nops to delay, must be a constant so compiler optimizes if().
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
void delayCycles(uint8_t n) {
|
||||
if (n & 1) asm volatile("nop\n\t");
|
||||
if (n & 2) asm volatile("nop\n\t" "nop\n\t");
|
||||
if (n & 4) asm volatile("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** clock for don't care bits
|
||||
*\param[in] delayBefore if true, delay before raising clock*/
|
||||
inline __attribute__((always_inline))
|
||||
void writeBit(bool value) {
|
||||
fastDigitalWrite(DinPin, value);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(2);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void readBit(uint16_t &v, uint8_t b, uint8_t delayRead = 1) {
|
||||
delayCycles(2);
|
||||
fastDigitalWrite(ClkPin, 1);
|
||||
delayCycles(delayRead);
|
||||
if (fastDigitalRead(DoutPin)) v |= (1 << b);
|
||||
fastDigitalWrite(ClkPin, 0);
|
||||
}
|
||||
};
|
||||
//==============================================================================
|
||||
// MCP3204 and MCP3208 use the same code.
|
||||
template<uint8_t CsPin, uint8_t ClkPin,
|
||||
uint8_t DoutPin, uint8_t DinPin, uint8_t UsecDelay = 0>
|
||||
class MCP3208 : public MCP3204<CsPin, ClkPin, DoutPin, DinPin, UsecDelay> {
|
||||
};
|
||||
#endif // MCP320X_h
|
||||
@@ -0,0 +1,126 @@
|
||||
#ifndef MCP355X_h
|
||||
#define MCP355X_h
|
||||
#include <DigitalIO.h>
|
||||
// Overflow values.
|
||||
const int32_t MCP355X_OVH = 2097152L;
|
||||
const int32_t MCP355X_OVL = -2097153L;
|
||||
const int32_t MCP355X_ERR = 0X80000000;
|
||||
const uint8_t MCP355X_TO_MS = 100;
|
||||
//==============================================================================
|
||||
template<uint8_t CsPin, uint8_t SckPin, uint8_t SdoPin>
|
||||
class MCP355X {
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
/** Set pin modes and initial levels. */
|
||||
void begin(bool singleMode = true) {
|
||||
m_singleMode = singleMode;
|
||||
fastPinMode(SdoPin, 0);
|
||||
fastPinMode(SckPin, 1);
|
||||
fastDigitalWrite(SckPin, 1);
|
||||
fastPinMode(CsPin, 1);
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
if (!m_singleMode) {
|
||||
// Wait for conversion to complete.
|
||||
delay(100);
|
||||
// Start continuous conversion mode.
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** Read MCP355X 22-bit ADC
|
||||
* \return 22-bit value.
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
int32_t read() {
|
||||
uint8_t t = 0;
|
||||
uint8_t v3 = 0;
|
||||
if (m_singleMode) {
|
||||
// Start conversion.
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
// Delay at least 10 usec to avoid RDY glitch on exit from Shutdown.
|
||||
delay(1);
|
||||
// Toggle CsPin to indicate single conversion mode.
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
// Wait for conversion to complete.
|
||||
while (1) {
|
||||
delay(1);
|
||||
fastDigitalWrite(CsPin, 0);
|
||||
// Delay while RDY settles.
|
||||
delayCycles(4);
|
||||
if (!fastDigitalRead(SdoPin)) break;
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
if (t++ > MCP355X_TO_MS) return MCP355X_ERR;
|
||||
}
|
||||
} else {
|
||||
while (1) {
|
||||
if (!fastDigitalRead(SdoPin)) break;
|
||||
delay(1);
|
||||
if (t++ > MCP355X_TO_MS) return MCP355X_ERR;
|
||||
}
|
||||
}
|
||||
uint8_t v2 = readByte();
|
||||
uint8_t v1 = readByte();
|
||||
uint8_t v0 = readByte();
|
||||
|
||||
// The 25th falling edge of SCK changes SDO/RDY from Data mode to RDY mode.
|
||||
uint8_t dummy = 0;
|
||||
readBit(dummy, 0);
|
||||
|
||||
if (m_singleMode) {
|
||||
fastDigitalWrite(CsPin, 1);
|
||||
}
|
||||
if ((v2 & 0XE0) == 0X20) {
|
||||
// Negative in range so extend sign bit.
|
||||
v2 |= 0XC0;
|
||||
v3 = 0XFF;
|
||||
} else if (v2 & 0X40) {
|
||||
// Overflow high. Cause value to be >= MCP355X_OVH.
|
||||
if (v2 & 0X20) v2 &= 0X3F;
|
||||
} else if (v2 & 0X80) {
|
||||
// Overflow low. Cause value to be <= MCP355X_OVH.
|
||||
if ((v2 & 0X20) == 0) v2 |= 0X40;
|
||||
v3 = 0XFF;
|
||||
}
|
||||
uint16_t v_high = (v3 << 8) | v2;
|
||||
uint16_t v_low = (v1 << 8) | v0;
|
||||
return ((uint32_t)v_high << 16) | v_low;
|
||||
}
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
/** delay n nops
|
||||
* \param[in] n nops to delay, must be a constant so compiler optimizes if().
|
||||
*/
|
||||
inline __attribute__((always_inline))
|
||||
void delayCycles(uint8_t n) {
|
||||
if (n & 1) asm volatile("nop\n\t");
|
||||
if (n & 2) asm volatile("nop\n\t" "nop\n\t");
|
||||
if (n & 4) asm volatile("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// Default delay yields about 2 MHz clock.
|
||||
inline __attribute__((always_inline))
|
||||
void readBit(uint8_t &v, uint8_t b, uint8_t delayRead = 0) {
|
||||
fastDigitalWrite(SckPin, 0);
|
||||
delayCycles(2 + delayRead);
|
||||
fastDigitalWrite(SckPin, 1);
|
||||
if (fastDigitalRead(SdoPin)) v |= (1 << b);
|
||||
delayCycles(delayRead);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
uint8_t readByte() {
|
||||
uint8_t v = 0;
|
||||
readBit(v, 7);
|
||||
readBit(v, 6);
|
||||
readBit(v, 5);
|
||||
readBit(v, 4);
|
||||
readBit(v, 3);
|
||||
readBit(v, 2);
|
||||
readBit(v, 1);
|
||||
readBit(v, 0);
|
||||
return v;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool m_singleMode;
|
||||
};
|
||||
#endif // MCP355X_h
|
||||
Reference in New Issue
Block a user