NXP Touch Cursor example for LPCXpresso54608, modified for use with Mbed OS.
The tutorial for this example can be found here: https://os.mbed.com/blog/entry/How-to-LPCXpresso54608-touch-panel/
touchpanel/fsl_ft5406.cpp@0:c107a6f8c368, 2018-04-11 (annotated)
- Committer:
- jplunkett
- Date:
- Wed Apr 11 20:46:55 2018 +0000
- Revision:
- 0:c107a6f8c368
Init
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jplunkett | 0:c107a6f8c368 | 1 | /* |
jplunkett | 0:c107a6f8c368 | 2 | * The Clear BSD License |
jplunkett | 0:c107a6f8c368 | 3 | * Copyright (c) 2016, Freescale Semiconductor, Inc. |
jplunkett | 0:c107a6f8c368 | 4 | * Copyright 2016-2017 NXP |
jplunkett | 0:c107a6f8c368 | 5 | * All rights reserved. |
jplunkett | 0:c107a6f8c368 | 6 | * |
jplunkett | 0:c107a6f8c368 | 7 | * Redistribution and use in source and binary forms, with or without modification, |
jplunkett | 0:c107a6f8c368 | 8 | * are permitted (subject to the limitations in the disclaimer below) provided |
jplunkett | 0:c107a6f8c368 | 9 | * that the following conditions are met: |
jplunkett | 0:c107a6f8c368 | 10 | * |
jplunkett | 0:c107a6f8c368 | 11 | * o Redistributions of source code must retain the above copyright notice, this list |
jplunkett | 0:c107a6f8c368 | 12 | * of conditions and the following disclaimer. |
jplunkett | 0:c107a6f8c368 | 13 | * |
jplunkett | 0:c107a6f8c368 | 14 | * o Redistributions in binary form must reproduce the above copyright notice, this |
jplunkett | 0:c107a6f8c368 | 15 | * list of conditions and the following disclaimer in the documentation and/or |
jplunkett | 0:c107a6f8c368 | 16 | * other materials provided with the distribution. |
jplunkett | 0:c107a6f8c368 | 17 | * |
jplunkett | 0:c107a6f8c368 | 18 | * o Neither the name of the copyright holder nor the names of its |
jplunkett | 0:c107a6f8c368 | 19 | * contributors may be used to endorse or promote products derived from this |
jplunkett | 0:c107a6f8c368 | 20 | * software without specific prior written permission. |
jplunkett | 0:c107a6f8c368 | 21 | * |
jplunkett | 0:c107a6f8c368 | 22 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. |
jplunkett | 0:c107a6f8c368 | 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
jplunkett | 0:c107a6f8c368 | 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
jplunkett | 0:c107a6f8c368 | 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
jplunkett | 0:c107a6f8c368 | 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
jplunkett | 0:c107a6f8c368 | 27 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
jplunkett | 0:c107a6f8c368 | 28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
jplunkett | 0:c107a6f8c368 | 29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
jplunkett | 0:c107a6f8c368 | 30 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
jplunkett | 0:c107a6f8c368 | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
jplunkett | 0:c107a6f8c368 | 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
jplunkett | 0:c107a6f8c368 | 33 | */ |
jplunkett | 0:c107a6f8c368 | 34 | |
jplunkett | 0:c107a6f8c368 | 35 | #include "fsl_common.h" |
jplunkett | 0:c107a6f8c368 | 36 | //#include "fsl_debug_console.h" |
jplunkett | 0:c107a6f8c368 | 37 | #include "fsl_i2c.h" |
jplunkett | 0:c107a6f8c368 | 38 | #include "fsl_ft5406.h" |
jplunkett | 0:c107a6f8c368 | 39 | |
jplunkett | 0:c107a6f8c368 | 40 | typedef struct _ft5406_touch_point |
jplunkett | 0:c107a6f8c368 | 41 | { |
jplunkett | 0:c107a6f8c368 | 42 | uint8_t XH; |
jplunkett | 0:c107a6f8c368 | 43 | uint8_t XL; |
jplunkett | 0:c107a6f8c368 | 44 | uint8_t YH; |
jplunkett | 0:c107a6f8c368 | 45 | uint8_t YL; |
jplunkett | 0:c107a6f8c368 | 46 | uint8_t RESERVED[2]; |
jplunkett | 0:c107a6f8c368 | 47 | } ft5406_touch_point_t; |
jplunkett | 0:c107a6f8c368 | 48 | |
jplunkett | 0:c107a6f8c368 | 49 | typedef struct _ft5406_touch_data |
jplunkett | 0:c107a6f8c368 | 50 | { |
jplunkett | 0:c107a6f8c368 | 51 | uint8_t GEST_ID; |
jplunkett | 0:c107a6f8c368 | 52 | uint8_t TD_STATUS; |
jplunkett | 0:c107a6f8c368 | 53 | ft5406_touch_point_t TOUCH[FT5406_MAX_TOUCHES]; |
jplunkett | 0:c107a6f8c368 | 54 | } ft5406_touch_data_t; |
jplunkett | 0:c107a6f8c368 | 55 | |
jplunkett | 0:c107a6f8c368 | 56 | #define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6)) |
jplunkett | 0:c107a6f8c368 | 57 | #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4) |
jplunkett | 0:c107a6f8c368 | 58 | #define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL) |
jplunkett | 0:c107a6f8c368 | 59 | #define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL) |
jplunkett | 0:c107a6f8c368 | 60 | |
jplunkett | 0:c107a6f8c368 | 61 | status_t FT5406_Init(ft5406_handle_t *handle, I2C_Type *base) |
jplunkett | 0:c107a6f8c368 | 62 | { |
jplunkett | 0:c107a6f8c368 | 63 | i2c_master_transfer_t *xfer = &(handle->xfer); |
jplunkett | 0:c107a6f8c368 | 64 | status_t status; |
jplunkett | 0:c107a6f8c368 | 65 | uint8_t mode; |
jplunkett | 0:c107a6f8c368 | 66 | |
jplunkett | 0:c107a6f8c368 | 67 | assert(handle); |
jplunkett | 0:c107a6f8c368 | 68 | assert(base); |
jplunkett | 0:c107a6f8c368 | 69 | |
jplunkett | 0:c107a6f8c368 | 70 | if (!handle || !base) |
jplunkett | 0:c107a6f8c368 | 71 | { |
jplunkett | 0:c107a6f8c368 | 72 | return kStatus_InvalidArgument; |
jplunkett | 0:c107a6f8c368 | 73 | } |
jplunkett | 0:c107a6f8c368 | 74 | |
jplunkett | 0:c107a6f8c368 | 75 | handle->base = base; |
jplunkett | 0:c107a6f8c368 | 76 | |
jplunkett | 0:c107a6f8c368 | 77 | /* clear transfer structure and buffer */ |
jplunkett | 0:c107a6f8c368 | 78 | memset(xfer, 0, sizeof(*xfer)); |
jplunkett | 0:c107a6f8c368 | 79 | memset(handle->touch_buf, 0, FT5406_TOUCH_DATA_LEN); |
jplunkett | 0:c107a6f8c368 | 80 | |
jplunkett | 0:c107a6f8c368 | 81 | /* set device mode to normal operation */ |
jplunkett | 0:c107a6f8c368 | 82 | mode = 0; |
jplunkett | 0:c107a6f8c368 | 83 | xfer->slaveAddress = 0x38; |
jplunkett | 0:c107a6f8c368 | 84 | xfer->direction = kI2C_Write; |
jplunkett | 0:c107a6f8c368 | 85 | xfer->subaddress = 0; |
jplunkett | 0:c107a6f8c368 | 86 | xfer->subaddressSize = 1; |
jplunkett | 0:c107a6f8c368 | 87 | xfer->data = &mode; |
jplunkett | 0:c107a6f8c368 | 88 | xfer->dataSize = 1; |
jplunkett | 0:c107a6f8c368 | 89 | xfer->flags = kI2C_TransferDefaultFlag; |
jplunkett | 0:c107a6f8c368 | 90 | |
jplunkett | 0:c107a6f8c368 | 91 | status = I2C_MasterTransferBlocking(handle->base, &handle->xfer); |
jplunkett | 0:c107a6f8c368 | 92 | |
jplunkett | 0:c107a6f8c368 | 93 | /* prepare transfer structure for reading touch data */ |
jplunkett | 0:c107a6f8c368 | 94 | xfer->slaveAddress = 0x38; |
jplunkett | 0:c107a6f8c368 | 95 | xfer->direction = kI2C_Read; |
jplunkett | 0:c107a6f8c368 | 96 | xfer->subaddress = 1; |
jplunkett | 0:c107a6f8c368 | 97 | xfer->subaddressSize = 1; |
jplunkett | 0:c107a6f8c368 | 98 | xfer->data = handle->touch_buf; |
jplunkett | 0:c107a6f8c368 | 99 | xfer->dataSize = FT5406_TOUCH_DATA_LEN; |
jplunkett | 0:c107a6f8c368 | 100 | xfer->flags = kI2C_TransferDefaultFlag; |
jplunkett | 0:c107a6f8c368 | 101 | |
jplunkett | 0:c107a6f8c368 | 102 | return status; |
jplunkett | 0:c107a6f8c368 | 103 | } |
jplunkett | 0:c107a6f8c368 | 104 | |
jplunkett | 0:c107a6f8c368 | 105 | status_t FT5406_Denit(ft5406_handle_t *handle) |
jplunkett | 0:c107a6f8c368 | 106 | { |
jplunkett | 0:c107a6f8c368 | 107 | assert(handle); |
jplunkett | 0:c107a6f8c368 | 108 | |
jplunkett | 0:c107a6f8c368 | 109 | if (!handle) |
jplunkett | 0:c107a6f8c368 | 110 | { |
jplunkett | 0:c107a6f8c368 | 111 | return kStatus_InvalidArgument; |
jplunkett | 0:c107a6f8c368 | 112 | } |
jplunkett | 0:c107a6f8c368 | 113 | |
jplunkett | 0:c107a6f8c368 | 114 | handle->base = NULL; |
jplunkett | 0:c107a6f8c368 | 115 | return kStatus_Success; |
jplunkett | 0:c107a6f8c368 | 116 | } |
jplunkett | 0:c107a6f8c368 | 117 | |
jplunkett | 0:c107a6f8c368 | 118 | status_t FT5406_ReadTouchData(ft5406_handle_t *handle) |
jplunkett | 0:c107a6f8c368 | 119 | { |
jplunkett | 0:c107a6f8c368 | 120 | assert(handle); |
jplunkett | 0:c107a6f8c368 | 121 | |
jplunkett | 0:c107a6f8c368 | 122 | if (!handle) |
jplunkett | 0:c107a6f8c368 | 123 | { |
jplunkett | 0:c107a6f8c368 | 124 | return kStatus_InvalidArgument; |
jplunkett | 0:c107a6f8c368 | 125 | } |
jplunkett | 0:c107a6f8c368 | 126 | |
jplunkett | 0:c107a6f8c368 | 127 | return I2C_MasterTransferBlocking(handle->base, &handle->xfer); |
jplunkett | 0:c107a6f8c368 | 128 | } |
jplunkett | 0:c107a6f8c368 | 129 | |
jplunkett | 0:c107a6f8c368 | 130 | status_t FT5406_GetSingleTouch(ft5406_handle_t *handle, touch_event_t *touch_event, int *touch_x, int *touch_y) |
jplunkett | 0:c107a6f8c368 | 131 | { |
jplunkett | 0:c107a6f8c368 | 132 | status_t status; |
jplunkett | 0:c107a6f8c368 | 133 | touch_event_t touch_event_local; |
jplunkett | 0:c107a6f8c368 | 134 | |
jplunkett | 0:c107a6f8c368 | 135 | status = FT5406_ReadTouchData(handle); |
jplunkett | 0:c107a6f8c368 | 136 | |
jplunkett | 0:c107a6f8c368 | 137 | if (status == kStatus_Success) |
jplunkett | 0:c107a6f8c368 | 138 | { |
jplunkett | 0:c107a6f8c368 | 139 | ft5406_touch_data_t *touch_data = (ft5406_touch_data_t *)(void *)(handle->touch_buf); |
jplunkett | 0:c107a6f8c368 | 140 | |
jplunkett | 0:c107a6f8c368 | 141 | if (touch_event == NULL) |
jplunkett | 0:c107a6f8c368 | 142 | { |
jplunkett | 0:c107a6f8c368 | 143 | touch_event = &touch_event_local; |
jplunkett | 0:c107a6f8c368 | 144 | } |
jplunkett | 0:c107a6f8c368 | 145 | *touch_event = TOUCH_POINT_GET_EVENT(touch_data->TOUCH[0]); |
jplunkett | 0:c107a6f8c368 | 146 | |
jplunkett | 0:c107a6f8c368 | 147 | /* Update coordinates only if there is touch detected */ |
jplunkett | 0:c107a6f8c368 | 148 | if ((*touch_event == kTouch_Down) || (*touch_event == kTouch_Contact)) |
jplunkett | 0:c107a6f8c368 | 149 | { |
jplunkett | 0:c107a6f8c368 | 150 | if (touch_x) |
jplunkett | 0:c107a6f8c368 | 151 | { |
jplunkett | 0:c107a6f8c368 | 152 | *touch_x = TOUCH_POINT_GET_X(touch_data->TOUCH[0]); |
jplunkett | 0:c107a6f8c368 | 153 | } |
jplunkett | 0:c107a6f8c368 | 154 | if (touch_y) |
jplunkett | 0:c107a6f8c368 | 155 | { |
jplunkett | 0:c107a6f8c368 | 156 | *touch_y = TOUCH_POINT_GET_Y(touch_data->TOUCH[0]); |
jplunkett | 0:c107a6f8c368 | 157 | } |
jplunkett | 0:c107a6f8c368 | 158 | } |
jplunkett | 0:c107a6f8c368 | 159 | } |
jplunkett | 0:c107a6f8c368 | 160 | |
jplunkett | 0:c107a6f8c368 | 161 | return status; |
jplunkett | 0:c107a6f8c368 | 162 | } |
jplunkett | 0:c107a6f8c368 | 163 | |
jplunkett | 0:c107a6f8c368 | 164 | status_t FT5406_GetMultiTouch(ft5406_handle_t *handle, int *touch_count, touch_point_t touch_array[FT5406_MAX_TOUCHES]) |
jplunkett | 0:c107a6f8c368 | 165 | { |
jplunkett | 0:c107a6f8c368 | 166 | status_t status; |
jplunkett | 0:c107a6f8c368 | 167 | |
jplunkett | 0:c107a6f8c368 | 168 | status = FT5406_ReadTouchData(handle); |
jplunkett | 0:c107a6f8c368 | 169 | |
jplunkett | 0:c107a6f8c368 | 170 | if (status == kStatus_Success) |
jplunkett | 0:c107a6f8c368 | 171 | { |
jplunkett | 0:c107a6f8c368 | 172 | ft5406_touch_data_t *touch_data = (ft5406_touch_data_t *)(void *)(handle->touch_buf); |
jplunkett | 0:c107a6f8c368 | 173 | int i; |
jplunkett | 0:c107a6f8c368 | 174 | |
jplunkett | 0:c107a6f8c368 | 175 | /* Decode number of touches */ |
jplunkett | 0:c107a6f8c368 | 176 | if (touch_count) |
jplunkett | 0:c107a6f8c368 | 177 | { |
jplunkett | 0:c107a6f8c368 | 178 | *touch_count = touch_data->TD_STATUS; |
jplunkett | 0:c107a6f8c368 | 179 | } |
jplunkett | 0:c107a6f8c368 | 180 | |
jplunkett | 0:c107a6f8c368 | 181 | /* Decode valid touch points */ |
jplunkett | 0:c107a6f8c368 | 182 | for (i = 0; i < touch_data->TD_STATUS; i++) |
jplunkett | 0:c107a6f8c368 | 183 | { |
jplunkett | 0:c107a6f8c368 | 184 | touch_array[i].TOUCH_ID = TOUCH_POINT_GET_ID(touch_data->TOUCH[i]); |
jplunkett | 0:c107a6f8c368 | 185 | touch_array[i].TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data->TOUCH[i]); |
jplunkett | 0:c107a6f8c368 | 186 | touch_array[i].TOUCH_X = TOUCH_POINT_GET_X(touch_data->TOUCH[i]); |
jplunkett | 0:c107a6f8c368 | 187 | touch_array[i].TOUCH_Y = TOUCH_POINT_GET_Y(touch_data->TOUCH[i]); |
jplunkett | 0:c107a6f8c368 | 188 | } |
jplunkett | 0:c107a6f8c368 | 189 | |
jplunkett | 0:c107a6f8c368 | 190 | /* Clear vacant elements of touch_array */ |
jplunkett | 0:c107a6f8c368 | 191 | for (; i < FT5406_MAX_TOUCHES; i++) |
jplunkett | 0:c107a6f8c368 | 192 | { |
jplunkett | 0:c107a6f8c368 | 193 | touch_array[i].TOUCH_ID = 0; |
jplunkett | 0:c107a6f8c368 | 194 | touch_array[i].TOUCH_EVENT = kTouch_Reserved; |
jplunkett | 0:c107a6f8c368 | 195 | touch_array[i].TOUCH_X = 0; |
jplunkett | 0:c107a6f8c368 | 196 | touch_array[i].TOUCH_Y = 0; |
jplunkett | 0:c107a6f8c368 | 197 | } |
jplunkett | 0:c107a6f8c368 | 198 | } |
jplunkett | 0:c107a6f8c368 | 199 | |
jplunkett | 0:c107a6f8c368 | 200 | return status; |
jplunkett | 0:c107a6f8c368 | 201 | } |