LCD LIB
Fork of RA8875 by
Revision 123:2f45e80fec5f, committed 2016-07-25
- Comitter:
- WiredHome
- Date:
- Mon Jul 25 10:55:58 2016 +0000
- Parent:
- 122:79e431f98fa9
- Child:
- 124:1690a7ae871c
- Commit message:
- Added idle callback - when the RA8875 driver is stuck waiting on the HW, or on a long timeout, it can call an optional callback. This could be used for maintaining the Watchdog, or other activities.
Changed in this revision
--- a/DisplayDefs.h Tue May 17 22:33:06 2016 +0000 +++ b/DisplayDefs.h Mon Jul 25 10:55:58 2016 +0000 @@ -3,7 +3,6 @@ #define RGB(r,g,b) ( ((r<<8)&0xF800) | ((g<<3)&0x07E0) | (b>>3) ) -typedef uint16_t color_t; /// return values from functions. Use this number, or use the /// lookup function to get a text string. @see GetErrorMessage.
--- a/RA8875.cpp Tue May 17 22:33:06 2016 +0000 +++ b/RA8875.cpp Mon Jul 25 10:55:58 2016 +0000 @@ -100,6 +100,7 @@ c_callback = NULL; obj_callback = NULL; method_callback = NULL; + idle_callback = NULL; } //RA8875::~RA8875() @@ -324,10 +325,15 @@ static uint8_t count = 0; uint8_t col, row; uint8_t key; - + while (!readable()) { wait_us(POLLWAITuSec); // COUNTIDLETIME(POLLWAITuSec); // As it is voluntary to call the getc and pend. Don't tally it. + if (idle_callback) { + if (external_abort == (*idle_callback)(getc_wait)) { + return 0; + } + } } // read the key press number uint8_t keyNumReg = ReadCommand(0xC1) & 0x03; @@ -544,6 +550,11 @@ while (i-- && ReadStatus() & mask) { wait_us(POLLWAITuSec); COUNTIDLETIME(POLLWAITuSec); + if (idle_callback) { + if (external_abort == (*idle_callback)(status_wait)) { + return false; + } + } } if (i) return true; @@ -561,6 +572,11 @@ while (i-- && ReadCommand(reg) & mask) { wait_us(POLLWAITuSec); COUNTIDLETIME(POLLWAITuSec); + if (idle_callback) { + if (external_abort == (*idle_callback)(command_wait)) { + return false; + } + } } if (i) return true;
--- a/RA8875.h Tue May 17 22:33:06 2016 +0000 +++ b/RA8875.h Mon Jul 25 10:55:58 2016 +0000 @@ -272,9 +272,34 @@ /// @param cmd is the command to execute. See @ref filecmd_t. /// @param buffer is a pointer to the buffer being passed. /// @param size is the number of bytes in the buffer. + /// @returns the noerror signal. /// typedef RetCode_t (* PrintCallback_T)(filecmd_t cmd, uint8_t * buffer, uint16_t size); + typedef enum { + unknown, ///< reason has not been assigned (this should not happen) + status_wait, ///< driver is polling the status register while busy + command_wait, ///< driver is polling the command register while busy + getc_wait, ///< user has called the getc function + touch_wait, ///< user has called the touch function + touchcal_wait ///< driver is performing a touch calibration + } IdleReason_T; + + /// Idle Callback + /// + /// This defines the interface for an idle callback. That is, when the + /// driver is held up, pending some event, it can call a registered + /// idle function. This could be most useful for servicing a watchdog. + /// + /// The user code, which is notified via this API, can force the idle + /// to abort, by returning the external_abort value back to the driver. + /// + /// @param info informs the callback why it is idle. + /// @returns noerror to allow the driver continue waiting. + /// @returns external_abort if the pending action should be aborted. + /// + typedef RetCode_t (* IdleCallback_T)(IdleReason_T info); + /// Constructor for a display based on the RAiO RA8875 /// display controller. /// @@ -518,6 +543,38 @@ RetCode_t TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime); + + /// Get the screen calibrated point of touch. + /// + /// This method determines if there is a touch and if so it will provide + /// the screen-relative touch coordinates. This method can be used in + /// a manner similar to Serial.readable(), to determine if there was a + /// touch and indicate that - but not care about the coordinates. Alternately, + /// if a valid pointer to a point_t is provided, then if a touch is detected + /// the point_t will be populated with data. + /// + /// @code + /// Timer t; + /// t.start(); + /// do { + /// point_t point = {0, 0}; + /// if (display.TouchPanelReadable(&point)) { + /// display.pixel(point, Red); + /// } + /// } while (t.read_ms() < 30000); + /// @endcode + /// + /// @param[out] TouchPoint is a pointer to a point_t, which is set as the touch point, if a touch is registered. + /// @returns a value indicating the state of the touch, + /// - no_cal: no calibration matrix is available, touch coordinates are not returned. + /// - no_touch: no touch is detected, touch coordinates are not returned. + /// - touch: touch is detected, touch coordinates are returned. + /// - held: held after touch, touch coordinates are returned. + /// - release: indicates a release, touch coordinates are returned. + /// + TouchCode_t TouchPanelReadable(point_t * TouchPoint = NULL); + + /// 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 @@ -563,37 +620,6 @@ /// TouchCode_t TouchPanelA2DRaw(int *x, int *y); - /// Get the screen calibrated point of touch. - /// - /// This method determines if there is a touch and if so it will provide - /// the screen-relative touch coordinates. This method can be used in - /// a manner similar to Serial.readable(), to determine if there was a - /// touch and indicate that - but not care about the coordinates. Alternately, - /// if a valid pointer to a point_t is provided, then if a touch is detected - /// the point_t will be populated with data. - /// - /// @code - /// Timer t; - /// t.start(); - /// do { - /// point_t point = {0, 0}; - /// if (display.TouchPanelReadable(&point)) { - /// display.pixel(point, Red); - /// } - /// } while (t.read_ms() < 30000); - /// @endcode - /// - /// @param[in, out] TouchPoint is a pointer to a point_t, which is set as the touch point, if a touch is registered. - /// @returns a value indicating the state of the touch, - /// - no_cal: no calibration matrix is available, touch coordinates are not returned. - /// - no_touch: no touch is detected, touch coordinates are not returned. - /// - touch: touch is detected, touch coordinates are returned. - /// - held: held after touch, touch coordinates are returned. - /// - release: indicates a release, touch coordinates are returned. - /// - TouchCode_t TouchPanelReadable(point_t * TouchPoint = NULL); - - /// Wait for a touch panel touch and return it. /// /// This method is similar to Serial.getc() in that it will wait for a touch @@ -2023,9 +2049,10 @@ /// Then, the PrintScreen(x,y,w,h) method is called. Each chunk of data in the /// BMP file to be created is passed to this callback. /// - /// @param callback is the callback function. + /// @param callback is the optional callback function. Without a callback function + /// it will unregister the handler. /// - void AttachPrintHandler(PrintCallback_T callback) { c_callback = callback; } + void AttachPrintHandler(PrintCallback_T callback = NULL) { c_callback = callback; } /// PrintScreen callback registration. /// @@ -2063,6 +2090,18 @@ /// RetCode_t PrintScreen(uint16_t layer, loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP); + /// idle callback registration. + /// + /// This method attaches a simple c-compatible callback of type XXXXXXXXXXX. + /// Then, at any time when the display driver is waiting, it will call the + /// registered function. This is probably most useful if you want to service + /// a watchdog, when you may have called an API that will "hang" waiting + /// on the user. + /// + /// @param callback is the idle callback function. Without a callback function + /// it will unregister the handler. + /// + void AttachIdleHandler(IdleCallback_T callback = NULL) { idle_callback = callback; } #ifdef PERF_METRICS /// Clear the performance metrics to zero. @@ -2281,6 +2320,8 @@ 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 Tue May 17 22:33:06 2016 +0000 +++ b/RA8875_Touch.cpp Mon Jul 25 10:55:58 2016 +0000 @@ -6,8 +6,6 @@ #define NOTOUCH_TIMEOUT_uS 100000 #define TOUCH_TICKER_uS 1000 -// ### Touch Panel support code additions begin here - RetCode_t RA8875::TouchPanelInit(void) { //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock @@ -67,13 +65,11 @@ // | | // +----------------------------------------------------+ - RetCode_t RA8875::TouchPanelCalibrate(tpMatrix_t * matrix) { return TouchPanelCalibrate(NULL, matrix); } - RetCode_t RA8875::TouchPanelCalibrate(const char * msg, tpMatrix_t * matrix, int maxwait_s) { point_t pTest[3]; @@ -82,8 +78,14 @@ Timer timeout; // timeout guards for not-installed, stuck, user not present... timeout.start(); - while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) + while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { wait_ms(20); + if (idle_callback) { + if (external_abort == (*idle_callback)(touchcal_wait)) { + return external_abort; + } + } + } cls(); if (msg) puts(msg); @@ -97,17 +99,36 @@ printf(" (%3d,%3d) => ", pTest[i].x, pTest[i].y); line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, White); line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, White); - while (!TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) + while (!TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { wait_ms(20); + if (idle_callback) { + if (external_abort == (*idle_callback)(touchcal_wait)) { + return external_abort; + } + } + } pSample[i].x = x; pSample[i].y = y; line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, Black); line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Black); foreground(Blue); printf(" (%4d,%4d)\r\n", x,y); - while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) + while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { wait_ms(20); - wait(2); + if (idle_callback) { + if (external_abort == (*idle_callback)(touchcal_wait)) { + return external_abort; + } + } + } + for (int t=0; t<100; t++) { + wait_ms(20); + if (idle_callback) { + if (external_abort == (*idle_callback)(touchcal_wait)) { + return external_abort; + } + } + } } if (timeout.read() >= maxwait_s) return touch_cal_timeout; @@ -118,7 +139,7 @@ /********************************************************************** * - * Function: getDisplayPoint() + * Function: TouchPanelReadable() * * Description: Given a valid set of calibration factors and a point * value reported by the touch screen, this function @@ -204,14 +225,24 @@ TouchCode_t RA8875::TouchPanelGet(point_t * TouchPoint) { - TouchCode_t t; + TouchCode_t t = no_touch; - do { + while (true) { t = TouchPanelReadable(TouchPoint); - } while (t == no_touch); + if (t != no_touch) + break; + if (idle_callback) { + if (external_abort == (*idle_callback)(touch_wait)) { + return no_touch; + } + } + } return t; } +// Below here are primarily "helper" functions. While many are accessible +// to the user code, they usually don't need to be called. + RetCode_t RA8875::TouchPanelSetMatrix(tpMatrix_t * matrixPtr) { if (matrixPtr == NULL || matrixPtr->Divider == 0) @@ -221,7 +252,6 @@ return noerror; } - static void InsertionSort(int * buf, int bufsize) { int i, j;