Skip to content

Commit

Permalink
SPI_3WIRE is a #define that also comes from Linux /usr/include/linux/…
Browse files Browse the repository at this point in the history
…spi/spidev.h file - rename fbcp-ili9341 3-wire support define to SPI_3WIRE_PROTOCOL instead
  • Loading branch information
juj committed Nov 3, 2018
1 parent 5917807 commit 6de6e06
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 27 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ endif()
set(GPIO_TFT_DATA_CONTROL 0 CACHE STRING "Explicitly specify the Data/Control GPIO pin (sometimes also called Register Select)")
if (GPIO_TFT_DATA_CONTROL GREATER 0)
message(STATUS "Using 4-wire SPI mode of communication, with GPIO pin ${GPIO_TFT_DATA_CONTROL} for Data/Control line")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGPIO_TFT_DATA_CONTROL=${GPIO_TFT_DATA_CONTROL} -DSPI_4WIRE=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGPIO_TFT_DATA_CONTROL=${GPIO_TFT_DATA_CONTROL}")
elseif (GPIO_TFT_DATA_CONTROL LESS 0)
message(STATUS "Using 3-wire SPI mode of communication, i.e. a display that does not havea a Data/Control line")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPI_3WIRE=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPI_3WIRE_PROTOCOL=1")
endif()

set(GPIO_TFT_RESET_PIN 0 CACHE STRING "Explicitly specify the Reset GPIO pin (leave out if there is no Reset line)")
Expand Down
2 changes: 1 addition & 1 deletion config.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
// requires that ALL_TASKS_SHOULD_DMA is also enabled.
// #define UPDATE_FRAMES_WITHOUT_DIFFING

#if defined(SINGLE_CORE_BOARD) && defined(USE_DMA_TRANSFERS) && !defined(SPI_3WIRE) // TODO: 3-wire SPI displays are not yet compatible with ALL_TASKS_SHOULD_DMA option.
#if defined(SINGLE_CORE_BOARD) && defined(USE_DMA_TRANSFERS) && !defined(SPI_3WIRE_PROTOCOL) // TODO: 3-wire SPI displays are not yet compatible with ALL_TASKS_SHOULD_DMA option.
// These are prerequisites for good performance on Pi Zero
#ifndef ALL_TASKS_SHOULD_DMA
#define ALL_TASKS_SHOULD_DMA
Expand Down
4 changes: 2 additions & 2 deletions display.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
#define SPI_BYTESPERPIXEL 2
#endif

#if (DISPLAY_DRAWABLE_WIDTH % 16 == 0) && defined(ALL_TASKS_SHOULD_DMA) &&!defined(USE_SPI_THREAD) && defined(USE_GPU_VSYNC) && !defined(DISPLAY_COLOR_FORMAT_R6X2G6X2B6X2) && !defined(SPI_3WIRE)
#if (DISPLAY_DRAWABLE_WIDTH % 16 == 0) && defined(ALL_TASKS_SHOULD_DMA) &&!defined(USE_SPI_THREAD) && defined(USE_GPU_VSYNC) && !defined(DISPLAY_COLOR_FORMAT_R6X2G6X2B6X2) && !defined(SPI_3WIRE_PROTOCOL)
// If conditions are suitable, defer moving pixels until the very last moment in dma.cpp when we are about
// to kick off DMA tasks.
// TODO: 3-wire SPI displays are not yet compatible with this path. Implement support for this to optimize performance of 3-wire SPI displays on Pi Zero. (Pi 3B does not care that much)
Expand All @@ -107,6 +107,6 @@ void DeinitSPIDisplay(void);
#error Please define -DSPI_BUS_CLOCK_DIVISOR=<some even number> on the CMake command line! This parameter along with core_freq=xxx in /boot/config.txt defines the SPI display speed. (spi speed = core_freq / SPI_BUS_CLOCK_DIVISOR)
#endif

#if !defined(GPIO_TFT_DATA_CONTROL) && !defined(SPI_3WIRE)
#if !defined(GPIO_TFT_DATA_CONTROL) && !defined(SPI_3WIRE_PROTOCOL)
#error Please reconfigure CMake with -DGPIO_TFT_DATA_CONTROL=<int> specifying which pin your display is using for the Data/Control line!
#endif
10 changes: 5 additions & 5 deletions dma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,15 @@ static void memcpy_to_dma_and_prev_framebuffer_in_c(uint16_t *dstDma, uint16_t *
*dstPrevFramebuffer = prevData;
}

#if defined(ALL_TASKS_SHOULD_DMA) && defined(SPI_3WIRE)
#if defined(ALL_TASKS_SHOULD_DMA) && defined(SPI_3WIRE_PROTOCOL)
// Bug: there is something about the chained DMA transfer mechanism that makes write window coordinate set commands not go through properly
// on 3-wire displays, but do not yet know what. (Remove this #error statement to debug)
#error ALL_TASKS_SHOULD_DMA and SPI_3WIRE are currently not mutually compatible!
#error ALL_TASKS_SHOULD_DMA and SPI_3WIRE_PROTOCOL are currently not mutually compatible!
#endif

#if defined(OFFLOAD_PIXEL_COPY_TO_DMA_CPP) && defined(SPI_3WIRE)
#if defined(OFFLOAD_PIXEL_COPY_TO_DMA_CPP) && defined(SPI_3WIRE_PROTOCOL)
// We would have to convert 8-bit tasks to 9-bit tasks immediately after offloaded memcpy has been done below to implement this.
#error OFFLOAD_PIXEL_COPY_TO_DMA_CPP and SPI_3WIRE are not mutually compatible!
#error OFFLOAD_PIXEL_COPY_TO_DMA_CPP and SPI_3WIRE_PROTOCOL are not mutually compatible!
#endif

void SPIDMATransfer(SPITask *task)
Expand Down Expand Up @@ -645,7 +645,7 @@ void SPIDMATransfer(SPITask *task)
// First send the SPI command byte in Polled SPI mode
spi->cs = BCM2835_SPI0_CS_TA | BCM2835_SPI0_CS_CLEAR | DISPLAY_SPI_DRIVE_SETTINGS;

#ifdef SPI_4WIRE
#ifndef SPI_3WIRE_PROTOCOL
CLEAR_GPIO(GPIO_TFT_DATA_CONTROL);
#ifdef DISPLAY_SPI_BUS_IS_16BITS_WIDE
spi->fifo = 0;
Expand Down
12 changes: 6 additions & 6 deletions spi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "mailbox.h"
#include "mem_alloc.h"

#if defined(DISPLAY_SPI_BUS_IS_16BITS_WIDE) && defined(SPI_3WIRE)
#if defined(DISPLAY_SPI_BUS_IS_16BITS_WIDE) && defined(SPI_3WIRE_PROTOCOL)
// I do not have any 3-wire ILI9486 displays to test support for this
#error TODO: 3-wire displays that have 16-bits wide command word are not currently implemented! (that is, ILI9486 does not work in 3-wire configuration) (Only 3-wire displays with 8-bit wide command words are currently supported)
#endif
Expand Down Expand Up @@ -87,7 +87,7 @@ void SetRealtimeThreadPriority()
bool previousTaskWasSPI = true;
#endif

#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL

uint32_t NumBytesNeededFor9BitSPITask(uint32_t byteSizeFor8BitTask)
{
Expand Down Expand Up @@ -210,7 +210,7 @@ void Interleave8BitSPITaskTo9Bit(SPITask *task)
#endif

}
#endif // ~SPI_3WIRE
#endif // ~SPI_3WIRE_PROTOCOL

void WaitForPolledSPITransferToFinish()
{
Expand Down Expand Up @@ -258,7 +258,7 @@ void RunSPITask(SPITask *task)
// printf("SPI cmd=0x%x, data=%d bytes\n", task->cmd, task->PayloadSize());

// Send the command word if display is 4-wire (3-wire displays can omit this, commands are interleaved in the data payload stream above)
#ifdef SPI_4WIRE
#ifndef SPI_3WIRE_PROTOCOL
CLEAR_GPIO(GPIO_TFT_DATA_CONTROL);

#ifdef DISPLAY_SPI_BUS_IS_16BITS_WIDE
Expand Down Expand Up @@ -311,7 +311,7 @@ void RunSPITask(SPITask *task)
uint8_t *tPrefillEnd = tStart + MIN(15, payloadSize);

// Send the command word if display is 4-wire (3-wire displays can omit this, commands are interleaved in the data payload stream above)
#ifdef SPI_4WIRE
#ifndef SPI_3WIRE_PROTOCOL
// An SPI transfer to the display always starts with one control (command) byte, followed by N data bytes.
CLEAR_GPIO(GPIO_TFT_DATA_CONTROL);

Expand All @@ -330,7 +330,7 @@ void RunSPITask(SPITask *task)
#endif

SET_GPIO(GPIO_TFT_DATA_CONTROL);
#endif // ~SPI_4WIRE
#endif // ~!SPI_3WIRE_PROTOCOL

// For small transfers, using DMA is not worth it, but pushing through with polled SPI gives better bandwidth.
// For larger transfers though that are more than this amount of bytes, using DMA is faster.
Expand Down
22 changes: 11 additions & 11 deletions spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ extern volatile SPIRegisterFile *spi;
typedef struct __attribute__((packed)) SPITask
{
uint32_t size; // Size, including both 8-bit and 9-bit tasks
#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL
uint32_t size9BitTaskWithPadding; // Size of the 9-bit task. The 9-bit task starts at address spiTask->data + spiTask->size - spiTask->size9BitTaskWithPadding;
#endif
uint8_t cmd;
Expand All @@ -112,16 +112,16 @@ typedef struct __attribute__((packed)) SPITask
#endif
uint8_t data[]; // Contains both 8-bit and 9-bit tasks back to back, 8-bit first, then 9-bit.

#ifdef SPI_4WIRE
inline uint8_t *PayloadStart() { return data; }
inline uint8_t *PayloadEnd() { return data + size; }
inline uint32_t PayloadSize() const { return size; }
inline uint32_t *DmaSpiHeaderAddress() { return &dmaSpiHeader; }
#else
#ifdef SPI_3WIRE_PROTOCOL
inline uint8_t *PayloadStart() { return data + (size - size9BitTaskWithPadding); }
inline uint8_t *PayloadEnd() { return data + (size - SPI_9BIT_TASK_PADDING_BYTES); }
inline uint32_t PayloadSize() const { return size9BitTaskWithPadding - SPI_9BIT_TASK_PADDING_BYTES; }
inline uint32_t *DmaSpiHeaderAddress() { return (uint32_t*)(PayloadStart()-4); }
#else
inline uint8_t *PayloadStart() { return data; }
inline uint8_t *PayloadEnd() { return data + size; }
inline uint32_t PayloadSize() const { return size; }
inline uint32_t *DmaSpiHeaderAddress() { return &dmaSpiHeader; }
#endif

} SPITask;
Expand Down Expand Up @@ -250,7 +250,7 @@ extern volatile int spiThreadSleeping;

extern int mem_fd;

#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL

// Converts the given SPI task in-place from an 8-bit task to a 9-bit task.
void Interleave8BitSPITaskTo9Bit(SPITask *task);
Expand All @@ -262,7 +262,7 @@ uint32_t NumBytesNeededFor9BitSPITask(uint32_t byteSizeFor8BitTask);

static inline SPITask *AllocTask(uint32_t bytes) // Returns a pointer to a new SPI task block, called on main thread
{
#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL
// For 3-wire/9-bit tasks, store the converted task right at the end of the 8-bit task.
uint32_t size9BitTaskWithPadding = NumBytesNeededFor9BitSPITask(bytes) + SPI_9BIT_TASK_PADDING_BYTES;
bytes += size9BitTaskWithPadding;
Expand Down Expand Up @@ -317,7 +317,7 @@ static inline SPITask *AllocTask(uint32_t bytes) // Returns a pointer to a new S

SPITask *task = (SPITask*)(spiTaskMemory->buffer + tail);
task->size = bytes;
#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL
task->size9BitTaskWithPadding = size9BitTaskWithPadding;
#endif
#ifdef OFFLOAD_PIXEL_COPY_TO_DMA_CPP
Expand All @@ -329,7 +329,7 @@ static inline SPITask *AllocTask(uint32_t bytes) // Returns a pointer to a new S

static inline void CommitTask(SPITask *task) // Advertises the given SPI task from main thread to worker, called on main thread
{
#ifdef SPI_3WIRE
#ifdef SPI_3WIRE_PROTOCOL
Interleave8BitSPITaskTo9Bit(task);
#endif
__sync_synchronize();
Expand Down

0 comments on commit 6de6e06

Please sign in to comment.