Skip to content

Commit

Permalink
Move portduino specific code to portduino platform, including using s…
Browse files Browse the repository at this point in the history
…pi_host to specify SPI device
  • Loading branch information
jp-bennett committed Apr 28, 2024
1 parent 0dedad6 commit fe6a27d
Show file tree
Hide file tree
Showing 13 changed files with 925 additions and 6 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ file(GLOB SRCS
src/lgfx/v1/misc/*.cpp
src/lgfx/v1/panel/*.cpp
src/lgfx/v1/platforms/arduino_default/*.cpp
src/lgfx/v1/platforms/portduino/*.cpp
src/lgfx/v1/platforms/esp32/*.cpp
src/lgfx/v1/platforms/esp32c3/*.cpp
src/lgfx/v1/platforms/esp32s2/*.cpp
Expand Down
5 changes: 1 addition & 4 deletions src/lgfx/v1/platforms/arduino_default/Bus_SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Original Source:
#elif defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx)
#elif defined (ARDUINO_ARCH_SPRESENSE)
#elif defined (ARDUINO_ARCH_MBED_RP2040) || defined(ARDUINO_ARCH_RP2040)
#elif defined (PORTDUINO_LINUX_HARDWARE)
#elif defined (ARDUINO)

#include "Bus_SPI.hpp"
Expand Down Expand Up @@ -60,10 +61,6 @@ namespace lgfx
PrivateSPI->end();
}

void Bus_SPI::spi_device(HardwareSPI *newSPI)
{
PrivateSPI = newSPI;
}

void Bus_SPI::beginTransaction(void)
{
Expand Down
1 change: 0 additions & 1 deletion src/lgfx/v1/platforms/arduino_default/Bus_SPI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ namespace lgfx

bool init(void) override;
void release(void) override;
void spi_device(HardwareSPI *newSPI);

void beginTransaction(void) override;
void endTransaction(void) override;
Expand Down
2 changes: 1 addition & 1 deletion src/lgfx/v1/platforms/arduino_default/Bus_Stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Original Source:
[mongonta0716](https://github.com/mongonta0716)
[tobozo](https://github.com/tobozo)
/----------------------------------------------------------------------------*/
#if defined (ARDUINO)
#if defined (ARDUINO) && !defined (PORTDUINO_LINUX_HARDWARE)

#include "Bus_Stream.hpp"
#include "../../misc/pixelcopy.hpp"
Expand Down
1 change: 1 addition & 0 deletions src/lgfx/v1/platforms/arduino_default/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Original Source:
#elif defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx)
#elif defined (ARDUINO_ARCH_SPRESENSE)
#elif defined (ARDUINO_ARCH_MBED_RP2040) || defined(ARDUINO_ARCH_RP2040)
#elif defined (PORTDUINO_LINUX_HARDWARE)
#elif defined (ARDUINO)

#include "common.hpp"
Expand Down
4 changes: 4 additions & 0 deletions src/lgfx/v1/platforms/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Original Source:

#include "rp2040/common.hpp"

#elif defined (PORTDUINO_LINUX_HARDWARE)

#include "portduino/common.hpp"

#elif defined (ARDUINO)

#include "arduino_default/common.hpp"
Expand Down
4 changes: 4 additions & 0 deletions src/lgfx/v1/platforms/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ Original Source:
#include "rp2040/Bus_I2C.hpp"
#include "rp2040/Bus_SPI.hpp"

#elif defined (PORTDUINO_LINUX_HARDWARE)

#include "portduino/Bus_SPI.hpp"

#elif defined (ARDUINO)

#include "arduino_default/Bus_SPI.hpp"
Expand Down
219 changes: 219 additions & 0 deletions src/lgfx/v1/platforms/portduino/Bus_SPI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*----------------------------------------------------------------------------/
Lovyan GFX - Graphics library for embedded devices.
Original Source:
https://github.com/lovyan03/LovyanGFX/
Licence:
[FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt)
Author:
[lovyan03](https://twitter.com/lovyan03)
Contributors:
[ciniml](https://github.com/ciniml)
[mongonta0716](https://github.com/mongonta0716)
[tobozo](https://github.com/tobozo)
/----------------------------------------------------------------------------*/
#if defined (ESP_PLATFORM)
#elif defined (ESP8266)
#elif defined (__SAMD21__) || defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__)
#elif defined (__SAMD51__)
#elif defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx)
#elif defined (ARDUINO_ARCH_SPRESENSE)
#elif defined (ARDUINO_ARCH_MBED_RP2040) || defined(ARDUINO_ARCH_RP2040)
#elif defined (PORTDUINO_LINUX_HARDWARE)

#include "Bus_SPI.hpp"
#include "../../misc/pixelcopy.hpp"
#include <Arduino.h>
#include <SPI.h>

namespace lgfx
{
inline namespace v1
{
//----------------------------------------------------------------------------

void Bus_SPI::config(const config_t& config)
{
_cfg = config;

if (_cfg.pin_dc >= 0)
{
pinMode(_cfg.pin_dc, pin_mode_t::output);
gpio_hi(_cfg.pin_dc);
}
}

bool Bus_SPI::init(void)
{
dc_h();
pinMode(_cfg.pin_dc, pin_mode_t::output);
char x = (_cfg.spi_host & (1 << 4) - 1) + '0';
char y = (_cfg.spi_host >> 4) + '0';
PrivateSPI = new HardwareSPI();
std::string spiString = "/dev/spidev";
spiString += x;
spiString += ".";
spiString += y;
PrivateSPI->begin(spiString.c_str());
return true;
}

void Bus_SPI::release(void)
{
PrivateSPI->end();
}


void Bus_SPI::beginTransaction(void)
{
dc_h();
//SPISettings setting(_cfg.freq_write, BitOrder::MSBFIRST, _cfg.spi_mode, true);
SPISettings setting(_cfg.freq_write, MSBFIRST, _cfg.spi_mode);
PrivateSPI->beginTransaction(setting);
}

void Bus_SPI::endTransaction(void)
{
PrivateSPI->endTransaction();
dc_h();
}

void Bus_SPI::beginRead(void)
{
PrivateSPI->endTransaction();
//SPISettings setting(_cfg.freq_read, BitOrder::MSBFIRST, _cfg.spi_mode, false);
SPISettings setting(_cfg.freq_read, MSBFIRST, _cfg.spi_mode);
PrivateSPI->beginTransaction(setting);
}

void Bus_SPI::endRead(void)
{
PrivateSPI->endTransaction();
beginTransaction();
}

void Bus_SPI::wait(void)
{
}

bool Bus_SPI::busy(void) const
{
return false;
}

bool Bus_SPI::writeCommand(uint32_t data, uint_fast8_t bit_length)
{
dc_l();
PrivateSPI->transfer((uint8_t*)&data, bit_length >> 3);
dc_h();
return true;
}

void Bus_SPI::writeData(uint32_t data, uint_fast8_t bit_length)
{
PrivateSPI->transfer((uint8_t*)&data, bit_length >> 3);
}

void Bus_SPI::writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t length)
{
/*
auto bytes = bit_length >> 3;
do
{
PrivateSPI->send(reinterpret_cast<uint8_t*>(&data), bytes);
} while (--length);
/*/
const uint8_t dst_bytes = bit_length >> 3;
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
auto buf = _flip_buffer.getBuffer(512);
size_t fillpos = 0;
reinterpret_cast<uint32_t*>(buf)[0] = data;
fillpos += dst_bytes;
uint32_t len;
do
{
len = ((length - 1) % limit) + 1;
if (limit <= 64) limit <<= 1;

while (fillpos < len * dst_bytes)
{
memcpy(&buf[fillpos], buf, fillpos);
fillpos += fillpos;
}

PrivateSPI->transfer(buf, len * dst_bytes);
} while (length -= len);
//*/
}

void Bus_SPI::writePixels(pixelcopy_t* param, uint32_t length)
{
const uint8_t dst_bytes = param->dst_bits >> 3;
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
uint32_t len;
do
{
len = ((length - 1) % limit) + 1;
if (limit <= 32) limit <<= 1;
auto buf = _flip_buffer.getBuffer(len * dst_bytes);
param->fp_copy(buf, 0, len, param);
PrivateSPI->transfer(buf, len * dst_bytes);
} while (length -= len);
}

void Bus_SPI::writeBytes(const uint8_t* data, uint32_t length, bool dc, bool use_dma)
{
if (dc) dc_h();
else dc_l();
PrivateSPI->transfer(const_cast<uint8_t*>(data), length);
if (!dc) dc_h();
}

uint32_t Bus_SPI::readData(uint_fast8_t bit_length)
{
uint32_t res = 0;
bit_length >>= 3;
if (!bit_length) return res;
int idx = 0;
do
{
res |= PrivateSPI->transfer(0) << idx;
idx += 8;
} while (--bit_length);
return res;
}

bool Bus_SPI::readBytes(uint8_t* dst, uint32_t length, bool use_dma)
{
do
{
dst[0] = PrivateSPI->transfer(0);
++dst;
} while (--length);
return true;
}

void Bus_SPI::readPixels(void* dst, pixelcopy_t* param, uint32_t length)
{
uint32_t bytes = param->src_bits >> 3;
uint32_t dstindex = 0;
uint32_t len = 4;
uint8_t buf[24];
param->src_data = buf;
do {
if (len > length) len = length;
readBytes((uint8_t*)buf, len * bytes, true);
param->src_x = 0;
dstindex = param->fp_copy(dst, dstindex, dstindex + len, param);
length -= len;
} while (length);
}

//----------------------------------------------------------------------------
}
}

#endif
104 changes: 104 additions & 0 deletions src/lgfx/v1/platforms/portduino/Bus_SPI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*----------------------------------------------------------------------------/
Lovyan GFX - Graphics library for embedded devices.
Original Source:
https://github.com/lovyan03/LovyanGFX/
Licence:
[FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt)
Author:
[lovyan03](https://twitter.com/lovyan03)
Contributors:
[ciniml](https://github.com/ciniml)
[mongonta0716](https://github.com/mongonta0716)
[tobozo](https://github.com/tobozo)
/----------------------------------------------------------------------------*/
#pragma once

#include <stdint.h>

#include "../../Bus.hpp"
#include "../common.hpp"

namespace lgfx
{
inline namespace v1
{
//----------------------------------------------------------------------------

class Bus_SPI : public IBus
{
public:
struct config_t
{
uint32_t freq_write = 16000000;
uint32_t freq_read = 8000000;
//bool spi_3wire = true;
//bool use_lock = true;
int16_t pin_sclk = -1;
int16_t pin_miso = -1;
int16_t pin_mosi = -1;
int16_t pin_dc = -1;
uint8_t spi_mode = 0;
int8_t spi_host = 0;
};

const config_t& config(void) const { return _cfg; }

void config(const config_t& config);

bus_type_t busType(void) const override { return bus_type_t::bus_spi; }

bool init(void) override;
void release(void) override;

void beginTransaction(void) override;
void endTransaction(void) override;
void wait(void) override;
bool busy(void) const override;

bool writeCommand(uint32_t data, uint_fast8_t bit_length) override;
void writeData(uint32_t data, uint_fast8_t bit_length) override;
void writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t count) override;
void writePixels(pixelcopy_t* param, uint32_t length) override;
void writeBytes(const uint8_t* data, uint32_t length, bool dc, bool use_dma) override;

void initDMA(void) {}
void flush(void) {}
void addDMAQueue(const uint8_t* data, uint32_t length) override { writeBytes(data, length, true, true); }
void execDMAQueue(void) {}
uint8_t* getDMABuffer(uint32_t length) override { return _flip_buffer.getBuffer(length); }

void beginRead(void) override;
void endRead(void) override;
uint32_t readData(uint_fast8_t bit_length) override;
bool readBytes(uint8_t* dst, uint32_t length, bool use_dma) override;
void readPixels(void* dst, pixelcopy_t* param, uint32_t length) override;

protected:

__attribute__ ((always_inline)) inline void dc_h(void) {
gpio_hi(_cfg.pin_dc);
}
__attribute__ ((always_inline)) inline void dc_l(void) {
gpio_lo(_cfg.pin_dc);
}

HardwareSPI *PrivateSPI = &SPI;
config_t _cfg;
FlipBuffer _flip_buffer;
bool _need_wait;
uint32_t _mask_reg_dc;
uint32_t _last_apb_freq = -1;
uint32_t _clkdiv_write;
uint32_t _clkdiv_read;
volatile uint32_t* _gpio_reg_dc_h;
volatile uint32_t* _gpio_reg_dc_l;

};

//----------------------------------------------------------------------------
}
}
Loading

0 comments on commit fe6a27d

Please sign in to comment.