From bdd1b03fb0ae0fa3f862fb0aec39e5e9695bc930 Mon Sep 17 00:00:00 2001 From: Miso Kim Date: Fri, 27 Jan 2023 01:55:42 +0900 Subject: [PATCH 1/3] Update CMakefile.txt for aarch64 OS aarch64 architecture is for 64bit OS. It doesn't allow the 32bit compiler option like -marm -mabi=aapcs-linux -mhard-float -mfloat-abi=hard If only the architecture is not aarch64, it follows the existing compiler option, otherwise drop unacceptable options. --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abd94b2..f62fad7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() +EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE ) +message( STATUS "Architecture: ${ARCHITECTURE}" ) + include_directories(/opt/vc/include) link_directories(/opt/vc/lib) @@ -46,7 +49,11 @@ if (SINGLE_CORE_BOARD) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSINGLE_CORE_BOARD=1") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm -mabi=aapcs-linux -mhard-float -mfloat-abi=hard -mlittle-endian -mtls-dialect=gnu2 -funsafe-math-optimizations") +if (NOT ${ARCHITECTURE} STREQUAL "aarch64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm -mabi=aapcs-linux -mhard-float -mfloat-abi=hard -mlittle-endian -mtls-dialect=gnu2 -funsafe-math-optimizations") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlittle-endian -funsafe-math-optimizations") +endif() option(ARMV6Z "Target a Raspberry Pi with ARMv6Z instruction set (Pi 1A, 1A+, 1B, 1B+, Zero, Zero W)" ${DEFAULT_TO_ARMV6Z}) if (ARMV6Z) From 74a9f22a71c6eb157406c4f7a26cb22f443256e1 Mon Sep 17 00:00:00 2001 From: Miso Kim Date: Mon, 30 Jan 2023 22:33:07 +0900 Subject: [PATCH 2/3] CMakeLists.txt spi.cpp tick.h --- CMakeLists.txt | 4 ++-- spi.cpp | 9 ++++++++- tick.h | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f62fad7..891d0f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,10 +49,10 @@ if (SINGLE_CORE_BOARD) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSINGLE_CORE_BOARD=1") endif() -if (NOT ${ARCHITECTURE} STREQUAL "aarch64") +if (NOT ${ARCHITECTURE} STREQUAL "aarch64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm -mabi=aapcs-linux -mhard-float -mfloat-abi=hard -mlittle-endian -mtls-dialect=gnu2 -funsafe-math-optimizations") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlittle-endian -funsafe-math-optimizations") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlittle-endian -funsafe-math-optimizations -mstrict-align") endif() option(ARMV6Z "Target a Raspberry Pi with ARMv6Z instruction set (Pi 1A, 1A+, 1B, 1B+, Zero, Zero W)" ${DEFAULT_TO_ARMV6Z}) diff --git a/spi.cpp b/spi.cpp index d156f2d..96f1223 100644 --- a/spi.cpp +++ b/spi.cpp @@ -49,8 +49,11 @@ volatile SPIRegisterFile *spi = 0; // Points to the system timer register. N.B. spec sheet says this is two low and high parts, in an 32-bit aligned (but not 64-bit aligned) address. Profiling shows // that Pi 3 Model B does allow reading this as a u64 load, and even when unaligned, it is around 30% faster to do so compared to loading in parts "lo | (hi << 32)". +#if __aarch64__ +volatile uint32_t *systemTimerRegister = 0; +#else volatile uint64_t *systemTimerRegister = 0; - +#endif void DumpSPICS(uint32_t reg) { PRINT_FLAG(BCM2835_SPI0_CS_CS); @@ -515,7 +518,11 @@ int InitSPI() if (bcm2835 == MAP_FAILED) FATAL_ERROR("mapping /dev/mem failed"); spi = (volatile SPIRegisterFile*)((uintptr_t)bcm2835 + BCM2835_SPI0_BASE); gpio = (volatile GPIORegisterFile*)((uintptr_t)bcm2835 + BCM2835_GPIO_BASE); + #if __aarch64__ + systemTimerRegister = (volatile uint32_t*)((uintptr_t)bcm2835 + BCM2835_TIMER_BASE + 0x04); // Generates an unaligned 64-bit pointer, but seems to be fine. + #else systemTimerRegister = (volatile uint64_t*)((uintptr_t)bcm2835 + BCM2835_TIMER_BASE + 0x04); // Generates an unaligned 64-bit pointer, but seems to be fine. + #endif // TODO: On graceful shutdown, (ctrl-c signal?) close(mem_fd) #endif diff --git a/tick.h b/tick.h index 2036168..256dade 100644 --- a/tick.h +++ b/tick.h @@ -5,11 +5,14 @@ #include // Initialized in spi.cpp along with the rest of the BCM2835 peripheral: +#if __aarch64__ +extern volatile uint32_t *systemTimerRegister; +#define tick() (*systemTimerRegister+((uint64_t)(*(systemTimerRegister+1))<<32)) +#else extern volatile uint64_t *systemTimerRegister; #define tick() (*systemTimerRegister) - #endif - +#endif #ifdef NO_THROTTLING #define usleep(x) ((void)0) From d6dd96859a56d5d306a0779cd0263f8ef3b3c45a Mon Sep 17 00:00:00 2001 From: Miso Kim Date: Tue, 31 Jan 2023 01:48:56 +0900 Subject: [PATCH 3/3] CMakeLists.txt display.h spi.cpp spi.h --- CMakeLists.txt | 6 +++++- display.h | 2 ++ spi.cpp | 26 ++++++++++++++++++++++---- spi.h | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 891d0f6..54c0ec4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 2.8) +project(fbcp-ili9341) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() @@ -227,6 +228,9 @@ elseif(KEDEI_V63_MPI3501) if (USE_DMA_TRANSFERS) message(FATAL_ERROR "DMA is unfortunately not possible with KeDei MPI3501. Please disable with -DUSE_DMA_TRANSFERS=OFF.") endif() +elseif(KEDEI_TRASH) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKEDEI_TRASH") + message(STATUS "Targeting KeDei 3.5 inch SPI TFTLCD 480*320 16bit/18bit version 3.0 2015/4/9 display") elseif(ILI9341) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DILI9341") message(STATUS "Targeting ILI9341") @@ -278,4 +282,4 @@ endif() add_executable(fbcp-ili9341 ${sourceFiles}) -target_link_libraries(fbcp-ili9341 pthread bcm_host atomic) +target_link_libraries(fbcp-ili9341 pthread bcm_host atomic bcm2835) diff --git a/display.h b/display.h index ff0bd72..5ef83b9 100644 --- a/display.h +++ b/display.h @@ -7,6 +7,8 @@ #if defined(ILI9341) || defined(ILI9340) #include "ili9341.h" +#elif defined(KEDEI_TRASH) +#include "kedei_trash.h" #elif defined(ILI9486L) #include "ili9486l.h" #elif defined(ILI9488) diff --git a/spi.cpp b/spi.cpp index 96f1223..8be1a80 100644 --- a/spi.cpp +++ b/spi.cpp @@ -41,7 +41,7 @@ static uint32_t writeCounter = 0; TOGGLE_CHIP_SELECT_LINE(); \ DEBUG_PRINT_WRITTEN_BYTE(w); \ } while(0) - + int mem_fd = -1; volatile void *bcm2835 = 0; volatile GPIORegisterFile *gpio = 0; @@ -322,7 +322,6 @@ void RunSPITask(SPITask *task) SET_GPIO(GPIO_TFT_DATA_CONTROL); #endif - // Send the data payload: while(tStart < tPrefillEnd) WRITE_FIFO(*tStart++); while(tStart < tEnd) @@ -338,6 +337,11 @@ void RunSPITask(SPITask *task) } #else +#ifdef KEDEI_TRASH +extern void lcd_data8(uint8_t *data); +extern void lcd_cmd(uint8_t data); +#endif + void RunSPITask(SPITask *task) { WaitForPolledSPITransferToFinish(); @@ -355,6 +359,15 @@ void RunSPITask(SPITask *task) const uint32_t payloadSize = tEnd - tStart; uint8_t *tPrefillEnd = tStart + MIN(15, payloadSize); +#ifdef KEDEI_TRASH + lcd_cmd(task->cmd); + while(tStart < tEnd) + { + lcd_data8(tStart); + tStart += 2; + } +#else // not KEDEI_TRASH + // Send the command word if display is 4-wire (3-wire displays can omit this, commands are interleaved in the data payload stream above) #ifndef SPI_3WIRE_PROTOCOL // An SPI transfer to the display always starts with one control (command) byte, followed by N data bytes. @@ -365,7 +378,6 @@ void RunSPITask(SPITask *task) WRITE_FIFO(0x00); #endif WRITE_FIFO(task->cmd); - #ifdef DISPLAY_SPI_BUS_IS_16BITS_WIDE while(!(spi->cs & (BCM2835_SPI0_CS_DONE))) /*nop*/; spi->fifo; @@ -393,7 +405,11 @@ void RunSPITask(SPITask *task) else #endif { - while(tStart < tPrefillEnd) WRITE_FIFO(*tStart++); + while(tStart < tPrefillEnd) + { + WRITE_FIFO(*tStart++); + + } while(tStart < tEnd) { uint32_t cs = spi->cs; @@ -402,10 +418,12 @@ void RunSPITask(SPITask *task) if ((cs & (BCM2835_SPI0_CS_RXR|BCM2835_SPI0_CS_RXF))) spi->cs = BCM2835_SPI0_CS_CLEAR_RX | BCM2835_SPI0_CS_TA | DISPLAY_SPI_DRIVE_SETTINGS; } } +#endif // not KEDEI_TRASH #ifdef DISPLAY_NEEDS_CHIP_SELECT_SIGNAL END_SPI_COMMUNICATION(); #endif + } #endif diff --git a/spi.h b/spi.h index e88c8d0..738a5a5 100644 --- a/spi.h +++ b/spi.h @@ -112,12 +112,12 @@ typedef struct __attribute__((packed)) SPITask #else uint8_t cmd; #endif - uint32_t dmaSpiHeader; #ifdef OFFLOAD_PIXEL_COPY_TO_DMA_CPP uint8_t *fb; uint8_t *prevFb; uint16_t width; #endif + uint32_t dmaSpiHeader; uint8_t data[]; // Contains both 8-bit and 9-bit tasks back to back, 8-bit first, then 9-bit. #ifdef SPI_3WIRE_PROTOCOL @@ -130,6 +130,7 @@ typedef struct __attribute__((packed)) SPITask inline uint8_t *PayloadEnd() { return data + size; } inline uint32_t PayloadSize() const { return size; } inline uint32_t *DmaSpiHeaderAddress() { return &dmaSpiHeader; } + // inline uint32_t *DmaSpiHeaderAddress() { return 0; } #endif } SPITask;