使用硬件spi接口,驱动SHARP的LS013B7DH03,
gui部分可以采用ugui提供基本的字符绘图操作,也可以使用其他的gui框架,调整相应的接口即可
目前只在本型号屏幕试过,其他的未作测试
下面是驱动文件,SPI+DMA方式
sharp_mlcd.h
#ifndef __SHARP_MLCD_H
#define __SHARP_MLCD_H
#include <stdint.h>
#include <stdbool.h>
#define LS013B7DH03
#ifndef SPI_LSB
#define SHARP_MIP_REV_BYTE(b) ((uint8_t) __REV(__RBIT(b))) /*Architecture / compiler dependent byte bits order reverse*/
#else
#define SHARP_MIP_REV_BYTE(b) (b)
#endif
#ifndef SPI_LSB
#define MLCD_WR 0x80
#define MLCD_VCOM 0x40
#define MLCD_CLR 0x20
#else
#define MLCD_WR 0x01
#define MLCD_VCOM 0x02
#define MLCD_CLR 0x04
#endif
#ifdef LS027B7DH01
#define DISP_HOR_RESOLUTION 400
#define DISP_VER_RESOLUTION 240
#elif defined LS032B7DD02
#define DISP_HOR_RESOLUTION 336
#define DISP_VER_RESOLUTION 536
#elif defined LS044Q7DH01
#define DISP_HOR_RESOLUTION 320
#define DISP_VER_RESOLUTION 240
#elif defined LS006B7DH03
#define DISP_HOR_RESOLUTION 64
#define DISP_VER_RESOLUTION 64
#elif defined LS011B7DH03
#define DISP_HOR_RESOLUTION 160
#define DISP_VER_RESOLUTION 68
#elif defined LS013B7DH03
#define DISP_HOR_RESOLUTION 128
#define DISP_VER_RESOLUTION 128
#else
#error You need to define the horizontal and vertical resolution for a new model
#endif
//@note Horizontal screen size in byte count
#define GFX_FB_CANVAS_W ((DISP_HOR_RESOLUTION + 7) / 8)
//@note Vertical screen size in line number
#define GFX_FB_CANVAS_H DISP_VER_RESOLUTION
//@note EXTCOMIN pulse frequency in hal_extcom_start(hz) fcn. -> GFXDisplayOn()
#define EXTCOMIN_FREQ 1
#define BUF_LEN ((GFX_FB_CANVAS_W+2)*GFX_FB_CANVAS_H+2)
extern uint8_t frameBuffer[BUF_LEN];
typedef enum
{
BLACK = 0,
WHITE,
TRANSPARENT //means leaving original color
} MLCD_COLOR;
typedef struct {
const uint8_t *data;
uint16_t width;
uint16_t height;
uint8_t dataSize;
} tImage;
void mlcd_init();
void mlcd_update();
void mlcd_clear();
void mlcd_clearbufer(MLCD_COLOR color);
void GFXDisplayPutPixel(int16_t x, int16_t y, MLCD_COLOR color);
void GFXDisplayPutImage(int16_t x0, int16_t y0, const tImage* image, bool invert);
void GFXDisplayPutBitmap(int x0, int y0, uint16_t width, uint16_t height, const uint8_t *bmp, bool invert);
void init_buffer(uint8_t data);
#endif
sharp_mlcd.c
#include "sharp_mlcd.h"
#include "rsl10.h"
#include "board.h"
#include "app.h"
uint8_t frameBuffer[BUF_LEN];
static uint8_t clrdata[2]={MLCD_CLR,0};
static bool f_finished=false;
static uint8_t w;
#define LCD_TX_DMA_NUM 6
#define LCD_TX_DMA_SPI (DMA_DEST_SPI0 | \
DMA_TRANSFER_M_TO_P | \
DMA_LITTLE_ENDIAN | \
DMA_COMPLETE_INT_ENABLE | \
DMA_COUNTER_INT_DISABLE | \
DMA_START_INT_DISABLE | \
DMA_DEST_WORD_SIZE_8 | \
DMA_SRC_WORD_SIZE_32 | \
DMA_SRC_ADDR_INC | \
DMA_DEST_ADDR_STATIC | \
DMA_ADDR_LIN | \
DMA_DISABLE)
static void delay_us(uint32_t us)
{
Sys_Delay_ProgramROM((uint32_t)(0.000001 * SystemCoreClock*us));
// Sys_Delay_ProgramROM((uint32_t)(0.01 * SystemCoreClock));
}
static void start_trans()
{
Sys_GPIO_Set_High(PIN_LCD_CS);
}
static void end_trans()
{
Sys_GPIO_Set_Low(PIN_LCD_CS);
}
/* ----------------------------------------------------------------------------
* Function : void DMA_IRQ_FUNC(RX_DMA_NUM)(void)
* ----------------------------------------------------------------------------
* Description : DMA Channel assigned to SPI and PCM receive interrupt handler
* Inputs : None
* Outputs : None
* Assumptions : None
* ------------------------------------------------------------------------- */
void DMA_IRQ_FUNC(LCD_TX_DMA_NUM)(void)
{
f_finished=true;
Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
}
//void DMA6_IRQHandler()
//{
// Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
// NVIC_ClearPendingIRQ(DMA_IRQn(LCD_TX_DMA_NUM));
//}
void init_buffer(uint8_t data)
{
w = 2+GFX_FB_CANVAS_W;
//init buffer
memset(frameBuffer,data,BUF_LEN);
for(uint8_t i = 0; i < GFX_FB_CANVAS_H; i++)
{
frameBuffer[0 + i * w] = 0;
frameBuffer[1 + i * w] = SHARP_MIP_REV_BYTE(i + 1);
}
frameBuffer[0] = MLCD_WR;
frameBuffer[BUF_LEN - 2] = 0;
frameBuffer[BUF_LEN - 1] = 0x00;
}
void mlcd_init()
{
Sys_DIO_Config(PIN_LCD_CS, DIO_6X_DRIVE | DIO_NO_PULL | DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(PIN_LCD_CS);
Sys_DIO_Config(PIN_LCD_COM, DIO_6X_DRIVE | DIO_NO_PULL | DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(PIN_LCD_COM);
/* Initialize SPI interface */
// Sys_SPI_DIOConfig(0, SPI0_SELECT_MASTER, DIO_LPF_DISABLE | DIO_NO_PULL, PIN_LCD_SCLK, PIN_LCD_CS, PIN_LCD_MISO, PIN_LCD_MOSI);
Sys_DIO_Config(PIN_LCD_SCLK,DIO_MODE_SPI0_CLK|DIO_LPF_DISABLE | DIO_6X_DRIVE |DIO_NO_PULL);
Sys_DIO_Config(PIN_LCD_MOSI,DIO_MODE_SPI0_SERO|DIO_LPF_DISABLE | DIO_6X_DRIVE |DIO_NO_PULL);
/* Configure the SPI0 interface */
Sys_SPI_Config(0, SPI0_SELECT_MASTER | SPI0_ENABLE |
SPI0_CLK_POLARITY_NORMAL | SPI0_CONTROLLER_DMA |
SPI0_MODE_SELECT_AUTO | SPI0_PRESCALE_32);
Sys_SPI_TransferConfig(0, SPI0_START | SPI0_WRITE_DATA | SPI0_CS_1 |
SPI0_WORD_SIZE_8);
init_buffer(0x00);
Sys_Delay_ProgramROM((uint32_t)(1 * SystemCoreClock));
/* Clear the current status for the DMA receive channel for SPI */
Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
/* Enable DMA receive channel. */
// Sys_DMA_ChannelEnable(LCD_TX_DMA_NUM);
/* Clear pending DMA receive channel request and configure interrupt. */
NVIC_ClearPendingIRQ(DMA_IRQn(LCD_TX_DMA_NUM));
NVIC_SetPriority(DMA_IRQn(LCD_TX_DMA_NUM), 2);
/* Enable DMA receive channel interrupt. */
NVIC_EnableIRQ(DMA_IRQn(LCD_TX_DMA_NUM));
/* Unmask interrupts. */
// __set_PRIMASK(PRIMASK_ENABLE_INTERRUPTS);
// __set_FAULTMASK(FAULTMASK_ENABLE_INTERRUPTS);
}
void mlcd_clearbufer(MLCD_COLOR color)
{
uint8_t data;
if(color == WHITE)
{
data=0xff;
}
else
{
data=0;
}
for(uint8_t i=0;i<GFX_FB_CANVAS_H;i++)
{
memset(&frameBuffer[2+((GFX_FB_CANVAS_W+2)*i)],data,GFX_FB_CANVAS_W);
}
}
void mlcd_update()
{
start_trans();
// delay_us(6);
Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
f_finished=false;
Sys_DMA_ChannelConfig(
LCD_TX_DMA_NUM,
LCD_TX_DMA_SPI,
BUF_LEN,
0,
(uint32_t)frameBuffer,
(uint32_t)&SPI0->TX_DATA
);
Sys_DMA_ChannelEnable(LCD_TX_DMA_NUM);
while(!f_finished)
{
}
// delay_us(2);
end_trans();
// delay_us(6);
}
//clear screen
void mlcd_clear()
{
delay_us(6);
start_trans();
delay_us(6);
f_finished=false;
Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
Sys_DMA_ChannelConfig(
LCD_TX_DMA_NUM,
LCD_TX_DMA_SPI,
2,
0,
(uint32_t)clrdata,
(uint32_t)&SPI0->TX_DATA
);
Sys_DMA_ChannelEnable(LCD_TX_DMA_NUM);
while(!f_finished)
{
}
Sys_DMA_ClearChannelStatus(LCD_TX_DMA_NUM);
delay_us(2);
end_trans();
delay_us(6);
}
static void GFXDisplayPutPixel_FB(int16_t x, int16_t y, MLCD_COLOR color) {
if (y > (GFX_FB_CANVAS_H - 1) || ((x >> 3) > (GFX_FB_CANVAS_W - 1)))
//avoid running outside array index
return;
if(x<0)return;
if(y<0)return;
uint8_t maskBit;
maskBit = 0x80 >> (x & 0x07); //SPI data sent with MSB first
//maskBit = 0x01 << (x & 0x07); //SPI data sent with LSB first
if (color == WHITE)
{
frameBuffer[y*w+2+(x >> 3)] |= maskBit;
} //frameBuffer[y][(x>>1)] &= (maskBit^0xFF); frameBuffer[y][(x>>1)] |= color;
else if(color == BLACK)
{
frameBuffer[y*w+2+(x >> 3)] &= (maskBit ^ 0xFF);
}
else
{
}
}
void GFXDisplayPutPixel(int16_t x, int16_t y, MLCD_COLOR color)
{
GFXDisplayPutPixel_FB(x, y, color);
}
|