From 31c98d83b7027e4ebe64b9ace5533a467a5e9ed3 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 30 May 2017 00:40:17 +0800 Subject: [PATCH] Add mouse support, also add mipi component --- components/mipidisp/component.mk | 2 + components/mipidisp/crc16-ccitt.c | 91 +++++++++ components/mipidisp/crc16-ccitt.h | 35 ++++ components/mipidisp/hexdump.c | 52 ++++++ components/mipidisp/hexdump.h | 2 + components/mipidisp/mipi.c | 299 ++++++++++++++++++++++++++++++ components/mipidisp/mipi.h | 11 ++ components/mipidisp/mipi_dsi.c | 85 +++++++++ components/mipidisp/mipi_dsi.h | 2 + components/tme-esp32/adns9500.c | 105 +++++++++++ components/tme-esp32/adns9500.h | 3 + components/tme-esp32/main.c | 17 +- components/tme-esp32/mipi_lcd.c | 117 ++---------- components/tme/emu.c | 2 +- components/tme/scc.c | 4 +- sdkconfig | 6 +- 16 files changed, 714 insertions(+), 119 deletions(-) create mode 100644 components/mipidisp/component.mk create mode 100644 components/mipidisp/crc16-ccitt.c create mode 100644 components/mipidisp/crc16-ccitt.h create mode 100644 components/mipidisp/hexdump.c create mode 100644 components/mipidisp/hexdump.h create mode 100644 components/mipidisp/mipi.c create mode 100644 components/mipidisp/mipi.h create mode 100644 components/mipidisp/mipi_dsi.c create mode 100644 components/mipidisp/mipi_dsi.h create mode 100644 components/tme-esp32/adns9500.c create mode 100644 components/tme-esp32/adns9500.h diff --git a/components/mipidisp/component.mk b/components/mipidisp/component.mk new file mode 100644 index 0000000..f3e5119 --- /dev/null +++ b/components/mipidisp/component.mk @@ -0,0 +1,2 @@ + +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/components/mipidisp/crc16-ccitt.c b/components/mipidisp/crc16-ccitt.c new file mode 100644 index 0000000..e306c45 --- /dev/null +++ b/components/mipidisp/crc16-ccitt.c @@ -0,0 +1,91 @@ +/* + * Copyright 2001-2010 Georges Menie (www.menie.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "crc16-ccitt.h" + +/* CRC16 implementation acording to CCITT standards */ + +static const unsigned short crc16tab[256]= { + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +}; + +static int invert(int d) { + int q=0; + if (d&0x01) q|=0x80; + if (d&0x02) q|=0x40; + if (d&0x04) q|=0x20; + if (d&0x08) q|=0x10; + if (d&0x10) q|=0x08; + if (d&0x20) q|=0x04; + if (d&0x40) q|=0x02; + if (d&0x80) q|=0x01; + return q; +} + +unsigned short crc16_ccitt(uint16_t oldcrc, const void *buf, int len) +{ + register int counter; + register unsigned short crc = oldcrc; + for( counter = 0; counter < len; counter++) { + char d=*(char *)buf++; + char q=invert(d); + crc = (crc<<8) ^ crc16tab[((crc>>8) ^ q)&0x00FF]; + } + + return (invert(crc>>8))|(invert(crc&0xff)<<8); +} diff --git a/components/mipidisp/crc16-ccitt.h b/components/mipidisp/crc16-ccitt.h new file mode 100644 index 0000000..d41ddaf --- /dev/null +++ b/components/mipidisp/crc16-ccitt.h @@ -0,0 +1,35 @@ +/* + * Copyright 2001-2010 Georges Menie (www.menie.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CRC16_H_ +#define _CRC16_H_ + + +#include +unsigned short crc16_ccitt(uint16_t oldcrc, const void *buf, int len); + +#endif /* _CRC16_H_ */ diff --git a/components/mipidisp/hexdump.c b/components/mipidisp/hexdump.c new file mode 100644 index 0000000..062ea7e --- /dev/null +++ b/components/mipidisp/hexdump.c @@ -0,0 +1,52 @@ +#include +#include +#include + +void hexdump (void *addr, int len) { + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + + + if (len == 0) { + printf(" ZERO LENGTH\n"); + return; + } + if (len < 0) { + printf(" NEGATIVE LENGTH: %i\n",len); + return; + } + + // Process every byte in the data. + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + printf (" %s\n", buff); + + // Output the offset. + printf (" %04x ", i); + } + + // Now the hex code for the specific character. + printf (" %02x", pc[i]); + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + printf (" "); + i++; + } + + // And print the final ASCII bit. + printf (" %s\n", buff); +} diff --git a/components/mipidisp/hexdump.h b/components/mipidisp/hexdump.h new file mode 100644 index 0000000..acf54c3 --- /dev/null +++ b/components/mipidisp/hexdump.h @@ -0,0 +1,2 @@ +void hexdump (void *addr, int len); + diff --git a/components/mipidisp/mipi.c b/components/mipidisp/mipi.c new file mode 100644 index 0000000..504d3d0 --- /dev/null +++ b/components/mipidisp/mipi.c @@ -0,0 +1,299 @@ +#if 1 +/* +Thing to emulate single-lane MIPI using a flipflop and a bunch of resistors. +*/ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_system.h" +#include "driver/spi_common.h" +#include "soc/gpio_struct.h" +#include "soc/spi_struct.h" +#include "soc/spi_reg.h" +#include "driver/gpio.h" +#include "esp_heap_alloc_caps.h" +#include "mipi.h" +#include "hexdump.h" + +//IO pins +#define GPIO_D0N_LS 4 +#define GPIO_D0P_LS 33 +#define GPIO_D0_HS 32 +#define GPIO_CLKP_LS 25 +#define GPIO_CLKN_LS 27 +#define GPIO_FF_NRST 14 +#define GPIO_FF_CLK 12 +#define GPIO_NRST 5 + + + +#define HOST VSPI_HOST +#define IRQSRC ETS_SPI3_DMA_INTR_SOURCE +#define DMACH 2 +#define DESCCNT 8 + +#define SOTEOTWAIT() asm volatile("nop; nop; nop; nop") +//#define SOTEOTWAIT() ets_delay_us(10); + +static spi_dev_t *spidev; +static int cur_idle_desc=0; +static lldesc_t idle_dmadesc[3]; +static lldesc_t data_dmadesc[DESCCNT]; +static SemaphoreHandle_t sem=NULL; + +//ToDo: move these to spi_common... + +static int spi_freq_for_pre_n(int fapb, int pre, int n) { + return (fapb / (pre * n)); +} +/* + * Set the SPI clock to a certain frequency. Returns the effective frequency set, which may be slightly + * different from the requested frequency. + */ +static int spi_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle) { + int pre, n, h, l, eff_clk; + + //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value. + if (hz>((fapb/4)*3)) { + //Using Fapb directly will give us the best result here. + hw->clock.clkcnt_l=0; + hw->clock.clkcnt_h=0; + hw->clock.clkcnt_n=0; + hw->clock.clkdiv_pre=0; + hw->clock.clk_equ_sysclk=1; + eff_clk=fapb; + } else { + //For best duty cycle resolution, we want n to be as close to 32 as possible, but + //we also need a pre/n combo that gets us as close as possible to the intended freq. + //To do this, we bruteforce n and calculate the best pre to go along with that. + //If there's a choice between pre/n combos that give the same result, use the one + //with the higher n. + int bestn=-1; + int bestpre=-1; + int besterr=0; + int errval; + for (n=2; n<=64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse. + //Effectively, this does pre=round((fapb/n)/hz). + pre=((fapb/n)+(hz/2))/hz; + if (pre<=0) pre=1; + if (pre>8192) pre=8192; + errval=abs(spi_freq_for_pre_n(fapb, pre, n)-hz); + if (bestn==-1 || errval<=besterr) { + besterr=errval; + bestn=n; + bestpre=pre; + } + } + + n=bestn; + pre=bestpre; + l=n; + //This effectively does round((duty_cycle*n)/256) + h=(duty_cycle*n+127)/256; + if (h<=0) h=1; + + hw->clock.clk_equ_sysclk=0; + hw->clock.clkcnt_n=n-1; + hw->clock.clkdiv_pre=pre-1; + hw->clock.clkcnt_h=h-1; + hw->clock.clkcnt_l=l-1; + eff_clk=spi_freq_for_pre_n(fapb, pre, n); + } + return eff_clk; +} + +static void spidma_intr(void *arg) { + BaseType_t xHigherPriorityTaskWoken=0; + spidev->dma_int_clr.val=0xFFFFFFFF; //clear all ints + //Data is sent +// ets_printf("int\n"); + + xSemaphoreGiveFromISR(sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) portYIELD_FROM_ISR(); +} + +/* +Brings up the clock and data lines to LP11, resyncs the flipflop, restarts the clock and DMA engine. +*/ +void mipiResync() { + //Get clock and data transceivers back in idle state +// gpio_set_level(GPIO_D0N_LS, 1); +// SOTEOTWAIT(); +// gpio_set_level(GPIO_D0P_LS, 1); + + gpio_set_level(GPIO_CLKN_LS, 1); + SOTEOTWAIT(); + gpio_set_level(GPIO_CLKP_LS, 1); + + //Stop DMA transfer + spidev->dma_conf.dma_tx_stop=1; + while (spidev->ext2.val!=0) ; + + //Clear flipflop + gpio_set_level(GPIO_FF_NRST, 0); + ets_delay_us(1); + gpio_set_level(GPIO_FF_NRST, 1); + + //Clock is in LP11 now. We should go LP01, LP00 to enable HS receivers + gpio_set_level(GPIO_CLKP_LS, 0); + SOTEOTWAIT(); + gpio_set_level(GPIO_CLKN_LS, 0); + + cur_idle_desc=0; + idle_dmadesc[0].qe.stqe_next=&idle_dmadesc[0]; + //Set SPI to transfer contents of idle dmadesc + spidev->dma_conf.val |= SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST; + spidev->dma_out_link.start=0; + spidev->dma_in_link.start=0; + spidev->dma_conf.val &= ~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST); + spidev->dma_conf.dma_tx_stop=0; + spidev->dma_conf.dma_continue=1; + spidev->dma_conf.out_data_burst_en=1; + spidev->user.usr_mosi_highpart=0; + spidev->dma_out_link.addr=(int)(&idle_dmadesc[0]) & 0xFFFFF; + spidev->dma_out_link.start=1; + spidev->user.usr_mosi=1; + spidev->cmd.usr=1; + + //Data pair is in LP11 now. We should go LP01, LP00 to enable HS receivers +// gpio_set_level(GPIO_D0P_LS, 0); +// SOTEOTWAIT(); +// gpio_set_level(GPIO_D0N_LS, 0); + +} +void mipiInit() { + esp_err_t ret; + bool io_native=false; + spi_bus_config_t buscfg={ + .miso_io_num=-1, + .mosi_io_num=GPIO_D0_HS, + .sclk_io_num=GPIO_FF_CLK, + .quadwp_io_num=-1, + .quadhd_io_num=-1, + .max_transfer_sz=4096*3 + }; + + gpio_config_t io_conf={ + .intr_type=GPIO_INTR_DISABLE, + .mode=GPIO_MODE_OUTPUT, + .pin_bit_mask=(1<dma_conf.val|=SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST; + spidev->dma_out_link.start=0; + spidev->dma_in_link.start=0; + spidev->dma_conf.val&=~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST); + //Reset timing + spidev->ctrl2.val=0; + spi_set_clock(spidev, 80000000, 20000000, 128); + + //Configure SPI host + spidev->ctrl.rd_bit_order=1; //LSB first + spidev->ctrl.wr_bit_order=1; + spidev->pin.ck_idle_edge=0; + spidev->user.ck_out_edge=0; + spidev->ctrl2.miso_delay_mode=2; + spidev->ctrl.val &= ~(SPI_FREAD_DUAL|SPI_FREAD_QUAD|SPI_FREAD_DIO|SPI_FREAD_QIO); + spidev->user.val &= ~(SPI_FWRITE_DUAL|SPI_FWRITE_QUAD|SPI_FWRITE_DIO|SPI_FWRITE_QIO); + + //Disable unneeded ints + spidev->slave.val=0; + spidev->dma_int_ena.val=0; + //Set int on EOF + spidev->dma_int_clr.val=0xFFFFFFFF; //clear all ints + spidev->dma_int_ena.out_eof=1; +// spidev->dma_int_ena.in_suc_eof=1; + + //Init GPIO to MIPI idle levels + gpio_set_level(GPIO_D0N_LS, 1); + gpio_set_level(GPIO_D0P_LS, 1); + gpio_set_level(GPIO_CLKN_LS, 1); + gpio_set_level(GPIO_CLKP_LS, 1); + + //Reset display + gpio_set_level(GPIO_NRST, 0); + ets_delay_us(200); + gpio_set_level(GPIO_NRST, 1); + //Wait till display lives + vTaskDelay(100/portTICK_RATE_MS); + + sem=xSemaphoreCreateBinary(); +// xSemaphoreGive(sem); + mipiResync(0); + +} + +void mipiSendMultiple(uint8_t **data, int *lengths, int count) { + esp_err_t ret; + if (count==0) return; //no need to send anything + assert(data[0][0]==0xB8); +// hexdump(data, count); + //Set up link to new transfer + int next_idle_desc=(cur_idle_desc==0)?1:0; + + int last=-1; + for (int i=0; i + +void mipiSend(uint8_t *data, int count); +void mipiSendMultiple(uint8_t **data, int *lengths, int count); +void mipiInit(); +void mipiResync(); + +#endif \ No newline at end of file diff --git a/components/mipidisp/mipi_dsi.c b/components/mipidisp/mipi_dsi.c new file mode 100644 index 0000000..d1b56a6 --- /dev/null +++ b/components/mipidisp/mipi_dsi.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include "crc16-ccitt.h" +#include "mipi.h" + +//Reminder; MIPI is very LSB-first. +typedef struct { + uint8_t sot; //should be 0xB8 + uint8_t datatype; + uint16_t wordcount; + uint8_t ecc; //0 + uint8_t data[]; + //Footer is 2 bytes of checksum. +} __attribute__((packed)) DsiLPHdr; + + +typedef struct { + uint8_t sot; //should be 0xB8 + uint8_t datatype; + uint8_t data[]; + //Footer is 1 byte of ECC +} __attribute__((packed)) DsiSPHdr; + + +// calc XOR parity bit of all '1's in 24 bit value +static char parity (uint32_t val) { + uint32_t i,p; + p=0; + for(i=0; i!=24; i++) { + p^=val; + val>>=1; + } + return (p&1); +} + +static uint8_t calc_ecc(uint8_t *buf) { + int ret=0; + uint32_t cmd=(buf[0])+(buf[1]<<8)+(buf[2]<<16); + if(parity(cmd & 0b111100010010110010110111)) ret|=0x01; + if(parity(cmd & 0b111100100101010101011011)) ret|=0x02; + if(parity(cmd & 0b011101001001101001101101)) ret|=0x04; + if(parity(cmd & 0b101110001110001110001110)) ret|=0x08; + if(parity(cmd & 0b110111110000001111110000)) ret|=0x10; + if(parity(cmd & 0b111011111111110000000000)) ret|=0x20; + return ret; +} + +static uint16_t mipiword(uint16_t val) { + uint16_t ret; + uint8_t *pret=(uint8_t*)&ret; + pret[0]=(val&0xff); + pret[1]=(val>>8); + return ret; +} + +//Warning: CRC isn't tested (my display does not use it) +void mipiDsiSendLong(int type, uint8_t *data, int len) { + DsiLPHdr p; + uint8_t footer[3]; + uint8_t *datas[3]={(uint8_t*)&p, data, footer}; + int lengths[3]={sizeof(DsiLPHdr), len, sizeof(footer)}; + + p.sot=0xB8; + p.datatype=type; + p.wordcount=mipiword(len); + p.ecc=calc_ecc((uint8_t*)&p.datatype); + int crc=crc16_ccitt(0xFFFF, data, len); + footer[0]=(crc&0xff); + footer[1]=(crc>>8); + footer[2]=(crc&0x8000)?0:0xff; //need one last level transition at end + mipiSendMultiple(datas, lengths, 3); +} + +void mipiDsiSendShort(int type, uint8_t *data, int len) { + DsiSPHdr *p=alloca(sizeof(DsiSPHdr)+2+len); + p->sot=0xB8; + p->datatype=type; + memcpy(p->data, data, len); + p->data[len]=calc_ecc((uint8_t*)&p->datatype); + p->data[len+1]=(p->data[len]&0x80)?0:0xff; //need one last level transition at end + mipiSend((uint8_t*)p, sizeof(DsiSPHdr)+2+len); +} diff --git a/components/mipidisp/mipi_dsi.h b/components/mipidisp/mipi_dsi.h new file mode 100644 index 0000000..c9df8de --- /dev/null +++ b/components/mipidisp/mipi_dsi.h @@ -0,0 +1,2 @@ +void mipiDsiSendLong(int type, uint8_t *data, int len); +void mipiDsiSendShort(int type, uint8_t *data, int len); diff --git a/components/tme-esp32/adns9500.c b/components/tme-esp32/adns9500.c new file mode 100644 index 0000000..63fed89 --- /dev/null +++ b/components/tme-esp32/adns9500.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/spi_master.h" +#include "soc/gpio_struct.h" +#include "driver/gpio.h" +#include "esp_heap_alloc_caps.h" + +#define ADNS_MOSI 19 +#define ADNS_MISO 21 +#define ADNS_CLK 23 +#define ADNS_CS 22 + +//#define DELAY() asm("nop; nop; nop; nop;nop; nop; nop; nop;nop; nop; nop; nop;nop; nop; nop; nop;") +#define DELAY() ets_delay_us(10); + +static void adnsWrite(int adr, int val) { + int data=((adr|0x80)<<8)|val; + gpio_set_level(ADNS_CS, 0); + DELAY(); + for (int mask=0x8000; mask!=0; mask>>=1) { + gpio_set_level(ADNS_MOSI, (data&mask)?1:0); + gpio_set_level(ADNS_CLK, 0); + DELAY(); + gpio_set_level(ADNS_CLK, 1); + DELAY(); + } + gpio_set_level(ADNS_CS, 1); +} + +static int adnsRead(int adr) { + int data=((adr&0x7F)<<8); + int out=0; + gpio_set_level(ADNS_CS, 0); + DELAY(); + for (int mask=0x8000; mask!=0; mask>>=1) { + gpio_set_level(ADNS_MOSI, (data&mask)?1:0); + gpio_set_level(ADNS_CLK, 0); + DELAY(); + gpio_set_level(ADNS_CLK, 1); + if (gpio_get_level(ADNS_MISO)) out|=mask; + DELAY(); + } + gpio_set_level(ADNS_CS, 1); + return out&0xff; +} + +int adns9500_init() { + volatile int delay; + int t; + gpio_config_t gpioconf[2]={ + { + .pin_bit_mask=(1<=LINESPERBUF || j==319) { - //mipiDsiSendLong(0x39, img, (LINESPERBUF*320*2)+1); + mipiDsiSendLong(0x39, img, (LINESPERBUF*320*2)+1); img[0]=0x3c; l=0; - *p=&img[1]; + p=&img[1]; } } } @@ -273,13 +192,17 @@ void dispDraw(uint8_t *mem) { int dx, dy, btn; currFbPtr=mem; xSemaphoreGive(dispSem); -// mpuMouseGetDxDyBtn(&dx, &dy, &btn); -// mouseMove(dx, dy, btn); + adns900_get_dxdybtn(&dx, &dy, &btn); + mouseMove(dx, dy, btn); } void dispInit() { + initLcd(); printf("spi_lcd_init()\n"); + int ret=adns9500_init(); + if (!ret) printf("No mouse found!\n"); + dispSem=xSemaphoreCreateBinary(); #if CONFIG_FREERTOS_UNICORE xTaskCreatePinnedToCore(&displayTask, "display", 3000, NULL, 5, NULL, 0); diff --git a/components/tme/emu.c b/components/tme/emu.c index 17febfc..e906e30 100644 --- a/components/tme/emu.c +++ b/components/tme/emu.c @@ -90,7 +90,7 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { ncrWrite((address>>4)&0x7, (address>>9)&1, value); } else if (address >= 0x800000 && address < 0xC00000) { sccWrite(address, value); - printf("PC %x: Write to %x: %x\n", pc, address, value); +// printf("PC %x: Write to %x: %x\n", pc, address, value); } else { printf("PC %x: Write to %x: %x\n", pc, address, value); } diff --git a/components/tme/scc.c b/components/tme/scc.c index f573abc..5190aaa 100644 --- a/components/tme/scc.c +++ b/components/tme/scc.c @@ -43,7 +43,7 @@ static Scc scc; static void raiseInt(int chan) { if ((scc.wr1[chan]&1) && (scc.intpending&(~scc.intpendingOld))) { scc.intpendingOld=scc.intpending; - printf("SCC int, pending %x\n", scc.intpending); +// printf("SCC int, pending %x\n", scc.intpending); sccIrq(1); } } @@ -127,7 +127,7 @@ unsigned int sccRead(unsigned int addr) { } else if (reg==15) { val=scc.wr15[chan]; } - printf("SCC: read from chan %d reg %d val %x\n", chan, reg, val); +// printf("SCC: read from chan %d reg %d val %x\n", chan, reg, val); return val; } diff --git a/sdkconfig b/sdkconfig index 5784833..bc87f79 100644 --- a/sdkconfig +++ b/sdkconfig @@ -81,8 +81,8 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_APP_OFFSET=0x10000 -CONFIG_OPTIMIZATION_LEVEL_DEBUG=y -# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y # # Component config @@ -180,7 +180,7 @@ CONFIG_FATFS_MAX_LFN=255 # # FreeRTOS # -CONFIG_FREERTOS_UNICORE=y +# CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_HZ=100