Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RA8875 by
Revision 124:1690a7ae871c, committed 2016-07-31
- Comitter:
- WiredHome
- Date:
- Sun Jul 31 20:59:01 2016 +0000
- Parent:
- 123:2f45e80fec5f
- Child:
- 125:7a0b70f56550
- Commit message:
- Incorporated the Capacitive touch panel APIs in to the base RA8875 driver in a manner that integrated smoothly with the Resistive touch driver.
Changed in this revision
--- a/RA8875.cpp Mon Jul 25 10:55:58 2016 +0000
+++ b/RA8875.cpp Sun Jul 31 20:59:01 2016 +0000
@@ -91,18 +91,50 @@
"not enough ram", ///< could not allocate ram for scanline
};
-RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char *name)
+RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
+ const char *name)
: GraphicsDisplay(name)
, spi(mosi, miso, sclk)
, cs(csel)
, res(reset)
{
+ useTouchPanel = TP_NONE;
+ m_irq = NULL;
+ m_i2c = NULL;
c_callback = NULL;
obj_callback = NULL;
method_callback = NULL;
idle_callback = NULL;
}
+
+RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
+ PinName sda, PinName scl, PinName irq, const char * name)
+ : GraphicsDisplay(name)
+ , spi(mosi, miso, sclk)
+ , cs(csel)
+ , res(reset)
+{
+ useTouchPanel = TP_CAP;
+ m_irq = new InterruptIn(irq);
+ m_i2c = new I2C(sda, scl);
+ c_callback = NULL;
+ obj_callback = NULL;
+ method_callback = NULL;
+ idle_callback = NULL;
+
+ // Cap touch panel config
+ m_addr = (FT5206_I2C_ADDRESS << 1);
+ m_i2c->frequency(FT5206_I2C_FREQUENCY);
+
+ // Interrupt
+ m_irq->mode(PullUp);
+ m_irq->enable_irq();
+ m_irq->fall(this, &RA8875::TouchPanelISR);
+ TouchPanelInit();
+}
+
+
//RA8875::~RA8875()
//{
//}
@@ -168,8 +200,11 @@
Backlight_u8(255);
if (keypadon)
KeypadInit();
- if (touchscreenon)
+ if (touchscreenon) {
+ if (useTouchPanel == TP_NONE)
+ useTouchPanel = TP_RES;
TouchPanelInit();
+ }
#ifdef PERF_METRICS
performance.start();
ClearPerformance();
--- a/RA8875.h Mon Jul 25 10:55:58 2016 +0000
+++ b/RA8875.h Sun Jul 31 20:59:01 2016 +0000
@@ -113,6 +113,98 @@
#define max(a,b) ((a>b)?a:b)
+/// FT5206 definitions follow
+#define FT5206_I2C_FREQUENCY 400000
+
+#define FT5206_I2C_ADDRESS 0x38
+#define FT5206_NUMBER_OF_REGISTERS 31 // there are more registers, but this
+ // is enough to get all 5 touch coordinates.
+
+#define FT5206_NUMBER_OF_TOTAL_REGISTERS 0xFE
+
+#define FT5206_DEVICE_MODE 0x00 // Normal, test, etc.
+#define FT5206_GEST_ID 0x01 // Gesture detected
+#define FT5206_TD_STATUS 0x02 // How many points detected (3:0). 1-5 is valid.
+
+#define FT5206_TOUCH1_XH 0x03 // Event Flag, Touch X Position
+#define FT5206_TOUCH1_XL 0x04
+#define FT5206_TOUCH1_YH 0x05 // Touch ID, Touch Y Position
+#define FT5206_TOUCH1_YL 0x06
+
+#define FT5206_TOUCH2_XH 0x09 // Event Flag, Touch X Position
+#define FT5206_TOUCH2_XL 0x0a
+#define FT5206_TOUCH2_YH 0x0b // Touch ID, Touch Y Position
+#define FT5206_TOUCH2_YL 0x0c
+
+#define FT5206_TOUCH3_XH 0x0f // Event Flag, Touch X Position
+#define FT5206_TOUCH3_XL 0x10
+#define FT5206_TOUCH3_YH 0x11 // Touch ID, Touch Y Position
+#define FT5206_TOUCH3_YL 0x12
+
+#define FT5206_TOUCH4_XH 0x15 // Event Flag, Touch X Position
+#define FT5206_TOUCH4_XL 0x16
+#define FT5206_TOUCH4_YH 0x17 // Touch ID, Touch Y Position
+#define FT5206_TOUCH4_YL 0x18
+
+#define FT5206_TOUCH5_XH 0x1b // Event Flag, Touch X Position
+#define FT5206_TOUCH5_XL 0x1c
+#define FT5206_TOUCH5_YH 0x1d // Touch ID, Touch Y Position
+#define FT5206_TOUCH5_YL 0x1e
+
+// For typical usage, the registers listed below are not used.
+#define FT5206_ID_G_THGROUP 0x80 // Valid touching detect threshold
+#define FT5206_ID_G_THPEAK 0x81 // Valid touching peak detect threshold
+#define FT5206_ID_G_THCAL 0x82 // The threshold when calculating the focus of touching
+#define FT5206_ID_G_THWATER 0x83 // The threshold when there is surface water
+#define FT5206_ID_G_THTEMP 0x84 // The threshold of temperature compensation
+#define FT5206_ID_G_CTRL 0x86 // Power control mode
+#define FT5206_ID_G_TIME_ENTER_MONITOR 0x87 // The timer of entering monitor status
+#define FT5206_ID_G_PERIODACTIVE 0x88 // Period Active
+#define FT5206_ID_G_PERIODMONITOR 0x89 // The timer of entering idle while in monitor status
+#define FT5206_ID_G_AUTO_CLB_MODE 0xA0 // Auto calibration mode
+
+#define FT5206_TOUCH_LIB_VERSION_H 0xA1 // Firmware Library Version H byte
+#define FT5206_TOUCH_LIB_VERSION_L 0xA2 // Firmware Library Version L byte
+#define FT5206_ID_G_CIPHER 0xA3 // Chip vendor ID
+#define FT5206_G_MODE 0xA4 // The interrupt status to host
+#define FT5206_ID_G_PMODE 0xA5 // Power Consume Mode
+#define FT5206_FIRMID 0xA6 // Firmware ID
+#define FT5206_ID_G_STATE 0xA7 // Running State
+#define FT5206_ID_G_FT5201ID 0xA8 // CTPM Vendor ID
+#define FT5206_ID_G_ERR 0xA9 // Error Code
+#define FT5206_ID_G_CLB 0xAA // Configure TP module during calibration in Test Mode
+#define FT5206_ID_G_B_AREA_TH 0xAE // The threshold of big area
+#define FT5206_LOG_MSG_CNT 0xFE // The log MSG count
+#define FT5206_LOG_CUR_CHA 0xFF // Current character of log message, will point to the next
+ // character when one character is read.
+#define FT5206_GEST_ID_MOVE_UP 0x10
+#define FT5206_GEST_ID_MOVE_LEFT 0x14
+#define FT5206_GEST_ID_MOVE_DOWN 0x18
+#define FT5206_GEST_ID_MOVE_RIGHT 0x1c
+#define FT5206_GEST_ID_ZOOM_IN 0x48
+#define FT5206_GEST_ID_ZOOM_OUT 0x49
+#define FT5206_GEST_ID_NO_GESTURE 0x00
+
+#define FT5206_EVENT_FLAG_PUT_DOWN 0x00
+#define FT5206_EVENT_FLAG_PUT_UP 0x01
+#define FT5206_EVENT_FLAG_CONTACT 0x02
+#define FT5206_EVENT_FLAG_RESERVED 0x03
+
+#define FT5206_ID_G_POLLING_MODE 0x00
+#define FT5206_ID_G_TRIGGER_MODE 0x01
+
+#define FT5206_ID_G_PMODE_ACTIVE 0x00
+#define FT5206_ID_G_PMODE_MONITOR 0x01
+#define FT5206_ID_G_PMODE_HIBERNATE 0x03
+
+#define FT5206_ID_G_STATE_CONFIGURE 0x00
+#define FT5206_ID_G_STATE_WORK 0x01
+#define FT5206_ID_G_STATE_CALIBRATION 0x02
+#define FT5206_ID_G_STATE_FACTORY 0x03
+#define FT5206_ID_G_STATE_AUTO_CALIBRATION 0x04
+/// end of FT5206 definitions
+
+
//namespace SW_graphics
//{
@@ -301,7 +393,11 @@
typedef RetCode_t (* IdleCallback_T)(IdleReason_T info);
/// Constructor for a display based on the RAiO RA8875
- /// display controller.
+ /// display controller (use for TouchScreen: Resistive or none)
+ ///
+ /// This constructor differs from the alternate by supportting
+ /// either No Touch Screen, or the RA8875 built-in resistive
+ /// touch screen.
///
/// This configures the registers and calls the @ref init method.
///
@@ -328,7 +424,33 @@
/// @param[in] name is a text name for this object, which will permit
/// capturing stdout to puts() and printf() directly to it.
///
- RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char * name = "lcd");
+ RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
+ const char * name = "lcd");
+
+
+ /// Constructor for a display based on the RAiO RA8875
+ /// display controller (use for TouchScreen: Capacitive only)
+ ///
+ /// This constructor differs from the alternate by including support
+ /// for the Capactive Touch screen.
+ ///
+ /// @param[in] mosi is the SPI master out slave in pin on the mbed.
+ /// @param[in] miso is the SPI master in slave out pin on the mbed.
+ /// @param[in] sclk is the SPI shift clock pin on the mbed.
+ /// @param[in] csel is the DigitalOut pin on the mbed to use as the
+ /// active low chip select for the display controller.
+ /// @param[in] reset is the DigitalOut pin on the mbed to use as the
+ /// active low reset input on the display controller -
+ /// but this is not currently used.
+ /// @param[in] sda is the I2C Serial Data pin you are wiring to the FT5206.
+ /// @param[in] scl is the I2C Serial Clock pin you are wiring to the FT5206.
+ /// @param[in] irq is the Interrupt Request pin you are wiring to the FT5206.
+ /// @param[in] name is a text name for this object, which will permit
+ /// capturing stdout to puts() and printf() directly to it.
+ ///
+ RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
+ PinName sda, PinName scl, PinName irq, const char * name = "lcd");
+
// Destructor doesn't have much to do as this would typically be created
// at startup, and not at runtime.
@@ -353,13 +475,17 @@
/// and the default is true (on). See @ref Power.
/// @param[in] keypadon defines if the keypad support should be enabled. This parameter is optional
/// and the default is true (enabled). See @ref KeypadInit.
- /// @param[in] touchscreeenon defines if the keypad support should be enabled. This parameter is optional
- /// and the default is true (enabled). See @ref TouchPanelInit.
+ /// @param[in] touchscreeenon defines if the touchscreen support should be enabled.
+ /// This parameter is optional and the default is true (enabled). See @ref TouchPanelInit.\\
+ /// - If the constructor was called with support for the capacitive driver, this
+ /// parameter causes the driver to initialize.
+ /// - If the constructor was called without support for the capacitive driver, this
+ /// parameter is used to enable and initialize the resistive touchscreen driver.
/// @returns success/failure code. See @ref RetCode_t.
///
RetCode_t init(int width = 480, int height = 272, int color_bpp = 16,
bool poweron = true, bool keypadon = true, bool touchscreeenon = true);
-
+
/// Get a pointer to the error code.
///
/// This method returns a pointer to a text string that matches the
@@ -495,7 +621,7 @@
///
/// This activates the simplified touch panel init, which may work for
/// most uses. The alternate API is available if fine-grained control
- /// is needed for the numerous settings.
+ /// of the numerous settings of the resistive panel is needed.
///
/// @returns success/failure code. See @ref RetCode_t.
///
@@ -504,7 +630,10 @@
/// Initialize the Touch Panel controller with detailed settings.
///
/// This is the detailed touch panel init, which provides the ability
- /// to set nearly every possible option.
+ /// to set nearly every option.
+ ///
+ /// @note If the capacitive touch panel was constructed, this behaves
+ /// the same as the simplified version.
///
/// @param[in] bTpEnable Touch Panel enable/disable control:
/// - TP_ENABLE: enable the touch panel
@@ -574,7 +703,84 @@
///
TouchCode_t TouchPanelReadable(point_t * TouchPoint = NULL);
+ /// Get the reported touch gesture, if any.
+ ///
+ /// If it could detect a gesture, it will return a value based on
+ /// the interpreted gesture.\\
+ ///
+ /// Valid gesture values are:
+ /// @li 0x00 No gesture
+ /// @li 0x10 Move up
+ /// @li 0x14 Move left
+ /// @li 0x18 Move down
+ /// @li 0x1C Move right
+ /// @li 0x48 Zoom in
+ /// @li 0x49 Zoom out
+ ///
+ /// @returns gesture information.
+ ///
+ uint8_t TouchGesture(void) { return gesture; }
+
+ /// Get the count of registered touches.
+ ///
+ /// @returns count of touch points to communicate; 0 to 5.
+ ///
+ int TouchCount(void) { return numberOfTouchPoints; }
+
+ /// Get the count of possible touch channels.
+ ///
+ /// @returns count of touch channels supported by the hardware.
+ ///
+ int TouchChannels(void);
+
+ /// Get the Touch ID value for a specified touch channel.
+ ///
+ /// Touch ID is a tracking number based on the order of the touch
+ /// detections. The first touch is ID 0, the next is ID 1, and
+ /// so on. If the first touch is lifted (no touch), the touch count
+ /// decrements, and the remaining touch is communicated on
+ /// touch channel zero, even as the Touch ID remains as originally
+ /// reported (1 in this example). In this way, it is easy to track
+ /// a specific touch.\\
+ ///
+ /// It is possible to query the data for a channel that is not
+ /// presently reported as touched.
+ ///
+ /// @param[in] channel is the touch channel, from 0 to 4, or 0 to getTouchCount()-1
+ /// It defaults to 0, in case the user is not interested in multi-touch.
+ /// @returns the touch ID, or 15 if you get the ID for an untouched channel.
+ /// @returns 0 if an invalid channel is queried.
+ ///
+ uint8_t TouchID(uint8_t channel = 0) { return (channel < 5) ? touchInfo[channel].touchID : touchInfo[0].touchID; }
+
+ /// Get the Touch Code for a touch channel.
+ ///
+ /// It is possible to query the data for a channel that is not
+ /// presently reported as touched.
+ ///
+ /// @param[in] channel is the touch channel, from 0 to 4, or 0 to getTouchCount()-1
+ /// It defaults to 0, in case the user is not interested in multi-touch.
+ /// @returns the touch code (@ref TouchCode_t).
+ /// @returns channel 0 information if an invalid channel is queried.
+ ///
+ TouchCode_t TouchCode(uint8_t channel = 0) { return (channel < 5) ? touchInfo[channel].touchCode : touchInfo[0].touchCode; }
+
+ /// Get the coordinates for a touch channel.
+ ///
+ /// This returns the (X,Y) coordinates for a touch channel.
+ ///\\
+ ///
+ /// It is possible to query the data for a channel that is not
+ /// presently reported as touched.
+ ///
+ /// @param[in] channel is an optional touch channel, from 0 to 4, or 0 to getTouchCount()-1.
+ /// It defaults to 0, in case the user is not interested in multi-touch.
+ /// @returns the coordinates as a point_t structure.
+ /// @returns channel 0 information if an invalid channel is queried.
+ ///
+ point_t TouchCoordinates(uint8_t channel = 0) { return (channel < 5) ? touchInfo[channel].coordinates : touchInfo[0].coordinates; }
+
/// Poll the TouchPanel and on a touch event return the a to d filtered x, y coordinates.
///
/// This method reads the touch controller, which has a 10-bit range for each the
@@ -2123,7 +2329,51 @@
private:
- /// Touch Panel register name definitions
+ /// Touch panel parameters - common to both resistive and capacitive
+
+ /// Data type to indicate which TP, if any, is in use.
+ typedef enum {
+ TP_NONE, ///< no touch panel in use
+ TP_RES, ///< resistive touch panel using RA8875
+ TP_CAP, ///< capacitive touch panel using FT5206
+ } WhichTP_T;
+
+ /// boolean flag set true when using Capacitive touch panel, and false
+ /// for resistive.
+ WhichTP_T useTouchPanel; ///< Indicates which TP is selected for use.
+
+ /// Touch State used by TouchPanelReadable. See @ref TouchCode_t.
+ TouchCode_t touchState;
+
+ ////////////////// Start of Capacitive Touch Panel parameters
+
+ uint8_t getTouchPositions(void);
+ void TouchPanelISR(void);
+ uint16_t numberOfTouchPoints;
+ uint8_t gesture; ///< Holds the reported gesture information.
+
+ /// Touch Information data structure
+ typedef struct {
+ uint8_t touchID; ///< Contains the touch ID, which is the "order" of touch, from 0 to n-1
+ TouchCode_t touchCode; ///< Contains the touch code; no_touch, touch, held, release
+ point_t coordinates; ///< Contains the X,Y coordinate of the touch
+ } touchInfo_T;
+
+ touchInfo_T touchInfo[5]; /// Contains the actual touch information in an array from 0 to n-1
+
+ InterruptIn * m_irq;
+ I2C * m_i2c;
+ int m_addr;
+ uint8_t data[2];
+
+ bool panelTouched;
+ void writeRegister8(uint8_t reg, uint8_t val);
+ uint8_t readRegister8(uint8_t reg);
+
+
+ ////////////////// Start of Resistive Touch Panel parameters
+
+ /// Resistive Touch Panel register name definitions
#define TPCR0 0x70
#define TPCR1 0x71
#define TPXH 0x72
@@ -2148,9 +2398,6 @@
// a touch, and if so, it then clears the sample counter so it doesn't get partial old
// and partial new.
- /// Touch State used by TouchPanelReadable. See @ref TouchCode_t.
- TouchCode_t touchState;
-
/// Touch Panel ticker
Ticker touchTicker;
@@ -2166,6 +2413,9 @@
/// Touch Panel calibration matrix.
tpMatrix_t tpMatrix;
+ ////////////////// End of Touch Panel parameters
+
+
/// Internal function to put a character using the built-in (internal) font engine
///
/// @param[in] c is the character to put to the screen.
@@ -2320,7 +2570,6 @@
RetCode_t (* c_callback)(filecmd_t cmd, uint8_t * buffer, uint16_t size);
FPointerDummy *obj_callback;
RetCode_t (FPointerDummy::*method_callback)(filecmd_t cmd, uint8_t * buffer, uint16_t size);
-
RetCode_t (* idle_callback)(IdleReason_T reason);
};
--- a/RA8875_Touch.cpp Mon Jul 25 10:55:58 2016 +0000
+++ b/RA8875_Touch.cpp Sun Jul 31 20:59:01 2016 +0000
@@ -1,69 +1,107 @@
/// This file contains the RA8875 Touch panel methods.
///
-
+/// It combines both resistive and capacitive touch methods, and tries
+/// to make them nearly transparent alternates for each other.
+///
#include "RA8875.h"
#define NOTOUCH_TIMEOUT_uS 100000
#define TOUCH_TICKER_uS 1000
+
+// Translate from FT5206 Event Flag to Touch Code to API-match the
+// alternate resistive touch screen driver common in the RA8875
+// displays.
+static const TouchCode_t EventFlagToTouchCode[4] = {
+ touch, // 00b Put Down
+ release, // 01b Put Up
+ held, // 10b Contact
+ no_touch // 11b Reserved
+};
+
+
RetCode_t RA8875::TouchPanelInit(void)
{
- //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
- WriteCommand(TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
- // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params
- WriteCommand(TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
- WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
- WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
- touchSample = 0;
- touchState = no_cal;
- touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
- touchTimer.start();
- touchTimer.reset();
- return noerror;
-}
-
-RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime)
-{
- // Parameter bounds check
- if( \
- !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \
- !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \
- !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \
- !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \
- !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \
- !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \
- ) return bad_parameter;
- // Construct the config byte for TPCR0 and write them
- WriteCommand(TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime); // Note: Wakeup is never enabled
- // Construct the config byte for TPCR1 and write them
- WriteCommand(TPCR1, bTpManualMode | bTpDebounce | bTpManualMode); // Note: Always uses internal Vref.
- // Set up the interrupt flag and enable bits
- WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
- WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
- touchSample = 0;
- touchState = no_cal;
- if (bTpEnable == TP_ENABLE) {
+ panelTouched = false;
+ if (useTouchPanel == TP_CAP) {
+ // Set to normal mode
+ writeRegister8(FT5206_DEVICE_MODE, 0);
+ } else {
+ //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
+ WriteCommand(TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
+ // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params
+ WriteCommand(TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
+ WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
+ WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
+ touchSample = 0;
+ touchState = no_cal;
touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
touchTimer.start();
touchTimer.reset();
- } else {
- touchTicker.detach();
- touchTimer.stop();
}
return noerror;
}
- // +----------------------------------------------------+
- // | |
- // | 1 |
- // | |
- // | |
- // | 2 |
- // | |
- // | |
- // | 3 |
- // | |
- // +----------------------------------------------------+
+
+RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime)
+{
+ if (useTouchPanel == TP_CAP) {
+ TouchPanelInit();
+ } else {
+ // Parameter bounds check
+ if( \
+ !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \
+ !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \
+ !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \
+ !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \
+ !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \
+ !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \
+ ) return bad_parameter;
+ // Construct the config byte for TPCR0 and write them
+ WriteCommand(TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime); // Note: Wakeup is never enabled
+ // Construct the config byte for TPCR1 and write them
+ WriteCommand(TPCR1, bTpManualMode | bTpDebounce | bTpManualMode); // Note: Always uses internal Vref.
+ // Set up the interrupt flag and enable bits
+ WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
+ WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
+ touchSample = 0;
+ touchState = no_cal;
+ if (bTpEnable == TP_ENABLE) {
+ touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
+ touchTimer.start();
+ touchTimer.reset();
+ } else {
+ touchTicker.detach();
+ touchTimer.stop();
+ }
+ }
+ return noerror;
+}
+
+
+int RA8875::TouchChannels(void)
+{
+ if (useTouchPanel == TP_CAP) {
+ return 5; // based on the FT5206 hardware
+ } else if (useTouchPanel == TP_RES) {
+ return 1; // based on the RA8875 resistive touch driver
+ } else {
+ return 0; // it isn't enabled, so there are none.
+ }
+}
+
+
+// +----------------------------------------------------+
+// | |
+// | 1 |
+// | |
+// | |
+// | 2 |
+// | |
+// | |
+// | 3 |
+// | |
+// +----------------------------------------------------+
RetCode_t RA8875::TouchPanelCalibrate(tpMatrix_t * matrix)
{
@@ -76,7 +114,7 @@
point_t pSample[3];
int x,y;
Timer timeout; // timeout guards for not-installed, stuck, user not present...
-
+
timeout.start();
while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) {
wait_ms(20);
@@ -90,9 +128,12 @@
if (msg)
puts(msg);
SetTextCursor(0,height()/2);
- pTest[0].x = 50; pTest[0].y = 50;
- pTest[1].x = width() - 50; pTest[1].y = height()/2;
- pTest[2].x = width()/2; pTest[2].y = height() - 50;
+ pTest[0].x = 50;
+ pTest[0].y = 50;
+ pTest[1].x = width() - 50;
+ pTest[1].y = height()/2;
+ pTest[2].x = width()/2;
+ pTest[2].y = height() - 50;
for (int i=0; i<3; i++) {
foreground(Blue);
@@ -144,24 +185,24 @@
* Description: Given a valid set of calibration factors and a point
* value reported by the touch screen, this function
* calculates and returns the true (or closest to true)
- * display point below the spot where the touch screen
+ * display point below the spot where the touch screen
* was touched.
- *
+ *
*
- *
+ *
* Argument(s): displayPtr (output) - Pointer to the calculated
* (true) display point.
* screenPtr (input) - Pointer to the reported touch
* screen point.
* matrixPtr (input) - Pointer to calibration factors
* matrix previously calculated
- * from a call to
+ * from a call to
* setCalibrationMatrix()
- *
+ *
*
- * The function simply solves for Xd and Yd by implementing the
- * computations required by the translation matrix.
- *
+ * The function simply solves for Xd and Yd by implementing the
+ * computations required by the translation matrix.
+ *
* /- -\
* /- -\ /- -\ | |
* | | | | | Xs |
@@ -171,10 +212,10 @@
* | | | | | 1 |
* \- -/ \- -/ | |
* \- -/
- *
+ *
* It must be kept brief to avoid consuming CPU cycles.
*
- * Return: OK - the display point was correctly calculated
+ * Return: OK - the display point was correctly calculated
* and its value is in the output argument.
* NOT_OK - an error was detected and the function
* failed to return a valid point.
@@ -182,42 +223,60 @@
* NOTE! NOTE! NOTE!
*
* setCalibrationMatrix() and getDisplayPoint() will do fine
- * for you as they are, provided that your digitizer
+ * for you as they are, provided that your digitizer
* resolution does not exceed 10 bits (1024 values). Higher
* resolutions may cause the integer operations to overflow
- * and return incorrect values. If you wish to use these
- * functions with digitizer resolutions of 12 bits (4096
- * values) you will either have to a) use 64-bit signed
- * integer variables and math, or b) judiciously modify the
- * operations to scale results by a factor of 2 or even 4.
+ * and return incorrect values. If you wish to use these
+ * functions with digitizer resolutions of 12 bits (4096
+ * values) you will either have to a) use 64-bit signed
+ * integer variables and math, or b) judiciously modify the
+ * operations to scale results by a factor of 2 or even 4.
*
*/
TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint)
{
- int a2dX = 0;
- int a2dY = 0;
-
- TouchCode_t ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
- if (ts != no_touch) {
- if (tpMatrix.Divider != 0) {
- if (TouchPoint) {
+ TouchCode_t ts = no_touch;
+
+ if (useTouchPanel == TP_RES) {
+ int a2dX = 0;
+ int a2dY = 0;
+
+ touchInfo[0].touchID = 0;
+ ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
+ if (ts != no_touch) {
+ panelTouched = true;
+ numberOfTouchPoints = 1;
+
+ if (tpMatrix.Divider != 0) {
+
/* Operation order is important since we are doing integer */
/* math. Make sure you add all terms together before */
/* dividing, so that the remainder is not rounded off */
/* prematurely. */
- TouchPoint->x = ( (tpMatrix.An * a2dX) +
+ touchInfo[0].coordinates.x = ( (tpMatrix.An * a2dX) +
(tpMatrix.Bn * a2dY) +
tpMatrix.Cn
) / tpMatrix.Divider ;
- TouchPoint->y = ( (tpMatrix.Dn * a2dX) +
+ touchInfo[0].coordinates.y = ( (tpMatrix.Dn * a2dX) +
(tpMatrix.En * a2dY) +
tpMatrix.Fn
) / tpMatrix.Divider ;
+ } else {
+ ts = no_cal;
}
} else {
- ts = no_cal;
+ numberOfTouchPoints = 0;
}
+ touchInfo[0].touchCode = ts;
+ }
+ if (panelTouched == true) {
+ panelTouched = false;
+ if (TouchPoint) {
+ *TouchPoint = touchInfo[0].coordinates;
+ ts = touchInfo[0].touchCode;
+ }
+ ts = touch;
}
return ts;
}
@@ -226,7 +285,7 @@
TouchCode_t RA8875::TouchPanelGet(point_t * TouchPoint)
{
TouchCode_t t = no_touch;
-
+
while (true) {
t = TouchPanelReadable(TouchPoint);
if (t != no_touch)
@@ -256,7 +315,7 @@
{
int i, j;
int temp;
-
+
for(i = 1; i < bufsize; i++) {
temp = buf[i];
j = i;
@@ -386,28 +445,28 @@
*
* Copyright (c) 2001, Carlos E. Vidales. All rights reserved.
*
- * This sample program was written and put in the public domain
- * by Carlos E. Vidales. The program is provided "as is"
+ * This sample program was written and put in the public domain
+ * by Carlos E. Vidales. The program is provided "as is"
* without warranty of any kind, either expressed or implied.
* If you choose to use the program within your own products
* you do so at your own risk, and assume the responsibility
* for servicing, repairing or correcting the program should
* it prove defective in any manner.
- * You may copy and distribute the program's source code in any
+ * You may copy and distribute the program's source code in any
* medium, provided that you also include in each copy an
* appropriate copyright notice and disclaimer of warranty.
* You may also modify this program and distribute copies of
- * it provided that you include prominent notices stating
+ * it provided that you include prominent notices stating
* that you changed the file(s) and the date of any change,
- * and that you do not charge any royalties or licenses for
+ * and that you do not charge any royalties or licenses for
* its use.
- *
- * This file contains functions that implement calculations
+ *
+ * This file contains functions that implement calculations
* necessary to obtain calibration factors for a touch screen
- * that suffers from multiple distortion effects: namely,
+ * that suffers from multiple distortion effects: namely,
* translation, scaling and rotation.
*
- * The following set of equations represent a valid display
+ * The following set of equations represent a valid display
* point given a corresponding set of touch screen points:
*
* /- -\
@@ -420,7 +479,7 @@
* \- -/ \- -/ | |
* \- -/
* where:
- * (Xd,Yd) represents the desired display point
+ * (Xd,Yd) represents the desired display point
* coordinates,
* (Xs,Ys) represents the available touch screen
* coordinates, and the matrix
@@ -428,18 +487,18 @@
* |A,B,C|
* |D,E,F| represents the factors used to translate
* \- -/ the available touch screen point values
- * into the corresponding display
+ * into the corresponding display
* coordinates.
- * Note that for practical considerations, the utilities
+ * Note that for practical considerations, the utilities
* within this file do not use the matrix coefficients as
- * defined above, but instead use the following
+ * defined above, but instead use the following
* equivalents, since floating point math is not used:
- * A = An/Divider
- * B = Bn/Divider
- * C = Cn/Divider
- * D = Dn/Divider
- * E = En/Divider
- * F = Fn/Divider
+ * A = An/Divider
+ * B = Bn/Divider
+ * C = Cn/Divider
+ * D = Dn/Divider
+ * E = En/Divider
+ * F = Fn/Divider
* The functions provided within this file are:
* setCalibrationMatrix() - calculates the set of factors
* in the above equation, given
@@ -458,23 +517,23 @@
* Function: setCalibrationMatrix()
*
* Description: Calling this function with valid input data
- * in the display and screen input arguments
+ * in the display and screen input arguments
* causes the calibration factors between the
* screen and display points to be calculated,
- * and the output argument - matrixPtr - to be
+ * and the output argument - matrixPtr - to be
* populated.
*
* This function needs to be called only when new
* calibration factors are desired.
- *
- *
- * Argument(s): displayPtr (input) - Pointer to an array of three
+ *
+ *
+ * Argument(s): displayPtr (input) - Pointer to an array of three
* sample, reference points.
- * screenPtr (input) - Pointer to the array of touch
- * screen points corresponding
+ * screenPtr (input) - Pointer to the array of touch
+ * screen points corresponding
* to the reference display points.
- * matrixPtr (output) - Pointer to the calibration
- * matrix computed for the set
+ * matrixPtr (output) - Pointer to the calibration
+ * matrix computed for the set
* of points being provided.
*
*
@@ -496,8 +555,8 @@
* Divider
*
*
- * Ys0*(Xs2*Xd1 - Xs1*Xd2) +
- * Ys1*(Xs0*Xd2 - Xs2*Xd0) +
+ * Ys0*(Xs2*Xd1 - Xs1*Xd2) +
+ * Ys1*(Xs0*Xd2 - Xs2*Xd0) +
* Ys2*(Xs1*Xd0 - Xs0*Xd1)
* C = ---------------------------------------------------
* Divider
@@ -513,17 +572,17 @@
* Divider
*
*
- * Ys0*(Xs2*Yd1 - Xs1*Yd2) +
- * Ys1*(Xs0*Yd2 - Xs2*Yd0) +
+ * Ys0*(Xs2*Yd1 - Xs1*Yd2) +
+ * Ys1*(Xs0*Yd2 - Xs2*Yd0) +
* Ys2*(Xs1*Yd0 - Xs0*Yd1)
* F = ---------------------------------------------------
* Divider
*
*
- * Return: OK - the calibration matrix was correctly
- * calculated and its value is in the
+ * Return: OK - the calibration matrix was correctly
+ * calculated and its value is in the
* output argument.
- * NOT_OK - an error was detected and the
+ * NOT_OK - an error was detected and the
* function failed to return a valid
* set of matrix values.
* The only time this sample code returns
@@ -534,14 +593,14 @@
* NOTE! NOTE! NOTE!
*
* setCalibrationMatrix() and getDisplayPoint() will do fine
- * for you as they are, provided that your digitizer
+ * for you as they are, provided that your digitizer
* resolution does not exceed 10 bits (1024 values). Higher
* resolutions may cause the integer operations to overflow
- * and return incorrect values. If you wish to use these
- * functions with digitizer resolutions of 12 bits (4096
- * values) you will either have to a) use 64-bit signed
- * integer variables and math, or b) judiciously modify the
- * operations to scale results by a factor of 2 or even 4.
+ * and return incorrect values. If you wish to use these
+ * functions with digitizer resolutions of 12 bits (4096
+ * values) you will either have to a) use 64-bit signed
+ * integer variables and math, or b) judiciously modify the
+ * operations to scale results by a factor of 2 or even 4.
*
*/
RetCode_t RA8875::TouchPanelComputeCalibration(point_t * displayPtr, point_t * screenPtr, tpMatrix_t * matrixPtr)
@@ -580,4 +639,83 @@
return( retValue ) ;
}
+////////////////// Capacitive Touch Panel
+
+uint8_t RA8875::readRegister8(uint8_t reg) {
+ char val;
+
+ m_i2c->write(m_addr, (const char *)®, 1);
+ m_i2c->read(m_addr, &val, 1);
+ return (uint8_t)val;
+}
+
+void RA8875::writeRegister8(uint8_t reg, uint8_t val) {
+ char data[2];
+
+ data[0] = (char)reg;
+ data[1] = (char)val;
+ m_i2c->write((int)FT5206_I2C_ADDRESS, data, 2);
+}
+
+
+// Interrupt for touch detection
+void RA8875::TouchPanelISR(void)
+{
+ getTouchPositions();
+ panelTouched = true;
+}
+
+uint8_t RA8875::getTouchPositions(void) {
+ uint8_t valXH;
+ uint8_t valYH;
+
+ numberOfTouchPoints = readRegister8(FT5206_TD_STATUS) & 0xF;
+ gesture = readRegister8(FT5206_GEST_ID);
+
+ // If the switch statement was based only on numberOfTouchPoints, it would not
+ // be able to generate notification for 'release' events (as it is no longer touched).
+ // Therefore, forcing a 5, and it intentially falls through each lower case.
+ switch (5) { // numberOfTouchPoints
+ case 5:
+ valXH = readRegister8(FT5206_TOUCH5_XH);
+ valYH = readRegister8(FT5206_TOUCH5_YH);
+ touchInfo[4].touchCode = EventFlagToTouchCode[valXH >> 6];
+ touchInfo[4].touchID = (valYH >> 4);
+ touchInfo[4].coordinates.x = (valXH & 0x0f)*256 + readRegister8(FT5206_TOUCH5_XL);
+ touchInfo[4].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH5_YL);
+ case 4:
+ valXH = readRegister8(FT5206_TOUCH4_XH);
+ valYH = readRegister8(FT5206_TOUCH4_YH);
+ touchInfo[3].touchCode = EventFlagToTouchCode[valXH >> 6];
+ touchInfo[3].touchID = (valYH >> 4);
+ touchInfo[3].coordinates.x = (readRegister8(FT5206_TOUCH4_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH4_XL);
+ touchInfo[3].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH4_YL);
+ case 3:
+ valXH = readRegister8(FT5206_TOUCH3_XH);
+ valYH = readRegister8(FT5206_TOUCH3_YH);
+ touchInfo[2].touchCode = EventFlagToTouchCode[valXH >> 6];
+ touchInfo[2].touchID = (valYH >> 4);
+ touchInfo[2].coordinates.x = (readRegister8(FT5206_TOUCH3_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH3_XL);
+ touchInfo[2].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH3_YL);
+ case 2:
+ valXH = readRegister8(FT5206_TOUCH2_XH);
+ valYH = readRegister8(FT5206_TOUCH2_YH);
+ touchInfo[1].touchCode = EventFlagToTouchCode[valXH >> 6];
+ touchInfo[1].touchID = (valYH >> 4);
+ touchInfo[1].coordinates.x = (readRegister8(FT5206_TOUCH2_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH2_XL);
+ touchInfo[1].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH2_YL);
+ case 1:
+ valXH = readRegister8(FT5206_TOUCH1_XH);
+ valYH = readRegister8(FT5206_TOUCH1_YH);
+ touchInfo[0].touchCode = EventFlagToTouchCode[valXH >> 6];
+ touchInfo[0].touchID = (valYH >> 4);
+ touchInfo[0].coordinates.x = (readRegister8(FT5206_TOUCH1_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH1_XL);
+ touchInfo[0].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH1_YL);
+ break;
+ default:
+ break;
+ }
+ return numberOfTouchPoints;
+}
+
// #### end of touch panel code additions
