drv_touch.c 6.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * File      : drv_touch.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2018 RT-Thread Develop Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-10-03     xuzhuoyi     first implementation.
 */

#include "drv_touch.h"
#include "drivers/i2c.h"

18 19 20 21
#ifdef PKG_USING_LITTLEVGL2RTT
#include "littlevgl2rtt.h"
#endif

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

#define TSC_I2C_ADDR    0x41            /* 7-bit I2C address                  */

static struct rt_i2c_bus_device *stmpe811_i2c_bus;


/**
  \fn          int32_t touch_readRegister (uint8_t reg, uint8_t *val)
  \brief       Read register value from Touchscreen controller
  \param[in]   reg    Register address
  \param[out]  val    Pointer where data will be read from register
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
static int32_t touch_read (uint8_t reg, uint8_t *val)
{
    struct rt_i2c_msg msgs[2];

    msgs[0].addr  = TSC_I2C_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf   = ®
    msgs[0].len   = 1;

    msgs[1].addr  = TSC_I2C_ADDR;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf   = val;
    msgs[1].len   = 1;

    if (rt_i2c_transfer(stmpe811_i2c_bus, msgs, 2) == 2)
    {
        return RT_EOK;
    }
    else
    {
        return -RT_ERROR;
    }

}

/**
  \fn          int32_t touch_writeData (uint8_t reg, const uint8_t *val)
  \brief       Write value to Touchscreen controller register
  \param[in]   reg    Register address
  \param[in]   val    Pointer with data to write to register
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
71
static int32_t touch_write(uint8_t reg, uint8_t val)
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
{
    struct rt_i2c_msg msgs;
    rt_uint8_t buf[2] = {reg, val};

    msgs.addr  = TSC_I2C_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf   = buf;
    msgs.len   = 2;

    if (rt_i2c_transfer(stmpe811_i2c_bus, &msgs, 1) == 1)
    {
    return RT_EOK;
    }
    else
    {
    return -RT_ERROR;
    }

}


/**
  \fn          int32_t Touch_Initialize (void)
  \brief       Initialize touchscreen
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
100
static rt_err_t stmpe811_touch_init(rt_device_t dev)
101
{
102
    stmpe811_i2c_bus = rt_i2c_bus_device_find("touch");
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

//    ptrI2C->Initialize  (NULL);
//    ptrI2C->PowerControl(ARM_POWER_FULL);
//    ptrI2C->Control     (ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
//    ptrI2C->Control     (ARM_I2C_BUS_CLEAR, 0);

    touch_write(STMPE811_SYS_CTRL1,      0x02); /* Reset Touch-screen controller */
    rt_thread_mdelay(10);                              /* Wait 10ms                     */


    touch_write(STMPE811_SYS_CTRL2,      0x0C); /* Enable TSC and ADC            */
    touch_write(STMPE811_ADC_CTRL1,      0x68); /* Set sample time , 12-bit mode */
    rt_thread_mdelay(1);                               /* Wait 1ms                      */

    touch_write(STMPE811_ADC_CTRL2,      0x01); /* ADC frequency 3.25 MHz        */
    touch_write(STMPE811_TSC_CFG,        0xC2); /* Detect delay 10us,
                                                 Settle time 500us             */
    touch_write(STMPE811_FIFO_TH,        0x01); /* Threshold for FIFO            */
    touch_write(STMPE811_FIFO_STA,       0x01); /* FIFO reset                    */
    touch_write(STMPE811_FIFO_STA,       0x00); /* FIFO not reset                */
    touch_write(STMPE811_TSC_FRACTION_Z, 0x07); /* Fraction z                    */
    touch_write(STMPE811_TSC_I_DRIVE,    0x01); /* Drive 50 mA typical           */
    touch_write(STMPE811_GPIO_AF,        0x00); /* Pins are used for touchscreen */
    touch_write(STMPE811_TSC_CTRL,       0x01); /* Enable TSC                    */

    return 0;
}

/**
  \fn          int32_t Touch_Uninitialize (void)
  \brief       De-initialize touchscreen
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
138
int32_t touch_uninitialize (void) {
139 140 141 142 143 144 145 146 147 148 149 150
  touch_write(STMPE811_SYS_CTRL1, 0x02);  /* Reset Touch-screen controller    */
  return 0;
}

/**
  \fn          int32_t Touch_GetState (TOUCH_STATE *pState)
  \brief       Get touchscreen state
  \param[out]  pState  pointer to TOUCH_STATE structure
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
151
int32_t touch_get_state(struct touch_state *state)
152
{
153 154 155 156
    uint8_t val;
    uint8_t num;
    uint8_t xyz[4];
    int32_t res;
157
    struct rt_i2c_msg msgs[2];
158 159 160 161

    /* Read touch status */
    res = touch_read(STMPE811_TSC_CTRL, &val);
    if (res < 0) return -1;
162
    state->pressed = (val & (1 << 7)) ? 1 : 0;
163
  
164
    if (state->pressed)
165 166 167 168 169 170 171 172 173
    {
        val = STMPE811_TSC_DATA;

        /* If FIFO overflow, discard all samples except the last one */
        res = touch_read(STMPE811_FIFO_SIZE, &num);
        if (res < 0 || num == 0) return -1;

        while (num--)
        {
174 175 176 177
            msgs[0].addr  = TSC_I2C_ADDR;
            msgs[0].flags = RT_I2C_WR;
            msgs[0].buf   = &val;
            msgs[0].len   = 1;
178

179
            //rt_i2c_transfer(stmpe811_i2c_bus, &msgs, 1);
180 181
          //ptrI2C->MasterTransmit (TSC_I2C_ADDR, &val, 1, true);
          //while (ptrI2C->GetStatus().busy);
182 183 184 185 186
            msgs[1].addr  = TSC_I2C_ADDR;
            msgs[1].flags = RT_I2C_RD;
            msgs[1].buf   = xyz;
            msgs[1].len   = 4;
            rt_i2c_transfer(stmpe811_i2c_bus, msgs, 2);
187 188 189
          //ptrI2C->MasterReceive (TSC_I2C_ADDR, xyz, 4, false);
          //while (ptrI2C->GetStatus().busy);
        }
190 191
        state->x =  (int16_t)((xyz[0] << 4) | ((xyz[1] & 0xF0) >> 4));
        state->y =  (int16_t) (xyz[2]       | ((xyz[1] & 0x0F) << 8));
192 193 194
    }
    else
    {
195
        /* Clear all data in FIFO */
196 197 198 199 200 201
        touch_write(STMPE811_FIFO_STA, 0x1);
        touch_write(STMPE811_FIFO_STA, 0x0);
    }

    return 0;
}
202 203 204

void touch_show_state()
{
205 206
    int16_t x;
    int16_t y;
207 208
    struct touch_state ts;
    touch_get_state(&ts);
209 210
    x = (3706 - ts.x) / 14;
    y = (-461 + ts.y) / 10.5;
211
    rt_kprintf("[drv_touch] touch_show_state, x: %d, y: %d, pressed: %d, padding: %d\n", ts.x , ts.y, ts.pressed, ts.padding);
212
    rt_kprintf("[drv_touch] touch_show_state, phy x: %d, phy y: %d\n", x , y);
213 214 215
}
MSH_CMD_EXPORT(touch_show_state, show screen coordinate in touching);

216 217 218
static int rt_hw_touch_init(void)
{
    static struct rt_device touch;
219 220

    /* init device structure */
221 222
    touch.type = RT_Device_Class_Unknown;
    touch.init = stmpe811_touch_init;
223
    touch.user_data = RT_NULL;
224 225

    /* register touch device to RT-Thread */
226
    rt_device_register(&touch, "touch", RT_DEVICE_FLAG_RDWR);
227 228 229 230
    
    return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_touch_init);