您尚未登录。

楼主 #1 2020-05-09 18:35:23

缥缈九哥
会员
注册时间: 2020-05-09
已发帖子: 76
积分: 102

基于NANO120的16位EBI总线的SSD1963的480X272驱动--缥缈九哥

最近做个项目,用到ARMJISHU公司的神舟III号4.3寸液晶屏,用NANO120KE3BN驱动起来了。CPU的PLL是96M,主频超到了48M。特地发出来抛砖引玉。

源码:

/******************************************************************************
* @file     ssd1963.c
* @brief    The Driver code for 480*272 16 Color LCD with NANO120KE3BN
* @version  1.0.0
* @date     05, December, 2013
*
* @note
* Copyright (C) 2000-2013 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "nano1xx.h"
#include "nano1xx_gpio.h"
#include "nano1xx_ebi.h"
#include "stdlib.h"
#include "core_cmInstr.h"
#include "rfid.h"
/*
_________________________________________________
| NANO120KE3BN     SSD1963  |
|            |
| EBIAD0- EBIAD15  <--->  DB0-DB15 |
| EBIWR PA10  ---->  WR#   |
| EBIRD PA11  ---->  RD#   |
| EBICS PB7   ---->  CS#   |
| PB6  EBIALE  ---->  D/C#  |
| PA8  EBIPA8  ---->  RESET#  |
| PA9  EBIPA9  ---->  LEDA  |
|_______________________________________________|
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define LCD_LEDA  GPIOA, 9  /* PA9=High,BackLight ON; Low,BackLight OFF */
#define LCD_RESET  GPIOA, 8  /* PA8=Low,LCD Reset;PA8=High,LCD Working   */
#define LCD_DCMD  GPIOB, 6  /* PB6=High,DATA mode; PB6=Low,COMMAND mode */
#define LCD_RESET_DELAY 100    /* LCD_RESET=Low,LCD_RESET_DELAY>=100us  */
#define BLACK         0x0000        /* 黑色:  0  , 0  , 0   */        
#define NAVY          0x000F         /* 深蓝色: 0  , 0  , 128   */        
#define DGREEN        0x03E0          /* 深绿色: 0  , 128, 0     */      
#define DCYAN         0x03EF         /* 深青色: 0  , 128, 128   */      
#define MAROON        0x7800          /* 深红色: 128, 0  , 0     */      
#define PURPLE       0x780F          /* 紫色:  128, 0  , 128   */        
#define OLIVE         0x7BE0         /* 橄榄绿: 128, 128, 0     */     
#define LGRAY         0xC618         /* 灰白色: 192, 192, 192   */      
#define DGRAY         0x7BEF          /* 深灰色: 128, 128, 128   */      
#define BLUE          0x001F          /* 蓝色:  0  , 0  , 255   */         
#define GREEN         0x07E0          /* 绿色:  0  , 255, 0     */         
#define CYAN          0x07FF          /* 青色:  0  , 255, 255   */         
#define RED           0xF800          /* 红色:  255, 0  , 0     */         
#define MAGENTA       0xF81F          /* 品红:  255, 0  , 255   */        
#define YELLOW        0xFFE0         /* 黄色:  255, 255, 0     */      
#define WHITE         0xFFFF          /* 白色:  255, 255, 255  */
#define SSD1963_HDP  0xDF01   /* HDP=479=0x01DF  */
#define SSD1963_HT  0x1302   /* HT =531=0x0213  */
#define SSD1963_HPS  0x2B00   /* HPS=43 =0x002B */
#define SSD1963_LPS  0x0800   /* LPS=8  =0x0008 */
#define SSD1963_HPW  10    /* HPW=10 =0x0A  */
#define SSD1963_VDP  0x0F01   /* VDP=271=0x010F */
#define SSD1963_VT  0x2001   /* VT =288=0x0120  */
#define SSD1963_VPS  0x0C00   /* VPS=12 =0x000C */
#define SSD1963_FPS  0x0100   /* FPS=1  =0x0001 */
#define SSD1963_VPW  10    /* VPW=10 =0x0A  */
/* Private macro -------------------------------------------------------------*/
/*  Command      Hex Code Description */
#define SSD1963_nop      0x00 /* No operation */
#define SSD1963_soft_reset     0x01 /* Software Reset */
#define SSD1963_get_power_mode    0x0A /* Get the current power mode */
#define SSD1963_get_address_mode   0x0B /* Get the frame buffer to the display panel read order */
#define SSD1963_Reserved0c     0x0C /* Reserved */
#define SSD1963_get_display_mode   0x0D /* The SSD1963 returns the Display Image Mode. */
#define SSD1963_get_tear_effect_status  0x0E /* Get the Tear Effect status */
#define SSD1963_Reserved0f     0x0F /* Reserved */
#define SSD1963_enter_sleep_mode   0x10 /* Turn off the panel. This command will pull low the GPIO0. If GPIO0 is configured as normal GPIO or LCD miscellaneous signal with command set_gpio_conf, this command will be ignored. */
#define SSD1963_exit_sleep_mode   0x11 /* Turn on the panel. This command will pull high the GPIO0. If GPIO0 is configured as normal GPIO or LCD miscellaneous signal with command set_gpio_conf, this command will be ignored. */
#define SSD1963_enter_partial_mode   0x12 /* Part of the display area is used for image display. */
#define SSD1963_enter_normal_mode   0x13 /* The whole display area is used for image display. */
#define SSD1963_exit_invert_mode   0x20 /* Displayed image colors are not inverted. */
#define SSD1963_enter_invert_mode   0x21 /* Displayed image colors are inverted. */
#define SSD1963_set_gamma_curve   0x26 /* Selects the gamma curve used by the display panel. */
#define SSD1963_set_display_off   0x28 /* Blanks the display panel */
#define SSD1963_set_display_on    0x29 /* Show the image on the display panel */
#define SSD1963_set_column_address   0x2A /* Set the column address */
#define SSD1963_set_page_address   0x2B /* Set the page address */
#define SSD1963_write_memory_start   0x2C /* Transfer image information from the host processor interface to the SSD1963 starting at the location provided by set_column_address and set_page_address  */
#define SSD1963_read_memory_start   0x2E /* Transfer image data from the SSD1963 to the host processor interface starting at the location provided by set_column_address and set_page_address  */
#define SSD1963_set_partial_area   0x30 /* Defines the partial display area on the display panel */
#define SSD1963_set_scroll_area   0x33 /* Defines the vertical scrolling and fixed area on display area */
#define SSD1963_set_tear_off    0x34 /* Synchronization information is not sent from the SSD1963 to the host processor */
#define SSD1963_set_tear_on    0x35 /* Synchronization information is sent from the SSD1963 to the host processor at the start of VFP */
#define SSD1963_set_address_mode   0x36 /* Set the read order from frame buffer to the display panel */
#define SSD1963_set_scroll_start   0x37 /* Defines the vertical scrolling starting point */
#define SSD1963_exit_idle_mode    0x38 /* Full color depth is used for the display panel */
#define SSD1963_enter_idle_mode   0x39 /* Reduce color depth is used on the display panel. */
#define SSD1963_Reserved3a     0x3A /* Reserved */
#define SSD1963_write_memory_continue  0x3C /* Transfer image information from the host processor interface to the SSD1963 from the last written location */
#define SSD1963_read_memory_continue  0x3E /* Read image data from the SSD1963 continuing after the last read_memory_continue or read_memory_start */
#define SSD1963_set_tear_scanline   0x44 /* Synchronization information is sent from the SSD1963 to the host processor when the display panel refresh reaches the provided scanline  */
#define SSD1963_get_scanline    0x45 /* Get the current scan line */
#define SSD1963_read_ddb     0xA1 /* Read the DDB from the provided location */
#define SSD1963_Reserveda8     0xA8 /* Reserved */
#define SSD1963_set_lcd_mode   0xB0 /* Set the LCD panel mode and resolution */
#define SSD1963_get_lcd_mode    0xB1 /* Get the current LCD panel mode, pad strength and resolution */
#define SSD1963_set_hori_period   0xB4 /* Set front porch */
#define SSD1963_get_hori_period   0xB5 /* Get current front porch settings */
#define SSD1963_set_vert_period   0xB6 /* Set the vertical blanking interval between last scan line and next LFRAME pulse */
#define SSD1963_get_vert_period   0xB7 /* Set the vertical blanking interval between last scan line and next LFRAME pulse */
#define SSD1963_set_gpio_conf    0xB8 /* Set the GPIO configuration. If the GPIO is not used for LCD, set the direction. Otherwise, they are toggled with LCD signals. */
#define SSD1963_get_gpio_conf    0xB9 /* Get the current GPIO configuration */
#define SSD1963_set_gpio_value    0xBA /* Set GPIO value for GPIO configured as output  */
#define SSD1963_get_gpio_status   0xBB /* Read current GPIO status. If the individual GPIO was configured as input, the value is the status of the corresponding pin. Otherwise, it is the programmed value. */
#define SSD1963_set_post_proc    0xBC /* Set the image post processor */
#define SSD1963_get_post_proc    0xBD /* Set the image post processor */
#define SSD1963_set_pwm_conf    0xBE /* Set the image post processor */
#define SSD1963_get_pwm_conf    0xBF /* Set the image post processor */
#define SSD1963_set_lcd_gen0    0xC0 /* Set the rise, fall, period and toggling properties of LCD signal generator 0 */
#define SSD1963_get_lcd_gen0    0xC1 /* Get the current settings of LCD signal generator 0 */
#define SSD1963_set_lcd_gen1    0xC2 /* Set the rise, fall, period and toggling properties of LCD signal generator 1 */
#define SSD1963_get_lcd_gen1    0xC3 /* Get the current settings of LCD signal generator 1 */
#define SSD1963_set_lcd_gen2    0xC4 /* Set the rise, fall, period and toggling properties of LCD signal generator 2 */
#define SSD1963_get_lcd_gen2    0xC5 /* Get the current settings of LCD signal generator 2 */
#define SSD1963_set_lcd_gen3    0xC6 /* Set the rise, fall, period and toggling properties of LCD signal generator 3 */
#define SSD1963_get_lcd_gen3    0xC7 /* Get the current settings of LCD signal generator 3  */
#define SSD1963_set_gpio0_rop    0xC8 /* Set the GPIO0 with respect to the LCD signal generators using ROP operation. No effect if the GPIO0 is configured as general GPIO. */
#define SSD1963_get_gpio0_rop    0xC9 /* Get the GPIO0 properties with respect to the LCD signal generators. */
#define SSD1963_set_gpio1_rop    0xCA /* Set the GPIO1 with respect to the LCD signal generators using ROP operation. No effect if the GPIO1 is configured as general GPIO. */
#define SSD1963_get_gpio1_rop    0xCB /* Get the GPIO1 properties with respect to the LCD signal generators.  */
#define SSD1963_set_gpio2_rop    0xCC /* Set the GPIO2 with respect to the LCD signal generators using ROP operation. No effect if the GPIO2 is configured as general GPIO. */
#define SSD1963_get_gpio2_rop    0xCD /* Get the GPIO2 properties with respect to the LCD signal generators. */
#define SSD1963_set_gpio3_rop    0xCE /* Set the GPIO3 with respect to the LCD signal generators using ROP operation. No effect if the GPIO3 is configured as general GPIO. */
#define SSD1963_get_gpio3_rop    0xCF /* Get the GPIO3 properties with respect to the LCD signal generators. */
#define SSD1963_set_dbc_conf    0xD0 /* Set the dynamic back light configuration 0xD1 get_dbc_conf Get the current dynamic back light configuration  */
#define SSD1963_set_dbc_th     0xD4 /* Set the threshold for each level of power saving */
#define SSD1963_get_dbc_th     0xD5 /* Get the threshold for each level of power saving */
#define SSD1963_set_pll     0xE0 /* Start the PLL. Before the start, the system was operated with the crystal oscillator or clock input */
#define SSD1963_set_pll_mn     0xE2 /* Set the PLL */
#define SSD1963_get_pll_mn     0xE3 /* Get the PLL settings */
#define SSD1963_get_pll_status    0xE4 /* Get the current PLL status */
#define SSD1963_set_deep_sleep    0xE5 /* Set deep sleep mode */
#define SSD1963_set_lshift_freq   0xE6 /* Set the LSHIFT (pixel clock) frequency */
#define SSD1963_get_lshift_freq   0xE7 /* Get current LSHIFT (pixel clock) frequency setting */
#define SSD1963_Reservede8     0xE8 /* Reserved */
#define SSD1963_Reservede9     0xE9 /* Reserved */
#define SSD1963_set_pixel_data_interface 0xF0 /* Set the pixel data format of the parallel host processor interface */
#define SSD1963_get_pixel_data_interface 0xF1 /* Get the current pixel data format settings */
#define SSD1963_Reservedff     0xFF /* Reserved */
/* Private variables ---------------------------------------------------------*/
void SSD1963_Fill(uint16_t color);
extern void SYS_Delay(uint32_t us);
void Delay_ms(uint32_t ms)
{
for(uint32_t i=0;i<ms;i++){SYS_Delay(1000);}
}
// Enable EBI function with 16-bit data width
void NANOEBI_Init(void)
{
EBI_TIMING_T sEBITiming;
UNLOCKREG();
/* Enable EBI clock  */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN;
/* EBI function enable */
EBI->EBICON |= EBI_EBICON_ExtEN;
EBI->EBICON |= EBI_EBICON_ExtBW16;
// Enable EBIAD15-0, GPIOPA9-8
GCR->PA_L_MFP = (GCR->PA_L_MFP & 0x0000000f) | 0x22222220; //PA7_MFP-PA1_MFP = EBI AD[6]-EBI AD[12]
GCR->PA_H_MFP = (GCR->PA_H_MFP & 0xf0000000) | 0x02222200; //PA14_MFP-PA12_MFP = EBI AD[15]-EBI AD[13] PA11_MFP-PA10_MFP = EBIWR-EBIRD PA9_MFP-PA8_MFP = PA9-PA8
GCR->PB_L_MFP = (GCR->PB_L_MFP & 0x00ffffff) | 0x20000000; //PB7_MFP-PB6_MFP = EBICS-PB6
GCR->PB_H_MFP = (GCR->PB_H_MFP & 0xff00ffff) | 0x00220000; //PB13_MFP-PB12_MFP = EBI AD[1]-EBI AD[0]
GCR->PC_L_MFP = (GCR->PC_L_MFP & 0x00ffffff) | 0x22000000; //PC15_MFP-PC14_MFP = EBI AD[3]-EBI AD[2]
GCR->PC_H_MFP = (GCR->PC_H_MFP & 0x00ffffff) | 0x22000000; //PC7_MFP-PC6_MFP = EBI AD[5]-EBI AD[4]
sEBITiming.eMCLKDIV = E_EBI_MCLKDIV_1;  //OK!!! 480NS 2.083MHZ
  sEBITiming.u8ExttALE=sEBITiming.u8ExtIR2R=sEBITiming.u8ExtIR2W = 0;
sEBITiming.u8ExtIW2X=sEBITiming.u8ExttAHD=sEBITiming.u8ExttACC = 0;
EBI_SetBusTiming(sEBITiming);
*(volatile uint16_t*)EBI_BASE_ADDR=0xFFFF;  //Set D0-D15 to HIGH
GPIO_Open(GPIOA, GPIO_PMD_PMD8_OUTPUT, GPIO_PMD_PMD8_MASK);
GPIO_Open(GPIOA, GPIO_PMD_PMD9_OUTPUT, GPIO_PMD_PMD9_MASK);
GPIO_Open(GPIOB, GPIO_PMD_PMD6_OUTPUT, GPIO_PMD_PMD6_MASK);
GPIO_SetBit(LCD_LEDA);      //PA9=High,BackLight ON; Low,BackLight OFF
GPIO_SetBit(LCD_DCMD);      //PB6=High,DATA mode; PB6=Low,COMMAND mode
GPIO_SetBit(LCD_RESET);      //PA8=Low,LCD Reset;PA8=High,LCD Working
SYS_Delay(LCD_RESET_DELAY);
GPIO_ClrBit(LCD_RESET);
SYS_Delay(LCD_RESET_DELAY);
GPIO_SetBit(LCD_RESET);
// LOCKREG();
}
static void EBI_test(void) {while(1) {*(volatile uint16_t*)EBI_BASE_ADDR=0x5555;*(volatile uint16_t*)EBI_BASE_ADDR=0xAAAA;}}
static __INLINE void SSD1963_WrPAR(uint8_t *data, uint8_t len){while(len--){EBI_WRITE_DATA16(0, *data++);}}
static __INLINE void SSD1963_WrCMD(uint8_t cmd, uint8_t *data, uint8_t len){GPIO_ClrBit(LCD_DCMD);EBI_WRITE_DATA16(0, cmd);GPIO_SetBit(LCD_DCMD);SSD1963_WrPAR(data, len);}
static __INLINE void SSD1963_WrRAM(uint16_t *data, uint32_t len){while(len--){EBI_WRITE_DATA16(0, *data++);}}
void SSD1963_Init(void)
{
uint32_t Parameter;
Parameter=0x04021d;   //PLL multiplier, set PLL clock to 120M N=0x36 for 6.5M, 0x23 for 10M crystal
SSD1963_WrCMD(SSD1963_set_pll_mn,(uint8_t*)&Parameter, 3);
Parameter=0x01;    //Enable PLL
SSD1963_WrCMD(SSD1963_set_pll,(uint8_t*)&Parameter, 1);
Delay_ms(1);
Parameter=0x03;    //Use PLL output as system clock
SSD1963_WrCMD(SSD1963_set_pll,(uint8_t*)&Parameter, 1);
Delay_ms(5);
SSD1963_WrCMD(SSD1963_soft_reset,(uint8_t*)&Parameter, 0); //software reset
Delay_ms(5);
Parameter=0x16D900;   //PLL setting for PCLK, depends on resolution
SSD1963_WrCMD(SSD1963_set_lshift_freq,(uint8_t*)&Parameter, 3);
Parameter=0x0020;   //LCD SPECIFICATION
SSD1963_WrCMD(SSD1963_set_lcd_mode,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HDP;  //Set HDP
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_VDP;  //Set VDP
SSD1963_WrPAR((uint8_t*)&Parameter, 3);
Parameter=SSD1963_HT;  //Set HT HSYNC
SSD1963_WrCMD(SSD1963_set_hori_period,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HPS;  //Set HPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_HPW;  //Set HPW
SSD1963_WrPAR((uint8_t*)&Parameter, 1);
Parameter=SSD1963_LPS;  //Set LPS
SSD1963_WrPAR((uint8_t*)&Parameter, 3);
Parameter=SSD1963_VT;  //Set VT VSYNC
SSD1963_WrCMD(SSD1963_set_vert_period,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_VPS;  //Set VPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_VPW;  //Set VPW
SSD1963_WrPAR((uint8_t*)&Parameter, 1);
Parameter=SSD1963_FPS;  //Set FPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=0x05;   //0x000F;    //GPIO[3:0] out 1
SSD1963_WrCMD(SSD1963_set_gpio_value,(uint8_t*)&Parameter, 1);
Parameter=0x0107;   //GPIO0 normal GPIO3=input, GPIO[2:0]=output
SSD1963_WrCMD(SSD1963_set_gpio_conf,(uint8_t*)&Parameter, 2);
Parameter=0x00;   //rotation
SSD1963_WrCMD(SSD1963_set_address_mode,(uint8_t*)&Parameter, 1);
Delay_ms(50);
Parameter=0x8006;  //set PWM for B/L
SSD1963_WrCMD(SSD1963_set_pwm_conf,(uint8_t*)&Parameter, 2);
Parameter=0x0000f001;
SSD1963_WrPAR((uint8_t*)&Parameter, 4);
Parameter=0x0d;   //设置动态背光控制配置
SSD1963_WrCMD(SSD1963_set_dbc_conf,(uint8_t*)&Parameter, 1);
   
Parameter=0x03;   //03:16-bit (565 format)
SSD1963_WrCMD(SSD1963_set_pixel_data_interface,(uint8_t*)&Parameter, 1);
// SSD1963_WrCMD(SSD1963_enter_invert_mode,(uint8_t*)&Parameter, 0); //进入图形颜色翻转模式
// Parameter=0x01808080; //处理机允许  饱和度值  亮度 对比度
// SSD1963_WrCMD(SSD1963_set_post_proc,(uint8_t*)&Parameter, 4);
SSD1963_Fill(BLACK);
SSD1963_WrCMD(SSD1963_set_display_on,(uint8_t*)&Parameter, 0); //display on
Delay_ms(5);
}
void SSD1963_Fill(uint16_t color)
{
uint32_t Parameter;
Parameter=0;
SSD1963_WrCMD(SSD1963_set_column_address,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HDP;
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=0;
SSD1963_WrCMD(SSD1963_set_page_address,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_VDP;
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
SSD1963_WrCMD(SSD1963_write_memory_start,(uint8_t*)&Parameter, 0);
for(uint32_t i=0;i<130560;i++){SSD1963_WrRAM(&color, 1);}
}
void LCD_test(void)
{
uint16_t i=0,color[]={BLACK, NAVY, DGREEN, DCYAN, MAROON, PURPLE, OLIVE, LGRAY, DGRAY, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE};
while(1)
{
  if(i++>(sizeof(color)/sizeof(color[0])))i=0;
  SSD1963_Fill(color);Delay_ms(5000);
}
}
void LCD_Configuration(void)
{
NANOEBI_Init();
SSD1963_Init();
printf("REVSH(0x1234)=0x%04x\n\r",__REVSH(0x1234));
LCD_test();
EBI_test();
}

//代码完毕
--缥缈九哥测试

最近编辑记录 缥缈九哥 (2020-05-09 19:59:24)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn