Add mouse support, also add mipi component
This commit is contained in:
parent
dfce5c50be
commit
31c98d83b7
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
COMPONENT_ADD_INCLUDEDIRS := .
|
|
@ -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);
|
||||||
|
}
|
|
@ -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 <stdint.h>
|
||||||
|
unsigned short crc16_ccitt(uint16_t oldcrc, const void *buf, int len);
|
||||||
|
|
||||||
|
#endif /* _CRC16_H_ */
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
void hexdump (void *addr, int len);
|
||||||
|
|
|
@ -0,0 +1,299 @@
|
||||||
|
#if 1
|
||||||
|
/*
|
||||||
|
Thing to emulate single-lane MIPI using a flipflop and a bunch of resistors.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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<<GPIO_D0N_LS)|(1LL<<GPIO_D0P_LS)|(1LL<<GPIO_D0_HS)|(1<<GPIO_CLKP_LS)|
|
||||||
|
(1<<GPIO_CLKN_LS)|(1<<GPIO_FF_NRST)|(1<<GPIO_FF_CLK)|(1<<GPIO_NRST),
|
||||||
|
};
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
|
||||||
|
assert(spicommon_periph_claim(HOST));
|
||||||
|
ret=spicommon_bus_initialize_io(HOST, &buscfg, DMACH, SPICOMMON_BUSFLAG_MASTER, &io_native);
|
||||||
|
assert(ret==ESP_OK);
|
||||||
|
spidev=spicommon_hw_for_host(HOST);
|
||||||
|
|
||||||
|
//Set up idle dma desc
|
||||||
|
uint8_t *idle_mem=pvPortMallocCaps(64, MALLOC_CAP_DMA);
|
||||||
|
memset(idle_mem, 0, 64);
|
||||||
|
for (int i=0; i<3; i++) {
|
||||||
|
idle_dmadesc[i].size=64;
|
||||||
|
idle_dmadesc[i].length=64;
|
||||||
|
idle_dmadesc[i].buf=idle_mem;
|
||||||
|
idle_dmadesc[i].eof=0;
|
||||||
|
idle_dmadesc[i].sosf=0;
|
||||||
|
idle_dmadesc[i].owner=1;
|
||||||
|
idle_dmadesc[i].qe.stqe_next = &idle_dmadesc[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_intr_alloc(IRQSRC, 0, spidma_intr, NULL, NULL);
|
||||||
|
|
||||||
|
//Reset DMA
|
||||||
|
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);
|
||||||
|
//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<count; i++) {
|
||||||
|
last++;
|
||||||
|
spicommon_setup_dma_desc_links(&data_dmadesc[last], lengths[i], data[i], false);
|
||||||
|
//Look for new end
|
||||||
|
for (; data_dmadesc[last].eof!=1; last++) ;
|
||||||
|
//Kill eof and make desc point to the next one.
|
||||||
|
data_dmadesc[last].eof=0;
|
||||||
|
data_dmadesc[last].qe.stqe_next=&data_dmadesc[last+1];
|
||||||
|
}
|
||||||
|
//Make very last data desc go to the runout idle desc
|
||||||
|
data_dmadesc[last].qe.stqe_next=&idle_dmadesc[2];
|
||||||
|
//and make the runout go to the end idle desc
|
||||||
|
idle_dmadesc[2].qe.stqe_next=&idle_dmadesc[next_idle_desc];
|
||||||
|
idle_dmadesc[2].eof=1;
|
||||||
|
//Make sure that idle desc keeps spinning
|
||||||
|
idle_dmadesc[next_idle_desc].qe.stqe_next=&idle_dmadesc[next_idle_desc];
|
||||||
|
|
||||||
|
gpio_set_level(GPIO_D0P_LS, 0);
|
||||||
|
SOTEOTWAIT();
|
||||||
|
gpio_set_level(GPIO_D0N_LS, 0);
|
||||||
|
|
||||||
|
//Break the loop on the current idle descriptor
|
||||||
|
idle_dmadesc[cur_idle_desc].qe.stqe_next=&data_dmadesc[0];
|
||||||
|
//Okay, done.
|
||||||
|
cur_idle_desc=next_idle_desc; //for next time
|
||||||
|
|
||||||
|
//Wait until transmission is done
|
||||||
|
xSemaphoreTake(sem, portMAX_DELAY);
|
||||||
|
|
||||||
|
gpio_set_level(GPIO_D0N_LS, 1);
|
||||||
|
SOTEOTWAIT();
|
||||||
|
gpio_set_level(GPIO_D0P_LS, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mipiSend(uint8_t *data, int len) {
|
||||||
|
mipiSendMultiple(&data, &len, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef MIPI_H
|
||||||
|
#define MIPI_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void mipiSend(uint8_t *data, int count);
|
||||||
|
void mipiSendMultiple(uint8_t **data, int *lengths, int count);
|
||||||
|
void mipiInit();
|
||||||
|
void mipiResync();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rom/crc.h>
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
void mipiDsiSendLong(int type, uint8_t *data, int len);
|
||||||
|
void mipiDsiSendShort(int type, uint8_t *data, int len);
|
|
@ -0,0 +1,105 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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<<ADNS_MOSI)|(1<<ADNS_CS)|(1<<ADNS_CLK),
|
||||||
|
.mode=GPIO_MODE_OUTPUT,
|
||||||
|
.pull_up_en=GPIO_PULLUP_DISABLE,
|
||||||
|
.pull_down_en=GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type=GPIO_PIN_INTR_DISABLE
|
||||||
|
},{
|
||||||
|
.pin_bit_mask=(1<<ADNS_MISO),
|
||||||
|
.mode=GPIO_MODE_INPUT,
|
||||||
|
.pull_up_en=GPIO_PULLUP_ENABLE,
|
||||||
|
.pull_down_en=GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type=GPIO_PIN_INTR_DISABLE
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gpio_config(&gpioconf[0]);
|
||||||
|
gpio_config(&gpioconf[1]);
|
||||||
|
|
||||||
|
int tout=5;
|
||||||
|
int r;
|
||||||
|
do {
|
||||||
|
adnsWrite(0,0);
|
||||||
|
adnsWrite(0x3A,0x5a); //Power-Up Reset
|
||||||
|
vTaskDelay(50/portTICK_RATE_MS);
|
||||||
|
adnsRead(0x2);
|
||||||
|
adnsRead(0x3);
|
||||||
|
adnsRead(0x4);
|
||||||
|
adnsRead(0x5);
|
||||||
|
adnsRead(0x6);
|
||||||
|
|
||||||
|
r=adnsRead(0);
|
||||||
|
printf("ADNS: Read %X\n", r);
|
||||||
|
tout--;
|
||||||
|
} while (r!=0x33 && tout!=0);
|
||||||
|
if (tout==0) return 0;
|
||||||
|
|
||||||
|
adnsWrite(0x20, 0); //Main laser turn on !!!
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void adns900_get_dxdybtn(int *x, int *y, int *btn) {
|
||||||
|
int16_t sx, sy;
|
||||||
|
sx=adnsRead(0x3);
|
||||||
|
sx|=adnsRead(0x4)<<8;
|
||||||
|
sy=adnsRead(0x5);
|
||||||
|
sy|=adnsRead(0x6)<<8;
|
||||||
|
// printf("Mouse: %d %d\n", sx, sy);
|
||||||
|
*x=sx;
|
||||||
|
*y=sy;
|
||||||
|
*btn=gpio_get_level(ADNS_MISO)?0:1;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
int adns9500_init();
|
||||||
|
void adns900_get_dxdybtn(int *x, int *y, int *btn);
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "tmeconfig.h"
|
#include "tmeconfig.h"
|
||||||
|
|
||||||
#include "mpu6050.h"
|
|
||||||
#include "mpumouse.h"
|
|
||||||
|
|
||||||
unsigned char *romdata;
|
unsigned char *romdata;
|
||||||
|
|
||||||
void emuTask(void *pvParameters)
|
void emuTask(void *pvParameters)
|
||||||
|
@ -36,17 +33,6 @@ void emuTask(void *pvParameters)
|
||||||
tmeStartEmu(ram, romdata);
|
tmeStartEmu(ram, romdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseTask(void *pvParameters)
|
|
||||||
{
|
|
||||||
printf("Starting mouse task...\n");
|
|
||||||
while(!mpu6050_init()) {
|
|
||||||
printf("Can't init MPU....\n");
|
|
||||||
vTaskDelay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
mpuMouseEmu();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void app_main()
|
void app_main()
|
||||||
{
|
{
|
||||||
|
@ -60,7 +46,6 @@ void app_main()
|
||||||
err=esp_partition_mmap(part, 0, 128*1024, SPI_FLASH_MMAP_DATA, (const void**)&romdata, &hrom);
|
err=esp_partition_mmap(part, 0, 128*1024, SPI_FLASH_MMAP_DATA, (const void**)&romdata, &hrom);
|
||||||
if (err!=ESP_OK) printf("Couldn't map bootrom part!\n");
|
if (err!=ESP_OK) printf("Couldn't map bootrom part!\n");
|
||||||
printf("Starting emu...\n");
|
printf("Starting emu...\n");
|
||||||
// xTaskCreatePinnedToCore(&mouseTask, "mouse", 6*1024, NULL, 6, NULL, 0);
|
xTaskCreatePinnedToCore(&emuTask, "emu", 6*1024, NULL, 5, NULL, 0);
|
||||||
xTaskCreatePinnedToCore(&emuTask, "emu", 8*1024, NULL, 5, NULL, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,8 @@
|
||||||
#include "soc/gpio_struct.h"
|
#include "soc/gpio_struct.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_heap_alloc_caps.h"
|
#include "esp_heap_alloc_caps.h"
|
||||||
#include "mpumouse.h"
|
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
#include "adns9500.h"
|
||||||
|
|
||||||
#include "mipi.h"
|
#include "mipi.h"
|
||||||
#include "mipi_dsi.h"
|
#include "mipi_dsi.h"
|
||||||
|
@ -31,92 +30,7 @@ typedef struct {
|
||||||
} DispPacket;
|
} DispPacket;
|
||||||
|
|
||||||
//Copied from the X163QLN01 appliation note.
|
//Copied from the X163QLN01 appliation note.
|
||||||
DispPacket initPackets[]={
|
const DispPacket initPackets[]={
|
||||||
#if 0
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xBD, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBE, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBF, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBB, 3, {0x07, 0x07, 0x07}},
|
|
||||||
{0x39, 0xD0, 1, {0x00}},
|
|
||||||
{0x39, 0xD1, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xD2, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xD3, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xC7, 1, {0x40}},
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x15, 0xEB, 1, {0x02}},
|
|
||||||
{0x15, 0xF5, 1, {0x10}},
|
|
||||||
{0x39, 0xED, 8, {0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48}},
|
|
||||||
{0x39, 0xC7, 8, {0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}},
|
|
||||||
{0x39, 0xFE, 2, {0x08, 0x08}},
|
|
||||||
{0x39, 0xC3, 3, {0xF2, 0xF2, 0xF2}},
|
|
||||||
{0x39, 0xE9, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x15, 0xCA, 1, {0x04}},
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xB0, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xB1, 3, {0x05, 0x05, 0x05}},
|
|
||||||
{0x39, 0xB2, 3, {0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xB4, 3, {0x07, 0x07, 0x07}},
|
|
||||||
{0x39, 0xB5, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xB6, 3, {0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xB7, 3, {0x35, 0x35, 0x35}},
|
|
||||||
{0x39, 0xB8, 3, {0x23, 0x23, 0x23}},
|
|
||||||
{0x39, 0xB9, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xBA, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xBE, 3, {0x32, 0x32, 0x32}},
|
|
||||||
{0x39, 0xC2, 12, {0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B}},
|
|
||||||
{0x39, 0xCF, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
|
|
||||||
{0x15, 0x35, 1, {0x00}},
|
|
||||||
{0x15, 0x36, 1, {0x00}},
|
|
||||||
{0x15, 0xC0, 1, {0x28}},
|
|
||||||
{0x32, 0x00, 1, {0x00}},
|
|
||||||
{0x15, 0x51, 1, {0x00}},
|
|
||||||
{0x05, 0x11, 1, {0x00}},
|
|
||||||
{0x05, 0x29, 1, {0x00}},
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xBD, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBE, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBF, 5, {0x01, 0x01, 0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xBB, 3, {0x07, 0x07, 0x07}},
|
|
||||||
{0x39, 0xD0, 1, {0x00}},
|
|
||||||
{0x39, 0xD1, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xD2, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xD3, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xC7, 1, {0x40}},
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x15, 0xEB, 1, {0x02}},
|
|
||||||
{0x15, 0xF5, 1, {0x10}},
|
|
||||||
{0x39, 0xED, 8, {0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48}},
|
|
||||||
{0x39, 0xC7, 8, {0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}},
|
|
||||||
{0x39, 0xFE, 2, {0x08, 0x08}},
|
|
||||||
{0x39, 0xC3, 3, {0xF2, 0xF2, 0xF2}},
|
|
||||||
{0x39, 0xE9, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x15, 0xCA, 1, {0x04}},
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0x55, 0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xB0, 3, {0x00, 0x00, 0x00}},
|
|
||||||
{0x39, 0xB1, 3, {0x05, 0x05, 0x05}},
|
|
||||||
{0x39, 0xB2, 3, {0x01, 0x01, 0x01}},
|
|
||||||
{0x39, 0xB4, 3, {0x07, 0x07, 0x07}},
|
|
||||||
{0x39, 0xB5, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xB6, 3, {0x55, 0x55, 0x55}},
|
|
||||||
{0x39, 0xB7, 3, {0x35, 0x35, 0x35}},
|
|
||||||
{0x39, 0xB8, 3, {0x23, 0x23, 0x23}},
|
|
||||||
{0x39, 0xB9, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xBA, 3, {0x03, 0x03, 0x03}},
|
|
||||||
{0x39, 0xBE, 3, {0x32, 0x32, 0x32}},
|
|
||||||
{0x39, 0xC2, 12, {0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B}},
|
|
||||||
{0x39, 0xCF, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
|
|
||||||
{0x15, 0x35, 1, {0x00}},
|
|
||||||
{0x15, 0x36, 1, {0x00}},
|
|
||||||
{0x15, 0xC0, 1, {0x28}},
|
|
||||||
{0x32, 0x00, 1, {0x00}},
|
|
||||||
{0x15, 0x51, 1, {0x00}},
|
|
||||||
{0x05, 0x11, 1, {0x00}},
|
|
||||||
{0x05, 0x29, 1, {0x00}},
|
|
||||||
#endif
|
|
||||||
#if 1
|
|
||||||
{0x39, 0xF0, 5, {0x55, 0xAA, 0x52, 0x08, 0x00}},
|
{0x39, 0xF0, 5, {0x55, 0xAA, 0x52, 0x08, 0x00}},
|
||||||
{0x39, 0xBD, 5, {0x01, 0x90, 0x14, 0x14, 0x00}},
|
{0x39, 0xBD, 5, {0x01, 0x90, 0x14, 0x14, 0x00}},
|
||||||
{0x39, 0xBE, 5, {0x01, 0x90, 0x14, 0x14, 0x01}},
|
{0x39, 0xBE, 5, {0x01, 0x90, 0x14, 0x14, 0x01}},
|
||||||
|
@ -147,7 +61,6 @@ DispPacket initPackets[]={
|
||||||
{0x32, 0, 0, {0}},
|
{0x32, 0, 0, {0}},
|
||||||
{0x05, 0x11, 1, {0x00}}, //exit_sleep_mode
|
{0x05, 0x11, 1, {0x00}}, //exit_sleep_mode
|
||||||
{0x05, 0x29, 1, {0x00}}, //turn display on
|
{0x05, 0x29, 1, {0x00}}, //turn display on
|
||||||
#endif
|
|
||||||
{0x15, 0x3A, 1, {0x55}}, //16-bit mode
|
{0x15, 0x3A, 1, {0x55}}, //16-bit mode
|
||||||
// {0x29, 0x2B, 4, {0x00, 0x00, 0x00, 0xEF}},
|
// {0x29, 0x2B, 4, {0x00, 0x00, 0x00, 0xEF}},
|
||||||
{0,0,0,{0}}
|
{0,0,0,{0}}
|
||||||
|
@ -223,10 +136,12 @@ SemaphoreHandle_t dispSem = NULL;
|
||||||
|
|
||||||
#define LINESPERBUF 1
|
#define LINESPERBUF 1
|
||||||
|
|
||||||
void IRAM_ATTR displayTask(void *arg) {
|
static void initLcd() {
|
||||||
|
|
||||||
mipiInit();
|
mipiInit();
|
||||||
|
vTaskDelay(20/portTICK_RATE_MS); //give screen a sec
|
||||||
|
for (int j=0; j<2; j++) { //Init multiple times; for mysterious reasons it sometimes doesn't catch first time.
|
||||||
for (int i=0; initPackets[i].type!=0; i++) {
|
for (int i=0; initPackets[i].type!=0; i++) {
|
||||||
|
mipiResync();
|
||||||
if (initPackets[i].type==0x39 || initPackets[i].type==0x29) {
|
if (initPackets[i].type==0x39 || initPackets[i].type==0x29) {
|
||||||
uint8_t data[17];
|
uint8_t data[17];
|
||||||
data[0]=initPackets[i].addr;
|
data[0]=initPackets[i].addr;
|
||||||
|
@ -238,11 +153,15 @@ void IRAM_ATTR displayTask(void *arg) {
|
||||||
if (initPackets[i].type==5) vTaskDelay(300/portTICK_RATE_MS);
|
if (initPackets[i].type==5) vTaskDelay(300/portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
printf("Inited.\n");
|
printf("Display inited.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR displayTask(void *arg) {
|
||||||
uint8_t *img=malloc((LINESPERBUF*320*2)+1);
|
uint8_t *img=malloc((LINESPERBUF*320*2)+1);
|
||||||
assert(img);
|
assert(img);
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
int l=0;
|
int l=0;
|
||||||
mipiResync();
|
mipiResync();
|
||||||
|
@ -258,10 +177,10 @@ void IRAM_ATTR displayTask(void *arg) {
|
||||||
}
|
}
|
||||||
l++;
|
l++;
|
||||||
if (l>=LINESPERBUF || j==319) {
|
if (l>=LINESPERBUF || j==319) {
|
||||||
//mipiDsiSendLong(0x39, img, (LINESPERBUF*320*2)+1);
|
mipiDsiSendLong(0x39, img, (LINESPERBUF*320*2)+1);
|
||||||
img[0]=0x3c;
|
img[0]=0x3c;
|
||||||
l=0;
|
l=0;
|
||||||
*p=&img[1];
|
p=&img[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,13 +192,17 @@ void dispDraw(uint8_t *mem) {
|
||||||
int dx, dy, btn;
|
int dx, dy, btn;
|
||||||
currFbPtr=mem;
|
currFbPtr=mem;
|
||||||
xSemaphoreGive(dispSem);
|
xSemaphoreGive(dispSem);
|
||||||
// mpuMouseGetDxDyBtn(&dx, &dy, &btn);
|
adns900_get_dxdybtn(&dx, &dy, &btn);
|
||||||
// mouseMove(dx, dy, btn);
|
mouseMove(dx, dy, btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dispInit() {
|
void dispInit() {
|
||||||
|
initLcd();
|
||||||
printf("spi_lcd_init()\n");
|
printf("spi_lcd_init()\n");
|
||||||
|
int ret=adns9500_init();
|
||||||
|
if (!ret) printf("No mouse found!\n");
|
||||||
|
|
||||||
dispSem=xSemaphoreCreateBinary();
|
dispSem=xSemaphoreCreateBinary();
|
||||||
#if CONFIG_FREERTOS_UNICORE
|
#if CONFIG_FREERTOS_UNICORE
|
||||||
xTaskCreatePinnedToCore(&displayTask, "display", 3000, NULL, 5, NULL, 0);
|
xTaskCreatePinnedToCore(&displayTask, "display", 3000, NULL, 5, NULL, 0);
|
||||||
|
|
|
@ -90,7 +90,7 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
|
||||||
ncrWrite((address>>4)&0x7, (address>>9)&1, value);
|
ncrWrite((address>>4)&0x7, (address>>9)&1, value);
|
||||||
} else if (address >= 0x800000 && address < 0xC00000) {
|
} else if (address >= 0x800000 && address < 0xC00000) {
|
||||||
sccWrite(address, value);
|
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 {
|
} else {
|
||||||
printf("PC %x: Write to %x: %x\n", pc, address, value);
|
printf("PC %x: Write to %x: %x\n", pc, address, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ static Scc scc;
|
||||||
static void raiseInt(int chan) {
|
static void raiseInt(int chan) {
|
||||||
if ((scc.wr1[chan]&1) && (scc.intpending&(~scc.intpendingOld))) {
|
if ((scc.wr1[chan]&1) && (scc.intpending&(~scc.intpendingOld))) {
|
||||||
scc.intpendingOld=scc.intpending;
|
scc.intpendingOld=scc.intpending;
|
||||||
printf("SCC int, pending %x\n", scc.intpending);
|
// printf("SCC int, pending %x\n", scc.intpending);
|
||||||
sccIrq(1);
|
sccIrq(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ unsigned int sccRead(unsigned int addr) {
|
||||||
} else if (reg==15) {
|
} else if (reg==15) {
|
||||||
val=scc.wr15[chan];
|
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;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000
|
CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
CONFIG_APP_OFFSET=0x10000
|
CONFIG_APP_OFFSET=0x10000
|
||||||
CONFIG_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Component config
|
# Component config
|
||||||
|
@ -180,7 +180,7 @@ CONFIG_FATFS_MAX_LFN=255
|
||||||
#
|
#
|
||||||
# FreeRTOS
|
# FreeRTOS
|
||||||
#
|
#
|
||||||
CONFIG_FREERTOS_UNICORE=y
|
# CONFIG_FREERTOS_UNICORE is not set
|
||||||
CONFIG_FREERTOS_CORETIMER_0=y
|
CONFIG_FREERTOS_CORETIMER_0=y
|
||||||
# CONFIG_FREERTOS_CORETIMER_1 is not set
|
# CONFIG_FREERTOS_CORETIMER_1 is not set
|
||||||
CONFIG_FREERTOS_HZ=100
|
CONFIG_FREERTOS_HZ=100
|
||||||
|
|
Loading…
Reference in New Issue