Use the hardware spi interface to drive SHARP's LS013B7DH03.
The gui part can use ugui to provide basic character drawing operations, or you can use other gui frameworks and adjust the corresponding interfaces.
Currently only tested on this model screen, no other tests
The following is the driver file, SPI+DMA mode
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);
}
|