mirror of
https://github.com/sipeed/Maixduino.git
synced 2026-03-06 18:17:00 +01:00
Merge branch 'master' of github.com:btx000/Kenduino-core
This commit is contained in:
399
cores/arduino/SPI.cpp
Normal file
399
cores/arduino/SPI.cpp
Normal file
@@ -0,0 +1,399 @@
|
||||
|
||||
#include "SPI.h"
|
||||
|
||||
#include "stdio.h"
|
||||
#include "utils.h"
|
||||
#include "fpioa.h"
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "./kendryte-standalone-sdk/lib/drivers/include/spi.h"
|
||||
#include "SPI_hal.h"
|
||||
#include "sysctl.h"
|
||||
|
||||
SPIClass SPI;
|
||||
|
||||
extern volatile spi_t *const spi[4];
|
||||
|
||||
static spi_transfer_width_t sipeed_spi_get_frame_size(size_t data_bit_length)
|
||||
{
|
||||
if (data_bit_length < 8)
|
||||
return SPI_TRANS_CHAR;
|
||||
else if (data_bit_length < 16)
|
||||
return SPI_TRANS_SHORT;
|
||||
return SPI_TRANS_INT;
|
||||
}
|
||||
|
||||
static void sipeed_spi_set_tmod(uint8_t spi_num, uint32_t tmod)
|
||||
{
|
||||
configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2);
|
||||
volatile spi_t *spi_handle = spi[spi_num];
|
||||
uint8_t tmod_offset = 0;
|
||||
switch(spi_num)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
tmod_offset = 8;
|
||||
break;
|
||||
case 2:
|
||||
configASSERT(!"Spi Bus 2 Not Support!");
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
tmod_offset = 10;
|
||||
break;
|
||||
}
|
||||
set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param chip_select -1: not use cs
|
||||
*/
|
||||
void sipeed_spi_transfer_data_standard(spi_device_num_t spi_num, int8_t chip_select, const uint8_t *tx_buff,uint8_t *rx_buff, size_t len)
|
||||
{
|
||||
configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2);
|
||||
configASSERT(len > 0);
|
||||
size_t index, fifo_len;
|
||||
size_t rx_len = len;
|
||||
size_t tx_len = rx_len;
|
||||
sipeed_spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV);
|
||||
|
||||
volatile spi_t *spi_handle = spi[spi_num];
|
||||
|
||||
uint8_t dfs_offset;
|
||||
switch(spi_num){
|
||||
case 0:
|
||||
case 1:
|
||||
dfs_offset = 16;
|
||||
break;
|
||||
case 2:
|
||||
configASSERT(!"Spi Bus 2 Not Support!");
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
dfs_offset = 0;
|
||||
break;
|
||||
}
|
||||
uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F;
|
||||
spi_transfer_width_t frame_width = sipeed_spi_get_frame_size(data_bit_length);
|
||||
spi_handle->ctrlr1 = (uint32_t)(tx_len/frame_width - 1);
|
||||
spi_handle->ssienr = 0x01;
|
||||
spi_handle->ser = 1U << chip_select;
|
||||
uint32_t i = 0;
|
||||
while (tx_len)
|
||||
{
|
||||
fifo_len = 32 - spi_handle->txflr;
|
||||
fifo_len = fifo_len < tx_len ? fifo_len : tx_len;
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
fifo_len = fifo_len / 4 * 4;
|
||||
for (index = 0; index < fifo_len / 4; index++)
|
||||
spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++];
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
fifo_len = fifo_len / 2 * 2;
|
||||
for (index = 0; index < fifo_len / 2; index++)
|
||||
spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++];
|
||||
break;
|
||||
default:
|
||||
for (index = 0; index < fifo_len; index++)
|
||||
spi_handle->dr[0] = tx_buff[i++];
|
||||
break;
|
||||
}
|
||||
tx_len -= fifo_len;
|
||||
}
|
||||
|
||||
while ((spi_handle->sr & 0x05) != 0x04)
|
||||
;
|
||||
if(rx_buff)
|
||||
{
|
||||
i = 0;
|
||||
while (rx_len)
|
||||
{
|
||||
fifo_len = spi_handle->rxflr;
|
||||
fifo_len = fifo_len < rx_len ? fifo_len : rx_len;
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
fifo_len = fifo_len / 4 * 4;
|
||||
for (index = 0; index < fifo_len / 4; index++)
|
||||
((uint32_t *)rx_buff)[i++] = spi_handle->dr[0];
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
fifo_len = fifo_len / 2 * 2;
|
||||
for (index = 0; index < fifo_len / 2; index++)
|
||||
((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0];
|
||||
break;
|
||||
default:
|
||||
for (index = 0; index < fifo_len; index++)
|
||||
rx_buff[i++] = (uint8_t)spi_handle->dr[0];
|
||||
break;
|
||||
}
|
||||
|
||||
rx_len -= fifo_len;
|
||||
}
|
||||
}
|
||||
spi_handle->ser = 0x00;
|
||||
spi_handle->ssienr = 0x00;
|
||||
}
|
||||
|
||||
void sipeed_spi_deinit(spi_device_num_t spi_num)
|
||||
{
|
||||
volatile spi_t *spi_handle = spi[spi_num];
|
||||
spi_handle->ssienr = 0x00;
|
||||
sysctl_clock_disable( sysctl_clock_t(SYSCTL_CLOCK_SPI0 + spi_num));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct{
|
||||
int8_t pin;
|
||||
bool used;
|
||||
} spi_ss_t;
|
||||
|
||||
static spi_ss_t g_ss_table[2][4]={
|
||||
{//SPI0
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false}
|
||||
},
|
||||
{//SPI1
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false},
|
||||
{.pin = -1, .used = false}
|
||||
}
|
||||
};
|
||||
|
||||
int8_t getSsByPin(uint8_t spi, int8_t pin)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if(pin<0)
|
||||
return -1;
|
||||
for(i=0; i<4; ++i)
|
||||
{
|
||||
if(g_ss_table[spi][i].used && g_ss_table[spi][i].pin == pin)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t getSsNumLast(uint8_t spi)
|
||||
{
|
||||
uint8_t i=0, count=0;
|
||||
for(i=0; i<4; ++i)
|
||||
{
|
||||
if(!g_ss_table[spi][i].used)
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool checkSs(uint8_t spi, int8_t ss)
|
||||
{
|
||||
int8_t ssPeriph;
|
||||
if( ss < 0) // not use ss
|
||||
return true;
|
||||
ssPeriph = getSsByPin(spi, ss);
|
||||
if(ssPeriph >= 0)
|
||||
return true;
|
||||
if(getSsNumLast(spi) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t setSs(uint8_t spi, int8_t pin)
|
||||
{
|
||||
uint8_t i=0;
|
||||
for(i=0; i<4; ++i)
|
||||
{
|
||||
if(!g_ss_table[spi][i].used)
|
||||
{
|
||||
g_ss_table[spi][i].used = true;
|
||||
g_ss_table[spi][i].pin = pin;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param miso -1: not use miso
|
||||
* @param mosi must >= 0
|
||||
* @param ss -1: not use hardware ss
|
||||
*/
|
||||
bool checkPinParam(uint8_t spi, int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||
{
|
||||
if(!checkSs(spi, ss))
|
||||
return false;
|
||||
//TODO:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkFreq(uint32_t freq)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool checkBitOder(uint8_t bitOrder)
|
||||
{
|
||||
//TODO: support LSB
|
||||
if(bitOrder!=SPI_MSBFIRST)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool checkDataMode(uint8_t dataMode)
|
||||
{
|
||||
if(dataMode > SPI_MODE3)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(spi_id_t spi_bus)
|
||||
:_spiNum(spi_bus), _freq(1000000),
|
||||
_sck(-1), _miso(-1), _mosi(-1), _ss(-1),
|
||||
_inTransaction(false),
|
||||
_initPinsInConstruct(false)
|
||||
{
|
||||
configASSERT(_spiNum==SPI_SOFT || _spiNum==SPI0 || _spiNum==SPI1);
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(spi_id_t spi_bus, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint32_t freq)
|
||||
:_spiNum(spi_bus), _freq(freq),
|
||||
_sck(sck), _miso(miso), _mosi(mosi), _ss(ss),
|
||||
_inTransaction(false),
|
||||
_initPinsInConstruct(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ss -1: not use
|
||||
*/
|
||||
void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||
{
|
||||
if(_initPinsInConstruct)
|
||||
{
|
||||
sck = _sck;
|
||||
miso = _miso;
|
||||
mosi = _mosi;
|
||||
ss = _ss;
|
||||
}
|
||||
configASSERT(checkPinParam(_spiNum, sck, miso, mosi, ss));
|
||||
|
||||
if(_spiNum == SPI_SOFT)
|
||||
{
|
||||
configASSERT(!"Soft SPI Not Support Yet!");
|
||||
return ;
|
||||
}
|
||||
//hardware SPI
|
||||
if(_spiNum == SPI0)
|
||||
{
|
||||
fpioa_set_function(sck, FUNC_SPI0_SCLK);
|
||||
if( ss >= 0)
|
||||
{
|
||||
fpioa_function_t a = (fpioa_function_t)(FUNC_SPI0_SS0+setSs(_spiNum, ss));
|
||||
fpioa_set_function(ss, a);
|
||||
}
|
||||
fpioa_set_function(mosi, FUNC_SPI0_D0);
|
||||
if(miso>=0)
|
||||
fpioa_set_function(miso, FUNC_SPI0_D1);
|
||||
}
|
||||
else if(_spiNum == SPI1)
|
||||
{
|
||||
fpioa_set_function(sck, FUNC_SPI1_SCLK);
|
||||
if( ss >= 0)
|
||||
{
|
||||
fpioa_set_function(ss, (fpioa_function_t)(FUNC_SPI1_SS0+setSs(_spiNum, ss)));
|
||||
}
|
||||
fpioa_set_function(mosi, FUNC_SPI1_D0);
|
||||
if(miso>=0)
|
||||
fpioa_set_function(miso, FUNC_SPI1_D1);
|
||||
}
|
||||
_mosi = mosi;
|
||||
_miso = miso;
|
||||
_sck = sck;
|
||||
_ss = ss;
|
||||
_ssPeriph = getSsByPin(_spiNum, ss);
|
||||
if(_ssPeriph<0)
|
||||
_ssPeriph = 0; // default to cs0 TODO: optimize?
|
||||
spi_init(spi_device_num_t(_spiNum), spi_work_mode_t(_dataMode), SPI_FF_STANDARD, 8, 0);
|
||||
spi_set_clk_rate(spi_device_num_t(_spiNum), _freq);
|
||||
}
|
||||
|
||||
void SPIClass::end()
|
||||
{
|
||||
sipeed_spi_deinit(spi_device_num_t(_spiNum));
|
||||
}
|
||||
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder)
|
||||
{
|
||||
//TODO: support LSB
|
||||
configASSERT(bitOrder==SPI_MSBFIRST);
|
||||
}
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode)
|
||||
{
|
||||
_dataMode = dataMode;
|
||||
spi_init(spi_device_num_t(_spiNum), spi_work_mode_t(_dataMode), SPI_FF_STANDARD, 8, 0);
|
||||
}
|
||||
|
||||
void SPIClass::setFrequency(uint32_t freq)
|
||||
{
|
||||
_freq = freq;
|
||||
spi_set_clk_rate(spi_device_num_t(_spiNum), _freq);
|
||||
}
|
||||
|
||||
void SPIClass::beginTransaction(SPISettings settings)
|
||||
{
|
||||
SPI_MUTEX_LOCK();
|
||||
_inTransaction = true;
|
||||
if( settings._freq!=_freq || settings._dataMode!=_dataMode || settings._bitOrder!=_bitOrder)
|
||||
{
|
||||
_dataMode = settings._dataMode;
|
||||
_bitOrder = settings._bitOrder; //TODO: bit order
|
||||
_freq = settings._freq;
|
||||
spi_init(spi_device_num_t(_spiNum), spi_work_mode_t(_dataMode), SPI_FF_STANDARD, 8, 0);
|
||||
spi_set_clk_rate(spi_device_num_t(_spiNum), _freq);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SPIClass::endTransaction(void)
|
||||
{
|
||||
_inTransaction = false;
|
||||
SPI_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void SPIClass::transfer(uint8_t * data, uint32_t size)
|
||||
{
|
||||
sipeed_spi_transfer_data_standard(spi_device_num_t(_spiNum), _ssPeriph, data, NULL, size);
|
||||
}
|
||||
|
||||
uint8_t SPIClass::transfer(uint8_t data)
|
||||
{
|
||||
uint8_t temp;
|
||||
sipeed_spi_transfer_data_standard(spi_device_num_t(_spiNum), _ssPeriph, &data, &temp, 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void SPIClass::transferBytes(uint8_t * data, uint8_t * out, uint32_t size)
|
||||
{
|
||||
sipeed_spi_transfer_data_standard(spi_device_num_t(_spiNum), _ssPeriph, data, out, size);
|
||||
}
|
||||
|
||||
|
||||
SPISettings::SPISettings(uint32_t freq, uint8_t bitOrder, uint8_t dataMode)
|
||||
:_freq(freq), _bitOrder(bitOrder), _dataMode(dataMode)
|
||||
{
|
||||
configASSERT(checkFreq(freq));
|
||||
configASSERT(checkBitOder(bitOrder));
|
||||
configASSERT(checkDataMode(dataMode));
|
||||
}
|
||||
|
||||
78
cores/arduino/SPI.h
Normal file
78
cores/arduino/SPI.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef __SPI_H
|
||||
#define __SPI_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef enum{
|
||||
SPI_SOFT = -1,
|
||||
SPI0 = 0,
|
||||
SPI1,
|
||||
SPI2,
|
||||
SPI3,
|
||||
SPI_MAX
|
||||
} spi_id_t;
|
||||
|
||||
|
||||
#define SPI_LSBFIRST 0
|
||||
#define SPI_MSBFIRST 1
|
||||
|
||||
#define SPI_MODE0 0
|
||||
#define SPI_MODE1 1
|
||||
#define SPI_MODE2 2
|
||||
#define SPI_MODE3 3
|
||||
|
||||
|
||||
class SPISettings
|
||||
{
|
||||
public:
|
||||
SPISettings() :_freq(1000000), _bitOrder(SPI_MSBFIRST), _dataMode(SPI_MODE0) {}
|
||||
SPISettings(uint32_t freq, uint8_t bitOrder, uint8_t dataMode);
|
||||
uint32_t _freq;
|
||||
uint8_t _bitOrder;
|
||||
uint8_t _dataMode;
|
||||
};
|
||||
|
||||
class SPIClass
|
||||
{
|
||||
private:
|
||||
spi_id_t _spiNum;
|
||||
uint32_t _freq;
|
||||
int8_t _sck;
|
||||
int8_t _miso;
|
||||
int8_t _mosi;
|
||||
int8_t _ss; //pin
|
||||
int8_t _ssPeriph; //peripheral
|
||||
uint8_t _dataMode;
|
||||
uint8_t _bitOrder;
|
||||
bool _inTransaction;
|
||||
bool _initPinsInConstruct;
|
||||
|
||||
public:
|
||||
SPIClass(spi_id_t spi_bus = SPI1);
|
||||
/*
|
||||
* API just for k210
|
||||
*/
|
||||
SPIClass(spi_id_t spi_bus, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint32_t freq = 1000000);
|
||||
void begin(int8_t sck=27, int8_t miso=26, int8_t mosi=28, int8_t ss=-1);
|
||||
void end();
|
||||
|
||||
void setBitOrder(uint8_t bitOrder);
|
||||
void setDataMode(uint8_t dataMode);
|
||||
void setFrequency(uint32_t freq);
|
||||
|
||||
void beginTransaction(SPISettings settings);
|
||||
void endTransaction(void);
|
||||
void transfer(uint8_t * data, uint32_t size);
|
||||
uint8_t transfer(uint8_t data);
|
||||
|
||||
void transferBytes(uint8_t * data, uint8_t * out, uint32_t size);
|
||||
|
||||
// special
|
||||
spi_id_t busId(){ return _spiNum; }
|
||||
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
|
||||
|
||||
#endif //__SPI_H
|
||||
Submodule cores/arduino/kendryte-standalone-sdk updated: 9fb2182338...ee61b9eefd
107
cores/arduino/st7789.c
Normal file
107
cores/arduino/st7789.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "st7789.h"
|
||||
|
||||
|
||||
static uint8_t g_gpio_dcx;
|
||||
static int8_t g_gpio_rst;
|
||||
static spi_device_num_t g_spi_num;
|
||||
static dmac_channel_number_t g_dma_ch;
|
||||
static uint8_t g_ss;
|
||||
|
||||
static void init_dcx(uint8_t dcx, int8_t dcx_pin)
|
||||
{
|
||||
fpioa_set_function(dcx_pin , FUNC_GPIO0 + dcx);
|
||||
g_gpio_dcx = dcx;
|
||||
gpio_set_drive_mode(g_gpio_dcx, GPIO_DM_OUTPUT);
|
||||
gpio_set_pin(g_gpio_dcx, GPIO_PV_HIGH);
|
||||
}
|
||||
|
||||
static void set_dcx_control(void)
|
||||
{
|
||||
gpio_set_pin(g_gpio_dcx, GPIO_PV_LOW);
|
||||
}
|
||||
|
||||
static void set_dcx_data(void)
|
||||
{
|
||||
gpio_set_pin(g_gpio_dcx, GPIO_PV_HIGH);
|
||||
}
|
||||
|
||||
static void init_rst(uint8_t rst, int8_t rst_pin)
|
||||
{
|
||||
g_gpio_rst = rst;
|
||||
if( rst_pin < 0)
|
||||
return ;
|
||||
fpioa_set_function(rst_pin , FUNC_GPIO0 + rst);
|
||||
gpio_set_drive_mode(g_gpio_rst, GPIO_DM_OUTPUT);
|
||||
gpio_set_pin(g_gpio_rst, GPIO_PV_HIGH);
|
||||
}
|
||||
|
||||
static void set_rst(uint8_t val)
|
||||
{
|
||||
if(g_gpio_rst < 0)
|
||||
return ;
|
||||
gpio_set_pin(g_gpio_rst, val);
|
||||
}
|
||||
|
||||
void tft_set_clk_freq(uint32_t freq)
|
||||
{
|
||||
spi_set_clk_rate(g_spi_num, freq);
|
||||
}
|
||||
|
||||
void tft_hard_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch)
|
||||
{
|
||||
g_spi_num = spi;
|
||||
g_dma_ch = dma_ch;
|
||||
g_ss = ss;
|
||||
init_dcx(dcx, dcx_pin);
|
||||
init_rst(rst, rst_pin);
|
||||
set_rst(0);
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
|
||||
tft_set_clk_freq(freq);
|
||||
set_rst(1);
|
||||
}
|
||||
|
||||
void tft_write_command(uint8_t cmd)
|
||||
{
|
||||
set_dcx_control();
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
|
||||
spi_init_non_standard(g_spi_num, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
|
||||
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
|
||||
spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, (uint8_t *)(&cmd), 1, SPI_TRANS_CHAR);
|
||||
}
|
||||
|
||||
void tft_write_byte(uint8_t *data_buf, uint32_t length)
|
||||
{
|
||||
set_dcx_data();
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
|
||||
spi_init_non_standard(g_spi_num, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
|
||||
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
|
||||
spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_CHAR);
|
||||
}
|
||||
|
||||
void tft_write_half(uint16_t *data_buf, uint32_t length)
|
||||
{
|
||||
set_dcx_data();
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0);
|
||||
spi_init_non_standard(g_spi_num, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
|
||||
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
|
||||
spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_SHORT);
|
||||
}
|
||||
|
||||
void tft_write_word(uint32_t *data_buf, uint32_t length)
|
||||
{
|
||||
set_dcx_data();
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
|
||||
|
||||
spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/,
|
||||
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
|
||||
spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_INT);
|
||||
}
|
||||
|
||||
void tft_fill_data(uint32_t *data_buf, uint32_t length)
|
||||
{
|
||||
set_dcx_data();
|
||||
spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
|
||||
spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/,
|
||||
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
|
||||
spi_fill_data_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length);
|
||||
}
|
||||
107
cores/arduino/st7789.h
Normal file
107
cores/arduino/st7789.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef _ST7789_H_
|
||||
#define _ST7789_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "gpio.h"
|
||||
#include "fpioa.h"
|
||||
#include "./kendryte-standalone-sdk/lib/drivers/include/spi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* clang-format off */
|
||||
#define NO_OPERATION 0x00
|
||||
#define SOFTWARE_RESET 0x01
|
||||
#define READ_ID 0x04
|
||||
#define READ_STATUS 0x09
|
||||
#define READ_POWER_MODE 0x0A
|
||||
#define READ_MADCTL 0x0B
|
||||
#define READ_PIXEL_FORMAT 0x0C
|
||||
#define READ_IMAGE_FORMAT 0x0D
|
||||
#define READ_SIGNAL_MODE 0x0E
|
||||
#define READ_SELT_DIAG_RESULT 0x0F
|
||||
#define SLEEP_ON 0x10
|
||||
#define SLEEP_OFF 0x11
|
||||
#define PARTIAL_DISPALY_ON 0x12
|
||||
#define NORMAL_DISPALY_ON 0x13
|
||||
#define INVERSION_DISPALY_OFF 0x20
|
||||
#define INVERSION_DISPALY_ON 0x21
|
||||
#define GAMMA_SET 0x26
|
||||
#define DISPALY_OFF 0x28
|
||||
#define DISPALY_ON 0x29
|
||||
#define HORIZONTAL_ADDRESS_SET 0x2A
|
||||
#define VERTICAL_ADDRESS_SET 0x2B
|
||||
#define MEMORY_WRITE 0x2C
|
||||
#define COLOR_SET 0x2D
|
||||
#define MEMORY_READ 0x2E
|
||||
#define PARTIAL_AREA 0x30
|
||||
#define VERTICAL_SCROL_DEFINE 0x33
|
||||
#define TEAR_EFFECT_LINE_OFF 0x34
|
||||
#define TEAR_EFFECT_LINE_ON 0x35
|
||||
#define MEMORY_ACCESS_CTL 0x36
|
||||
#define VERTICAL_SCROL_S_ADD 0x37
|
||||
#define IDLE_MODE_OFF 0x38
|
||||
#define IDLE_MODE_ON 0x39
|
||||
#define PIXEL_FORMAT_SET 0x3A
|
||||
#define WRITE_MEMORY_CONTINUE 0x3C
|
||||
#define READ_MEMORY_CONTINUE 0x3E
|
||||
#define SET_TEAR_SCANLINE 0x44
|
||||
#define GET_SCANLINE 0x45
|
||||
#define WRITE_BRIGHTNESS 0x51
|
||||
#define READ_BRIGHTNESS 0x52
|
||||
#define WRITE_CTRL_DISPALY 0x53
|
||||
#define READ_CTRL_DISPALY 0x54
|
||||
#define WRITE_BRIGHTNESS_CTL 0x55
|
||||
#define READ_BRIGHTNESS_CTL 0x56
|
||||
#define WRITE_MIN_BRIGHTNESS 0x5E
|
||||
#define READ_MIN_BRIGHTNESS 0x5F
|
||||
#define READ_ID1 0xDA
|
||||
#define READ_ID2 0xDB
|
||||
#define READ_ID3 0xDC
|
||||
#define RGB_IF_SIGNAL_CTL 0xB0
|
||||
#define NORMAL_FRAME_CTL 0xB1
|
||||
#define IDLE_FRAME_CTL 0xB2
|
||||
#define PARTIAL_FRAME_CTL 0xB3
|
||||
#define INVERSION_CTL 0xB4
|
||||
#define BLANK_PORCH_CTL 0xB5
|
||||
#define DISPALY_FUNCTION_CTL 0xB6
|
||||
#define ENTRY_MODE_SET 0xB7
|
||||
#define BACKLIGHT_CTL1 0xB8
|
||||
#define BACKLIGHT_CTL2 0xB9
|
||||
#define BACKLIGHT_CTL3 0xBA
|
||||
#define BACKLIGHT_CTL4 0xBB
|
||||
#define BACKLIGHT_CTL5 0xBC
|
||||
#define BACKLIGHT_CTL7 0xBE
|
||||
#define BACKLIGHT_CTL8 0xBF
|
||||
#define POWER_CTL1 0xC0
|
||||
#define POWER_CTL2 0xC1
|
||||
#define VCOM_CTL1 0xC5
|
||||
#define VCOM_CTL2 0xC7
|
||||
#define NV_MEMORY_WRITE 0xD0
|
||||
#define NV_MEMORY_PROTECT_KEY 0xD1
|
||||
#define NV_MEMORY_STATUS_READ 0xD2
|
||||
#define READ_ID4 0xD3
|
||||
#define POSITIVE_GAMMA_CORRECT 0xE0
|
||||
#define NEGATIVE_GAMMA_CORRECT 0xE1
|
||||
#define DIGITAL_GAMMA_CTL1 0xE2
|
||||
#define DIGITAL_GAMMA_CTL2 0xE3
|
||||
#define INTERFACE_CTL 0xF6
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
void tft_hard_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch);
|
||||
void tft_set_clk_freq(uint32_t freq);
|
||||
void tft_write_command(uint8_t cmd);
|
||||
void tft_write_byte(uint8_t *data_buf, uint32_t length);
|
||||
void tft_write_half(uint16_t *data_buf, uint32_t length);
|
||||
void tft_write_word(uint32_t *data_buf, uint32_t length);
|
||||
void tft_fill_data(uint32_t *data_buf, uint32_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user