LCD driver (FrameBuffer) development on S3C2440 (Part 2)

Publisher:epsilon15Latest update time:2021-10-21 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. An interrupt function is implemented in the driver. Under what circumstances is the interrupt generated? There are two main interrupts: INT_FRSYN and INT_FICNT, namely frame synchronized interrupt and FIFO interrupt. When is the frame synchronized interrupt generated? Is a segment generated after each frame is displayed?


In the interrupt function:


static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)

{

 struct s3c2410fb_info *fbi = dev_id;

 void __iomem *irq_base = fbi->irq_base;

 unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND);


 if (lcdirq & S3C2410_LCDINT_FRSYNC) {

  if (fbi->palette_ready)

   s3c2410fb_write_palette(fbi);


  writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND);

  writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND);

 }


 return IRQ_HANDLED;

}


What is the purpose of writing these two pending registers? I did not see any corresponding introduction in the data sheet.


2. The framebuffer is implemented in FIFO mode and DMA mode. I still don't understand the content of DMA. I originally wanted to learn about DMA by learning fb.


3. The role of LCD palette: There are many colors, more than 256. But we selected 256 and put them in the palette, so that our screen displays only one of the limited 256 colors. The palette is equivalent to a small collection of colors.


4. The driver only implements a few functions, and I still don’t understand the specific implementation process of frambuffer.


5. What is the function of the function in static struct fb_ops my2440fb_ops?


6. After writing the framebuffer driver, how should it be tested? How should the application layer test function be written?


A simple test can be done with dd: dd if=/dev/zero of=/dev/fb0 bs=480 count=3200 clear screen


echo '1000' > /dev/tty0 is output directly to the screen. The driver of tty0 has already called fb0


 

Continued from: Detailed explanation of LCD driver (FrameBuffer) example development on S3C2440 (I)


4. FrameBuffer device driver example code:


①. Create the driver file: my2440_lcd.c, which is the most basic structure of the driver: the initialization and unloading part of the FrameBuffer driver and others, as follows:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#include

#include

#include

#include

#include

#include

#include

#include

#include



/*FrameBuffer device name*/

static char driver_name[] = "my2440_lcd";


/*Define a structure to maintain the variables used in each function in the driver program

  Don't look at the structure to define these members, you will understand when you see where each function uses them*/

struct my2440fb_var

{

    int lcd_irq_no; /*Save LCD interrupt number*/

    struct clk *lcd_clock; /*Save the LCD clock obtained from the platform clock queue*/

    struct resource *lcd_mem; /*LCD IO space*/

    void __iomem *lcd_base; /*LCD IO space is mapped to the virtual address*/

    struct device *dev;


    struct s3c2410fb_hw regs; /* represents 5 LCD configuration registers, s3c2410fb_hw is defined in mach-s3c2410/include/mach/fb.h*/


    /*Define an array to act as a palette.

    According to the data sheet, when the TFT screen color bit mode is 8BPP, the length of the palette (color table) is 256, and the starting address of the palette is 0x4D000400*/

    u32 palette_buffer[256]; 


    u32 pseudo_pal[16];   

    unsigned int palette_ready; /*Identifies whether the palette is ready*/

};


/*Used as a clear palette (color table)*/

#define PALETTE_BUFF_CLEAR (0x80000000)    


/*LCD platform driver structure, the platform driver structure is defined in platform_device.h, the structure member interface function is implemented in step ②*/

static struct platform_driver lcd_fb_driver = 

{

    .probe = lcd_fb_probe, /*FrameBuffer device detection*/

    .remove = __devexit_p(lcd_fb_remove), /*FrameBuffer device removal*/

    .suspend = lcd_fb_suspend, /*FrameBuffer device suspend*/

    .resume = lcd_fb_resume, /*FrameBuffer device resume*/

    .driver = 

    {

        /*Note that the name here must be consistent with the place where the platform device is defined in the system, so that the platform device can be associated with the driver of the platform device*/

        .name = "s3c2410-lcd",

        .owner = THIS_MODULE,

    },

};


static int __init lcd_init(void)

{

    /*In Linux, the frame buffer device is considered a platform device, so register the platform device here*/

    return platform_driver_register(&lcd_fb_driver);

}


static void __exit lcd_exit(void)

{

    /*Unregister platform device*/

    platform_driver_unregister(&lcd_fb_driver);

}


module_init(lcd_init);

module_exit(lcd_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("Huang Gang");

MODULE_DESCRIPTION("My2440 LCD FrameBuffer Driver");



②、Implementation of various interface functions of LCD platform equipment:

/*Implementation of LCD FrameBuffer device detection. Note that a __devinit macro is used here. The implementation of the lcd_fb_remove interface function is explained here*/

static int __devinit lcd_fb_probe(struct platform_device *pdev)

{

    int i;

    int ret;

    struct resource *res; /*Used to save LCD resources obtained from LCD platform device*/

    struct fb_info *fbinfo; /*fb_info structure corresponding to the FrameBuffer driver*/

    struct s3c2410fb_mach_info *mach_info; /*Save the platform device data obtained from the kernel*/

    struct my2440fb_var *fbvar; /*Driver global variable structure defined above*/

    struct s3c2410fb_display *display; /*LCD screen configuration information structure, the structure is defined in mach-s3c2410/include/mach/fb.h*/


    /*Get LCD hardware related information data. As mentioned earlier, the kernel uses the s3c24xx_fb_set_platdata function to save LCD hardware related information to

     The LCD platform data, so here we take it out from the platform data and use it in the driver*/

    mach_info = pdev->dev.platform_data;

    if (mach_info == NULL)

    {

        /*Judge whether the data acquisition is successful*/

        dev_err(&pdev->dev, "no platform data for lcdn");

        return -EINVAL;

    }


    /*Get the LCD configuration information structure data of the FrameBuffer platform device defined in the kernel*/

    display = mach_info->displays + mach_info->default_display;


    /* Allocate space for fb_info, the size is the memory of my2440fb_var structure, framebuffer_alloc is defined in fb.h and implemented in fbsysfs.c*/

    fbinfo = framebuffer_alloc(sizeof(struct my2440fb_var), &pdev->dev);

    if(!fbinfo)

    {

        dev_err(&pdev->dev, "framebuffer alloc of registers failedn");

        ret = -ENOMEM;

        goto err_noirq;

    }

    platform_set_drvdata(pdev, fbinfo);/*Reset the LCD platform device data to fbinfo so that it can be used in some subsequent functions*/


    /*The purpose here is actually to point the member par of fb_info (note that it is a void type pointer) to the private variable structure fbvar here,

     The purpose is to retrieve the member par of fb_info in other interface functions so that the private variables here can continue to be used*/

    fbvar = fbinfo->par;

    fbvar->dev = &pdev->dev;


    /*Get the LCD interrupt number from the system-defined LCD platform device resources, platform_get_irq is defined in platform_device.h*/

    fbvar->lcd_irq_no = platform_get_irq(pdev, 0);

    if(fbvar->lcd_irq_no < 0)

    {

        /*Judge whether the interrupt number is obtained successfully*/

        dev_err(&pdev->dev, "no lcd irq for platformn");

        return -ENOENT;

    }


    /*Get the IO port resources used by the LCD platform device. Note that the IORESOURCE_MEM flag is consistent with the LCD platform device definition*/

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    if(res == NULL)

    {

        /*Judge whether the resource acquisition is successful*/

        dev_err(&pdev->dev, "failed to get memory region resourcen");

        return -ENOENT;

    }


    /*Request the IO space occupied by the LCD IO port (note the difference between IO space and memory space), request_mem_region is defined in ioport.h*/

    fbvar->lcd_mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name);

    if(fbvar->lcd_mem == NULL)

    {

        /*Judge whether the application for IO space is successful*/

        dev_err(&pdev->dev, "failed to reserve memory regionn");

        return -ENOENT;

    }


    /*Map the IO space occupied by the LCD IO port to the virtual address of the memory. ioremap is defined in io.h

     Note: IO space can only be used after mapping, and the subsequent operations on virtual addresses are operations on IO space*/

    fbvar->lcd_base = ioremap(res->start, res->end - res->start + 1);

    if(fbvar->lcd_base == NULL)

    {

        /*Judge whether the mapping virtual address is successful*/

        dev_err(&pdev->dev, "ioremap() of registers failedn");

        ret = -EINVAL;

        goto err_nomem;

    }


    /*Get the LCD clock from the platform clock queue. Why do we need to get this clock here? From the timing diagram of the LCD screen, the delay of various control signals

     All are related to the LCD clock. Some system clock definitions are in arch/arm/plat-s3c24xx/s3c2410-clock.c*/

    fbvar->lcd_clock = clk_get(NULL, "lcd");

    if(!fbvar->lcd_clock)

    {

        /*Judge whether the clock acquisition is successful*/

        dev_err(&pdev->dev, "failed to find lcd clock sourcen");

        ret = -ENOENT;

        goto err_nomap;

    }

    /*After the clock is acquired, it must be enabled before it can be used. clk_enable is defined in arch/arm/plat-s3c/clock.c*/

    clk_enable(fbvar->lcd_clock);

[1] [2] [3] [4] [5]
Keywords:S3C2440 Reference address:LCD driver (FrameBuffer) development on S3C2440 (Part 2)

Previous article:Analysis of MMC/SD card driver on s3c2440 (I)
Next article:LCD driver (FrameBuffer) development on S3C2440 (Part 1)

Recommended ReadingLatest update time:2024-11-23 21:08

s3c2440 bare metal - code relocation (1. Introduction of relocation, why code relocation is needed)
1. Introduction of relocation (why code relocation is needed) We know that the CPU of s3c2440 starts fetching instructions from address 0 and executes them. When starting from nor, address 0 corresponds to nor. Nor can be read like memory, but cannot be written like memory. We can fetch instructions from nor and execu
[Microcontroller]
s3c2440 bare metal - code relocation (1. Introduction of relocation, why code relocation is needed)
s3c2440 bare metal - UART programming - 2 - UART programming implementation
UART Programming 1. Initialization Our 2440 supports 3 UART serial ports, taking uart0 as an example. Then we need to implement the following functions to complete the most basic functions of the serial port: (1) uart0_init() is used to initialize the serial port (2) p
[Microcontroller]
Application of s3c2440 watchdog timer
The main function of the watchdog timer is to reset the system after the program runs away due to interference, so as not to make the system die forever.   Its principle is not much different from that of a general timer, that is, you need to set a period of time first, and when this period of time is exceeded, it wi
[Microcontroller]
Design of home gateway based on S3C2440 (Part 1)
Abstract: With the improvement of social and economic level, people's requirements for the quality of home life are getting higher and higher. At the same time, with the continuous development of embedded technology and the popularization of mobile communication devices, the conditions for remote control of ordina
[Analog Electronics]
Design of home gateway based on S3C2440 (Part 1)
S3C2440 I2C Implementation
/*****************************************************  * Description: S3C2440 I2C implementation  *****************************************************/ 1:I2C Principle     The bus structure and signal type The I2C bus is a serial bus composed of data line SDA and clock SCL, which can send and receive data. Bidirec
[Microcontroller]
S3C2440 I2C Implementation
Wiring Analysis of S3C2440 and NAND FLASH (K9F1208)
1. SDRAM (HY57V561620F) connection analysis 1. S3C2440 has 27 address lines ADDR and 8 chip select signals ngcs0-ngcs7, corresponding to bank0-bank7. When accessing the address space of bankx, the ngcsx pin is low and the peripheral is selected. 2^27=128MByte, 8*128Mbyte = 1Gbyte, so the total addressing space of
[Microcontroller]
Wiring Analysis of S3C2440 and NAND FLASH (K9F1208)
Some unclear concepts in S3C2440
UART Universal Asynchronous Receiver/Transmitter, UART is the abbreviation of Universal Asynchronous Receiver/Transmitter. UART is a chip used to control computers and serial devices. SPI interface SPI (Serial Peripheral Interface) bus system is a synchronous serial peripheral interface that enables MCU to communica
[Microcontroller]
Design of TV transmitter control unit based on S3C2440
With the development of radio and television, the application of TV transmitter technology is becoming more and more extensive. In order to effectively ensure the quality of TV signals, the importance of TV transmitter monitoring is more prominent. This paper gives a design method for intelligent control of TV trans
[Microcontroller]
Design of TV transmitter control unit based on S3C2440
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号