2023 views|2 replies

95

Posts

4

Resources
The OP
 

RSL10 drives ink screen [Copy link]

 

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);

}

Latest reply

Not bad, it uses DMA! Looking forward to the follow-up works!   Details Published on 2021-6-28 08:51

赞赏

1

查看全部赞赏

 
 

6587

Posts

0

Resources
2
 

Thanks for sharing

Are you using ugui to provide basic character drawing operations?

 
 
 

1942

Posts

2

Resources
3
 

Not bad, it uses DMA! Looking forward to the follow-up works!

 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list