浏览代码

add raspi4 dsi and xpt2046 touch driver

bigmagic 4 年之前
父节点
当前提交
f8c8bc1c41

+ 18 - 0
bsp/raspberry-pi/raspi4-32/driver/mbox.c

@@ -49,6 +49,24 @@ int mbox_call(unsigned char ch, int mmu_enable)
     return 0;
 }
 
+int bcm271x_mbox_get_touch(void)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_GET_TOUCHBUF; 
+    mbox[3] = 4;                        // buffer size
+    mbox[4] = 0;                        // len
+
+    mbox[5] = 0;                       // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return (int)(mbox[5] &  ~0xC0000000);
+}
+
 int bcm271x_notify_reboot(void)
 {
     mbox[0] = 7*4;                          // length of the message

+ 6 - 0
bsp/raspberry-pi/raspi4-32/driver/mbox.h

@@ -132,6 +132,11 @@ enum {
 #define MBOX_TAG_NOTIFY_REBOOT         0x00030048
 #define MBOX_TAG_NOTIFY_XHCI_RESET     0x00030058
 
+/*
+* touch
+*/
+#define MBOX_TAG_GET_TOUCHBUF          (0x0004000F)
+
 #define MBOX_ADDR 0x08000000
 
 #define    RES_CLK_ID           (0x000000000)
@@ -147,6 +152,7 @@ enum {
 #define    PWM_CLK_ID           (0x00000000a)
 
 int mbox_call(unsigned char ch, int mmu_enable);
+int bcm271x_mbox_get_touch(void);
 int bcm271x_notify_reboot(void);
 int bcm271x_notify_xhci_reset(void);
 int bcm271x_gpu_enable(void);

+ 16 - 0
bsp/raspberry-pi/raspi4-32/driver/touch/Sconscript

@@ -0,0 +1,16 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if not GetDepend('BSP_USING_XPT_TOUCH_DEV'):
+    SrcRemove(src, ['drv_xpt2046.c'])
+if not GetDepend('BSP_USING_DSI_TOUCH_DEV'):
+    SrcRemove(src, ['drv_dsi_touch.c'])
+
+group = DefineGroup('drv_touch', src, depend = ['BSP_USING_TOUCH'], CPPPATH = CPPPATH)
+
+Return('group')

+ 125 - 0
bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.c

@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-11-26     bigmagic       first version
+ */
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <touch.h>
+
+#include "mbox.h"
+#include "drv_dsi_touch.h"
+
+#define DBG_TAG "dsi_touch"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static rt_touch_t touch_device = RT_NULL;
+static struct rt_semaphore dsi_touch_ack;
+
+static rt_uint32_t touch_x;
+static rt_uint32_t touch_y;
+static rt_uint32_t touch_state;
+
+static rt_thread_t dsi_touch_tid = RT_NULL;
+#define DSI_TOUCH_THREAD_STACK_SIZE     (4096)
+#define DSI_TOUCH_THREAD_PRIORITY       (25)
+#define DSI_TOUCH_THREAD_TIMESLICE      (10)
+
+#define MAXIMUM_SUPPORTED_POINTS        (10)
+
+struct touch_regs
+{
+    uint8_t device_mode;
+    uint8_t gesture_id;
+    uint8_t num_points;
+    struct touch
+    {
+        uint8_t xh;
+        uint8_t xl;
+        uint8_t yh;
+        uint8_t yl;
+        uint8_t res1;
+        uint8_t res2;
+    } point[MAXIMUM_SUPPORTED_POINTS];
+};
+
+static void dsi_touch_thread_entry(void *param)
+{
+    static volatile uint32_t touchbuf;
+    touchbuf = bcm271x_mbox_get_touch(); //0x0f436000
+    while (1)
+    {
+        struct touch_regs *regs = (struct touch_regs *)touchbuf;
+        if ((regs->num_points > 0) && (regs->num_points < MAXIMUM_SUPPORTED_POINTS))
+        {
+            //only one touch point
+            touch_x = (((int)regs->point[0].xh & 0xf) << 8) + regs->point[0].xl;
+            touch_y = (((int)regs->point[0].yh & 0xf) << 8) + regs->point[0].yl;
+            touch_state = 1;
+        }
+        else
+        {
+            touch_state = 0;
+        }
+        rt_thread_mdelay(50); 
+    }
+}
+
+static rt_size_t dsi_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
+{
+    rt_uint16_t* touchxy = (rt_uint16_t *)buf;
+    if((read_num != 0) && (touch_state == 1))
+    {
+        touchxy[0] = touch_x;
+        touchxy[1] = touch_y;
+        touch_state = 0;
+        return read_num;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static rt_err_t dsi_control(struct rt_touch_device *device, int cmd, void *data)
+{
+    return RT_EOK;
+}
+
+static struct rt_touch_ops dsi_touch_ops =
+{
+    .touch_readpoint = dsi_read_point,
+    .touch_control = dsi_control,
+};
+
+static int hw_dsi_touch_init(void)
+{
+    //touch sem
+    rt_sem_init(&dsi_touch_ack, "dsi_touch_ack", 0, RT_IPC_FLAG_FIFO);
+
+    dsi_touch_tid = rt_thread_create("dsi_touch",
+                            dsi_touch_thread_entry, RT_NULL,
+                            DSI_TOUCH_THREAD_STACK_SIZE,
+                            DSI_TOUCH_THREAD_PRIORITY, DSI_TOUCH_THREAD_TIMESLICE);
+    if (dsi_touch_tid != RT_NULL)
+        rt_thread_startup(dsi_touch_tid);
+
+    touch_device = (rt_touch_t)rt_calloc(1, sizeof(struct rt_touch_device));
+
+    if (touch_device == RT_NULL)
+        return -RT_ERROR;
+
+    /* register touch device */
+    touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
+    touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
+    //rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
+    touch_device->ops = &dsi_touch_ops;
+    rt_hw_touch_register(touch_device, "dsi_touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
+    return 0;
+}
+INIT_DEVICE_EXPORT(hw_dsi_touch_init);

+ 13 - 0
bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-11-26     bigmagic       first version
+ */
+#ifndef __DRV_DSI_TOUCH_H__
+#define __DRV_DSI_TOUCH_H__
+
+#endif//DSI TOUCH

+ 252 - 0
bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.c

@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-11-08     bigmagic       first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <touch.h>
+
+#include "drv_xpt2046.h"
+//http://www.lcdwiki.com/MHS-3.5inch_RPi_Display
+
+#define DBG_TAG "xpt2046"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+//XPT2049
+#define     READ_X                (0xD0)
+#define     READ_Y                (0x90)
+
+#define     TFT_WIDTH             (320)
+#define     TFT_HEIGHT            (480)
+//freq
+#define     TOUCH_SPI_MAX_FREQ    (10*1000)
+
+#define     TP_IRQ_PIN            (17)
+#define     TOUCH_DEVICE_NAME     ("spi0.1")
+
+static struct rt_semaphore touch_ack;
+static rt_touch_t touch_device = RT_NULL;
+
+static rt_thread_t touch_tid = RT_NULL;
+#define TOUCH_THREAD_STACK_SIZE     (1024)
+#define TOUCH_THREAD_PRIORITY       (30)
+#define TOUCH_THREAD_TIMESLICE      (10)
+
+rt_uint8_t touch_flag = 0;
+rt_uint16_t touch_x_val = 0;
+rt_uint16_t touch_y_val = 0;
+
+extern struct rt_semaphore lcd_spi_lock;
+static void touch_read_x_y(void *dev, rt_uint16_t *x, rt_uint16_t *y)
+{
+    struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
+    struct rt_spi_message msg1,msg2,msg3,msg4;
+    rt_uint16_t readx_val = 0,ready_val = 0;
+    rt_uint8_t readx[2];
+    rt_uint8_t ready[2];
+    rt_sem_take(&lcd_spi_lock, RT_WAITING_FOREVER);
+
+    int read_x_id = READ_X;
+    int read_y_id = READ_Y;
+
+    msg1.send_buf   = &read_x_id;
+    msg1.recv_buf   = RT_NULL;
+    msg1.length     = 1;
+    msg1.cs_take    = 1;
+    msg1.cs_release = 0;
+    msg1.next       = &msg2;
+
+    msg2.send_buf   = RT_NULL;
+    msg2.recv_buf   = &readx[0];
+    msg2.length     = 2;
+    msg2.cs_take    = 0;
+    msg2.cs_release = 0;
+    msg2.next       = &msg3;
+
+    msg3.send_buf   = &read_y_id;
+    msg3.recv_buf   = RT_NULL;
+    msg3.length     = 1;
+    msg3.cs_take    = 0;
+    msg3.cs_release = 0;
+    msg3.next       = &msg4;
+
+    msg4.send_buf   = RT_NULL;
+    msg4.recv_buf   = &ready[0];
+    msg4.length     = 2;
+    msg4.cs_take    = 0;
+    msg4.cs_release = 1;
+    msg4.next       = RT_NULL;
+
+    rt_spi_transfer_message(touch_dev, &msg1);
+
+    readx_val = ((readx[0] << 8) | readx[1]) >> 4;
+    ready_val = ((ready[0] << 8) | ready[1]) >> 4;
+
+    rt_sem_release(&lcd_spi_lock);
+    *x = readx_val;
+    *y = ready_val;
+}
+
+/*
+XPT2046:Width:320 High:480
+no pressed:(0x800,0xfff)
+---ETH----USB-----------------------
+| (0x800,0x800)      (0xfff,0x800) |
+|                                  |
+| (0x800,0xFFF)      (0xfff,0xfff) |
+------------------------------------
+*/
+#define XMIN 0x800
+#define YMAX 0xfff 
+void read_tp(void *dev, rt_uint16_t *x, rt_uint16_t *y)
+{
+    struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
+    rt_uint8_t try = 0;
+    uint16_t _y[5] = {0,0,0,0,0};
+    uint16_t _x[5] = {0,0,0,0,0};
+    uint16_t x_val = 0;
+    uint16_t y_val = 0;
+    uint16_t cur_x = 0;
+    uint16_t cur_y = 0;
+    int index = 0;
+
+    while(1)
+    {
+        try = try + 1;
+        touch_read_x_y(touch_dev, x, y);
+        if((*x > XMIN) && (*y < YMAX))
+        {
+            _x[index] = *x;
+            _y[index] = *y;
+            index = index + 1;
+        }
+        if(index == 5)
+        {
+            break;
+        }
+
+        if(try > 10)
+        {
+            break;
+        }
+    }
+
+    x_val = (_x[0] + _x[1] + _x[2] + _x[3]+ _x[4]) / index;
+    y_val = (_y[0] + _y[1] + _y[2] + _y[3]+ _y[4]) / index;
+
+    cur_x = (x_val - 0x800) * TFT_WIDTH / 0x800;
+    cur_y = (y_val - 0x800) * TFT_HEIGHT / 0x800;
+
+    if((cur_x < TFT_WIDTH) && (cur_y < TFT_HEIGHT))
+    {
+        *x = TFT_WIDTH - cur_x;
+        *y = TFT_HEIGHT - cur_y;
+    }
+    else
+    {
+        *x = 0;
+        *y = 0;
+    }
+}
+
+static void touch_thread_entry(void *param)
+{
+    rt_uint16_t x,y;
+    struct rt_spi_device *touch_dev;
+    touch_dev = (struct rt_spi_device *)rt_device_find(TOUCH_DEVICE_NAME);
+    touch_dev->config.max_hz = TOUCH_SPI_MAX_FREQ;
+    if (!touch_dev)
+    {
+        rt_kprintf("no %s!\n", TOUCH_DEVICE_NAME);
+    }
+
+    while (1)
+    {
+        rt_sem_take(&touch_ack, RT_WAITING_FOREVER);
+        read_tp(touch_dev, &x, &y);
+        if((x!= 0) && (y !=0))
+        {
+            touch_x_val = x;
+            touch_y_val = y;
+            touch_flag = 1;
+        }
+        rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
+    }
+}
+
+static void touch_readly(void *args)
+{
+    if(rt_pin_read(TP_IRQ_PIN) == PIN_LOW)
+    {
+        rt_pin_mode(TP_IRQ_PIN, PIN_MODE_OUTPUT);
+        rt_pin_write(TP_IRQ_PIN,PIN_HIGH);
+        rt_sem_release(&touch_ack);
+    }
+}
+
+static rt_size_t xpt2046_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
+{
+    rt_uint16_t* touchxy = (rt_uint16_t *)buf;
+    if((read_num != 0) && (touch_flag == 1))
+    {
+        touchxy[0] = touch_x_val;
+        touchxy[1] = touch_y_val;
+        touch_flag = 0;
+        return read_num;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static rt_err_t xpt2046_control(struct rt_touch_device *device, int cmd, void *data)
+{
+    return RT_EOK;
+}
+
+static struct rt_touch_ops touch_ops =
+{
+    .touch_readpoint = xpt2046_read_point,
+    .touch_control = xpt2046_control,
+};
+
+static int hw_xpt2049_touch_init(void)
+{
+    //touch sem
+    rt_sem_init(&touch_ack, "touch_ack", 0, RT_IPC_FLAG_FIFO);
+
+    touch_tid = rt_thread_create("touch",
+                            touch_thread_entry, RT_NULL,
+                            TOUCH_THREAD_STACK_SIZE,
+                            TOUCH_THREAD_PRIORITY, TOUCH_THREAD_TIMESLICE);
+    if (touch_tid != RT_NULL)
+        rt_thread_startup(touch_tid);
+
+    rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
+    rt_pin_attach_irq(TP_IRQ_PIN, PIN_IRQ_MODE_LOW_LEVEL, touch_readly, RT_NULL);
+    rt_pin_irq_enable(TP_IRQ_PIN, PIN_IRQ_ENABLE);
+
+    touch_device = (rt_touch_t)rt_calloc(1, sizeof(struct rt_touch_device));
+
+    if (touch_device == RT_NULL)
+        return -RT_ERROR;
+
+    /* register touch device */
+    touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
+    touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
+    //rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
+    touch_device->ops = &touch_ops;
+
+    rt_hw_touch_register(touch_device, "xpt2046", RT_DEVICE_FLAG_INT_RX, RT_NULL);
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(hw_xpt2049_touch_init);

+ 13 - 0
bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-11-08     bigmagic       first version
+ */
+#ifndef __DRV_XPT2046_H__
+#define __DRV_XPT2046_H__
+
+#endif//XPT2046