Newer esp-idf; change mipi for proto with resistors, slight optimization by using native bswap routines

This commit is contained in:
Jeroen Domburg 2017-07-22 13:33:29 +08:00
parent 1ea57a1541
commit fd6cda6124
3 changed files with 126 additions and 76 deletions

View File

@ -1,4 +1,3 @@
#if 1
/*
Thing to emulate single-lane MIPI using a flipflop and a bunch of resistors.
*/
@ -47,62 +46,62 @@ 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));
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;
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;
}
}
//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;
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;
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) {
@ -152,6 +151,12 @@ void mipiResync() {
spidev->dma_out_link.addr=(int)(&idle_dmadesc[0]) & 0xFFFFF;
spidev->dma_out_link.start=1;
spidev->user.usr_mosi=1;
/* HACK for inverted clock */
spidev->user.usr_addr=1;
spidev->user1.usr_addr_bitlen=0; //1 addr bit
/* End hack */
spidev->cmd.usr=1;
}
@ -287,4 +292,3 @@ void mipiSend(uint8_t *data, int len) {
mipiSendMultiple(&data, &len, 1);
}
#endif

View File

@ -17,7 +17,8 @@
#include "hd.h"
#include "mouse.h"
#include <stdbool.h>
#include "esp_heap_alloc_caps.h"
#include "esp_heap_caps.h"
#include <byteswap.h>
unsigned char *macRom;
unsigned char *macRam;
@ -102,9 +103,9 @@ typedef struct {
};
} MemmapEnt;
#define MEMMAP_ES 0x20000 //entry size
#define MEMMAP_MAX_ADDR 0x1000000
#define MEMMAP_ES 0x20000
//Memmap describing 128 128K blocks of memory, from 0 to 0x1000000.
//Memmap describing 128 128K blocks of memory, from 0 to 0x1000000 (16MiB).
MemmapEnt memmap[128];
static void regenMemmap(int remapRom) {
@ -179,7 +180,9 @@ const inline static MemmapEnt *getMmmapEnt(const unsigned int address) {
unsigned int m68k_read_memory_8(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
return mmEnt->memAddr[address&(MEMMAP_ES-1)];
uint8_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
return *p;
} else {
return mmEnt->cb(address, 0, 0);
}
@ -188,8 +191,9 @@ unsigned int m68k_read_memory_8(unsigned int address) {
unsigned int m68k_read_memory_16(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
return (p[0]<<8)|(p[1]);
uint16_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
return __bswap_16(*p);
} else {
unsigned int ret;
ret=mmEnt->cb(address, 0, 0)<<8;
@ -201,8 +205,9 @@ unsigned int m68k_read_memory_16(unsigned int address) {
unsigned int m68k_read_memory_32(unsigned int address) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|(p[3]);
uint32_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
return __bswap_32(*p);
} else {
unsigned int ret;
ret=mmEnt->cb(address, 0, 0)<<24;
@ -216,7 +221,9 @@ unsigned int m68k_read_memory_32(unsigned int address) {
void m68k_write_memory_8(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
mmEnt->memAddr[address&(MEMMAP_ES-1)]=value;
uint8_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
*p=value;
} else {
mmEnt->cb(address, value, 1);
}
@ -225,9 +232,9 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
void m68k_write_memory_16(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p[0]=(value>>8);
p[1]=(value>>0);
uint16_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
*p=__bswap_16(value);
} else {
mmEnt->cb(address, (value>>8)&0xff, 1);
mmEnt->cb(address+1, (value>>0)&0xff, 1);
@ -238,11 +245,9 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) {
void m68k_write_memory_32(unsigned int address, unsigned int value) {
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
p[0]=(value>>24);
p[1]=(value>>16);
p[2]=(value>>8);
p[3]=(value>>0);
uint32_t *p;
p=&mmEnt->memAddr[address&(MEMMAP_ES-1)];
*p=__bswap_32(value);
} else {
mmEnt->cb(address, (value>>24)&0xff, 1);
mmEnt->cb(address+1, (value>>16)&0xff, 1);
@ -261,7 +266,7 @@ void printFps() {
long msec=(tv.tv_sec-oldtv.tv_sec)*1000;
msec+=(tv.tv_usec-oldtv.tv_usec)/1000;
printf("Speed: %d%%\n", (int)(100000/msec));
printf("Mem free: %dKiB 8-bit, %dKiB 32-bit\n", xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT)/1024, xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT)/1024);
// printf("Mem free: %dKiB 8-bit, %dKiB 32-bit\n", xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT)/1024, xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT)/1024);
}
oldtv.tv_sec=tv.tv_sec;
oldtv.tv_usec=tv.tv_usec;

View File

@ -19,6 +19,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
CONFIG_LOG_BOOTLOADER_LEVEL=3
# CONFIG_BOOTLOADER_LTO is not set
#
# Security features
@ -81,12 +82,30 @@ 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
#
# Compiler options
#
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
#
# Component config
#
#
# Application Level Tracing
#
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
CONFIG_ESP32_APPTRACE_DEST_NONE=y
# CONFIG_ESP32_APPTRACE_ENABLE is not set
#
# FreeRTOS SystemView Tracing
#
# CONFIG_AWS_IOT_SDK is not set
# CONFIG_BT_ENABLED is not set
CONFIG_BT_RESERVE_DRAM=0
@ -99,6 +118,7 @@ CONFIG_BT_RESERVE_DRAM=0
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
CONFIG_MEMMAP_SMP=y
# CONFIG_SPIRAM_SUPPORT is not set
# CONFIG_MEMMAP_TRACEMEM is not set
# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set
# CONFIG_ESP32_TRAX is not set
@ -107,17 +127,13 @@ CONFIG_TRACEMEM_RESERVE_DRAM=0x0
# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
# CONFIG_ESP32_ENABLE_COREDUMP is not set
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
# CONFIG_ESP32_APPTRACE_DEST_UART is not set
CONFIG_ESP32_APPTRACE_DEST_NONE=y
# CONFIG_ESP32_APPTRACE_ENABLE is not set
# CONFIG_MEMMAP_SPIRAM_ENABLE is not set
# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set
CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y
CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_NEWLIB_STDOUT_ADDCR=y
# CONFIG_NEWLIB_NANO_FORMAT is not set
CONFIG_CONSOLE_UART_DEFAULT=y
@ -134,6 +150,16 @@ CONFIG_ESP32_PANIC_GDBSTUB=y
CONFIG_ESP32_DEBUG_OCDAWARE=y
# CONFIG_INT_WDT is not set
# CONFIG_TASK_WDT is not set
CONFIG_BROWNOUT_DET=y
# CONFIG_BROWNOUT_DET_LVL_SEL_0 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
CONFIG_BROWNOUT_DET_LVL_SEL_7=y
CONFIG_BROWNOUT_DET_LVL=7
# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
@ -195,6 +221,7 @@ CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
# CONFIG_FREERTOS_ASSERT_DISABLE is not set
CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y
# CONFIG_ENABLE_MEMORY_DEBUG is not set
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024
CONFIG_FREERTOS_ISR_STACKSIZE=2000
# CONFIG_FREERTOS_LEGACY_HOOKS is not set
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
@ -227,21 +254,35 @@ CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0
CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
# CONFIG_LWIP_IP_FRAG is not set
# CONFIG_LWIP_IP_REASSEMBLY is not set
#
# TCP
#
CONFIG_TCP_MAXRTX=12
CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1436
CONFIG_TCP_SND_BUF_DEFAULT=5744
CONFIG_TCP_WND_DEFAULT=5744
CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
# CONFIG_TCP_OVERSIZE_DISABLE is not set
# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set
CONFIG_TCPIP_TASK_STACK_SIZE=2560
# CONFIG_PPP_SUPPORT is not set
#
# ICMP
#
# CONFIG_LWIP_MULTICAST_PING is not set
# CONFIG_LWIP_BROADCAST_PING is not set
#
# mbedTLS
#
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384
# CONFIG_MBEDTLS_DEBUG is not set
CONFIG_MBEDTLS_HARDWARE_AES=y
CONFIG_MBEDTLS_HARDWARE_MPI=y
CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y
CONFIG_MBEDTLS_HARDWARE_SHA=y
# CONFIG_MBEDTLS_UNSAFE_ACCELERATION is not set
CONFIG_MBEDTLS_HAVE_TIME=y
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set