Beispiel #1
0
void glcd_inverse_screen(unsigned char inverse) {
    if (inverse) {
        glcd_command(GLCD_CMD_DISPLAY_REVERSE);
    } else {
        glcd_command(GLCD_CMD_DISPLAY_NORMAL);
    }
}
Beispiel #2
0
void glcd_write()
{
	uint8_t bank;


	for (bank = 0; bank < PCD8544_MAX_BANKS; bank++) {
		/* Each bank is a single row 8 bits tall */
		uint8_t column;

		if (glcd_bbox_selected->y_min >= (bank+1)*8) {
			continue; /* Skip the entire bank */
		}

		if (glcd_bbox_selected->y_max < bank*8) {
			break;    /* No more banks need updating */
		}

		glcd_command(PCD8544_SET_Y_ADDRESS | bank);
		glcd_command(PCD8544_SET_X_ADDRESS | glcd_bbox_selected->x_min);

		for (column = glcd_bbox_selected->x_min; column <= glcd_bbox_selected->x_max; column++)
		{
			glcd_data( glcd_buffer_selected[PCD8544_MAX_COLS * bank + column] );
		}
	}

	glcd_reset_bbox();

}
Beispiel #3
0
void glcd_flip_screen(unsigned char flip) {
    if (flip) {
        glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);
        glcd_command(GLCD_CMD_VERTICAL_REVERSE);
        glcd_flipped = 0;
    } else {
        glcd_command(GLCD_CMD_HORIZONTAL_REVERSE);
        glcd_command(GLCD_CMD_VERTICAL_NORMAL);
        glcd_flipped = 1;
    }
}
Beispiel #4
0
void glcd_init(void)
{

#if defined(GLCD_CONTROLLER_PCD8544)
	/*
	 * Set up SPI (SSP)
	 * Note: Max allowed SPI clock is 4 MHz from datasheet.
	 */

	/* Select SSP/SPI port */
	SSP_IOConfig( CONTROLLER_SPI_PORT_NUMBER );

	/* Initialise SSP/SPI port */
	SSP_Init( CONTROLLER_SPI_PORT_NUMBER );

	/* Above functions take care of SPI pins */

	/* Set SS, DC and RST pins to output */
	CONTROLLER_SS_PORT->DIR  |= (1 << CONTROLLER_SS_PIN);
	CONTROLLER_DC_PORT->DIR  |= (1 << CONTROLLER_DC_PIN);
	CONTROLLER_RST_PORT->DIR |= (1 << CONTROLLER_RST_PIN);

	/* Deselect LCD */
	//GLCD_DESELECT();

	/* Reset the display */
	glcd_reset();

	/* Get into the EXTENDED mode! */
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);

	/* LCD bias select (4 is optimal?) */
	glcd_command(PCD8544_SET_BIAS | 0x2);

	/* Set VOP */
	glcd_command(PCD8544_SET_VOP | 50); // Experimentally determined

	/* Back to standard instructions */
	glcd_command(PCD8544_FUNCTION_SET);

	/* Normal mode */
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);

	glcd_select_screen(glcd_buffer,&glcd_bbox);

	glcd_clear();

#else /* GLCD_CONTROLLER_PCD8544 */
	#error "Controller not supported by LPC111x"
#endif

}
void glcd_init(void)
{

#if defined(GLCD_CONTROLLER_PCD8544)
	// Set up SPI (SSP)
	// Note: Max allowed SPI clock is 4 MHz from datasheet.

	// select SSP/SPI port
	SSP_IOConfig( PCD8544_SPI_PORT_NUMBER );

	// initialise SSP/SPI port
	SSP_Init( PCD8544_SPI_PORT_NUMBER );

	// above functions take care of SPI pins

	// set SS, DC and RST pins to output
	PCD8544_SS_PORT->DIR  |= (1 << PCD8544_SS_PIN);
	PCD8544_DC_PORT->DIR  |= (1 << PCD8544_DC_PIN);
	PCD8544_RST_PORT->DIR |= (1 << PCD8544_RST_PIN);

	// deselect LCD
	//GLCD_DESELECT();

	// reset the display
	glcd_reset();

	// get into the EXTENDED mode!
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);

	// LCD bias select (4 is optimal?)
	glcd_command(PCD8544_SET_BIAS | 0x2);

	// set VOP
	glcd_command(PCD8544_SET_VOP | 50); // Experimentally determined

	// back to standard instructions
	glcd_command(PCD8544_FUNCTION_SET);

	// normal mode
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);

	glcd_select_screen((uint8_t *)&glcd_buffer,&glcd_bbox);

	glcd_clear();

#else /* GLCD_CONTROLLER_PCD8544 */
	#error Controller not supported.
#endif

}
Beispiel #6
0
void glcd_set_contrast(uint8_t val) {
	/* Can set a 6-bit value (0 to 63)  */

	/* Must send this command byte before setting the contrast */
	glcd_command(0x81);
	
	/* Set the contrat value ("electronic volumne register") */
	if (val > 63) {
		glcd_command(63);
	} else {
		glcd_command(val);
	}
	return;
}
Beispiel #7
0
void glcd_power_down(void)
{
	/* First, fill RAM with zeroes to ensure minimum specified current consumption */
	glcd_clear();

	/* Power down */
	glcd_command(PCD8544_FUNCTION_SET|PCD8544_POWER_DOWN);
}
Beispiel #8
0
void glcd_blank() {
    // Reset the internal buffer
    for (int n = 1; n <= (SCREEN_WIDTH * SCREEN_HEIGHT / 8) - 1; n++) {
        glcd_buffer[n] = 0;
    }

    // Clear the actual screen
    for (int y = 0; y < 8; y++) {
        glcd_command(GLCD_CMD_SET_PAGE | y);

        // Reset column to 0 (the left side)
        glcd_command(GLCD_CMD_COLUMN_LOWER);
        glcd_command(GLCD_CMD_COLUMN_UPPER);

        // We iterate to 132 as the internal buffer is 65*132, not
        // 64*124.
        for (int x = 0; x < 132; x++) {
            glcd_data(0x00);
        }
    }
}
Beispiel #9
0
void glcd_refresh() {
    for (int y = 0; y < 8; y++) {

#ifdef ST7565_DIRTY_PAGES
        // Only copy this page if it is marked as "dirty"
        if (!(glcd_dirty_pages & (1 << y))) continue;
#endif

        glcd_command(GLCD_CMD_SET_PAGE | y);

        // Reset column to the left side.  The internal memory of the
        // screen is 132*64, we need to account for this if the display
        // is flipped.
        //
        // Some screens seem to map the internal memory to the screen
        // pixels differently, the ST7565_REVERSE define allows this to
        // be controlled if necessary.
#ifdef ST7565_REVERSE
        if (!glcd_flipped) {
#else
        if (glcd_flipped) {
#endif
            glcd_command(GLCD_CMD_COLUMN_LOWER | 4);
        } else {
            glcd_command(GLCD_CMD_COLUMN_LOWER);
        }
        glcd_command(GLCD_CMD_COLUMN_UPPER);

        for (int x = 0; x < 128; x++) {
            glcd_data(glcd_buffer[y * 128 + x]);
        }
    }

#ifdef ST7565_DIRTY_PAGES
    // All pages have now been updated, reset the indicator.
    glcd_dirty_pages = 0;
#endif
}

void glcd_init() {

    // Select the chip
    GLCD_CS1 = 0;

    GLCD_RESET = 0;

    // Datasheet says "wait for power to stabilise" but gives
    // no specific time!
    DelayMs(50);

    GLCD_RESET = 1;

    // Datasheet says max 1ms here
    //DelayMs(1);

    // Set LCD bias to 1/9th
    glcd_command(GLCD_CMD_BIAS_9);

    // Horizontal output direction (ADC segment driver selection)
    glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);

    // Vertical output direction (common output mode selection)
    glcd_command(GLCD_CMD_VERTICAL_REVERSE);

    // The screen is the "normal" way up
    glcd_flipped = 0;

    // Set internal resistor.  A suitable middle value is used as
    // the default.
    glcd_command(GLCD_CMD_RESISTOR | 0x3);

    // Power control setting (datasheet step 7)
    // Note: Skipping straight to 0x7 works with my hardware.
    //	glcd_command(GLCD_CMD_POWER_CONTROL | 0x4);
    //	DelayMs(50);
    //	glcd_command(GLCD_CMD_POWER_CONTROL | 0x6);
    //	DelayMs(50);
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x7);
    //	DelayMs(10);

    // Volume set (brightness control).  A middle value is used here
    // also.
    glcd_command(GLCD_CMD_VOLUME_MODE);
    glcd_command(31);

    // Reset start position to the top
    glcd_command(GLCD_CMD_DISPLAY_START);

    // Turn the display on
    glcd_command(GLCD_CMD_DISPLAY_ON);

    // Unselect the chip
    GLCD_CS1 = 1;
}
Beispiel #10
0
void glcd_init(void)
{

#if defined(GLCD_CONTROLLER_PCD8544)
	/*
	 * Set up SPI (SSP)
	 * Note: Max allowed SPI clock is 4 MHz from datasheet.
	 */

	/* Select SSP/SPI port */
	SSP_IOConfig( CONTROLLER_SPI_PORT_NUMBER );

	/* Initialise SSP/SPI port */
	SSP_Init( CONTROLLER_SPI_PORT_NUMBER );

	/* Above functions take care of SPI pins */

	/* Set SS, DC and RST pins to output */
	CONTROLLER_SS_PORT->DIR  |= (1 << CONTROLLER_SS_PIN);
	CONTROLLER_DC_PORT->DIR  |= (1 << CONTROLLER_DC_PIN);
	CONTROLLER_RST_PORT->DIR |= (1 << CONTROLLER_RST_PIN);

	/* Deselect LCD */
	GLCD_DESELECT();

	/* Reset the display */
	glcd_reset();

	/* Get into the EXTENDED mode! */
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);

	/* LCD bias select (4 is optimal?) */
	glcd_command(PCD8544_SET_BIAS | 0x2);

	/* Set VOP */
	glcd_command(PCD8544_SET_VOP | 50); // Experimentally determined

	/* Back to standard instructions */
	glcd_command(PCD8544_FUNCTION_SET);

	/* Normal mode */
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);

	glcd_select_screen(glcd_buffer,&glcd_bbox);

	glcd_clear();

#elif defined(GLCD_CONTROLLER_NT75451)
	/* Parallel interface controller used on NGX BlueBoards */
	
	/* Set 4x control lines pins as output */
	LPC_GPIO->DIR[CONTROLLER_LCD_EN_PORT] |= (1U<<CONTROLLER_LCD_EN_PIN);
	LPC_GPIO->DIR[CONTROLLER_LCD_RW_PORT] |= (1U<<CONTROLLER_LCD_RW_PIN);
	LPC_GPIO->DIR[CONTROLLER_LCD_RS_PORT] |= (1U<<CONTROLLER_LCD_RS_PIN);
	LPC_GPIO->DIR[CONTROLLER_LCD_CS_PORT] |= (1U<<CONTROLLER_LCD_CS_PIN);
	
	/* Don't worry about setting default RS/RW/CS/EN, they get set during use */
	
#ifdef CONTROLLER_LCD_DATA_PORT	
	/* Set data pins as output */
	LPC_GPIO->DIR[CONTROLLER_LCD_D0_PORT] |= GLCD_PARALLEL_MASK;
#else
	#error "Support of parallel data pins on different ports not supported."
#endif

	/* Initialise sequence - code by NGX Technologies */
	glcd_command(0xE2);  /*	S/W RESWT               */
	glcd_command(0xA0);  /*	ADC select              */
	glcd_command(0xC8);  /*	SHL Normal              */
	glcd_command(0xA3);  /*	LCD bias                */
	glcd_command(0x2F);  /*	Power control           */
	glcd_command(0x22);  /*	reg resistor select     */
	glcd_command(0x40);  /*	Initial display line 40 */
	glcd_command(0xA4);  /*	Normal display          */
	glcd_command(0xA6);  /*	Reverce display a7      */
	glcd_command(0x81);  /*	Ref vg select mode      */
	glcd_command(0x3f);  /*	Ref vg reg select       */
	glcd_command(0xB0);  /*	Set page address        */
	glcd_command(0x10);  /*	Set coloumn addr MSB    */
	glcd_command(0x00);  /*	Set coloumn addr LSB    */
	glcd_command(0xAF);  /*	Display ON              */

	/* Select default screen buffer */
	glcd_select_screen(glcd_buffer,&glcd_bbox);

	/* Clear the screen buffer */
	glcd_clear();
	
#else /* GLCD_CONTROLLER_PCD8544 */
	#error "Controller not supported by LPC111x"
#endif

}
Beispiel #11
0
void glcd_all_on(void)
{
	glcd_command(ST7565R_DISPLAY_ALL_ON);
}
Beispiel #12
0
void glcd_set_x_address(uint8_t x)
{
	glcd_command(PCD8544_SET_X_ADDRESS|(x & 0x7f));
}
Beispiel #13
0
void glcd_set_y_address(uint8_t y)
{
	glcd_command(PCD8544_SET_Y_ADDRESS|(y > 5 ? 5 : y));
}
Beispiel #14
0
void glcd_power_up(void)
{
	glcd_command(PCD8544_FUNCTION_SET);
}
Beispiel #15
0
void glcd_set_contrast(uint8_t val) {
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);
	glcd_command(PCD8544_SET_VOP | (val&0x7f));
	glcd_command(PCD8544_FUNCTION_SET);
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);
}
Beispiel #16
0
void glcd_init(void)
{

#if defined(GLCD_CONTROLLER_PCD8544)
	/* Initialisation for PCD8544 controller */

	/* Declare GPIO and SPI init structures */
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef  SPI_InitStructure;
  //NVIC_InitTypeDef NVIC_InitStructure;
	
	/* Initialise structures (which we will overide later) */
	GPIO_StructInit(&GPIO_InitStructure);
	SPI_StructInit(&SPI_InitStructure);
	
	/* Need to make start up the correct peripheral clocks */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	/* SS pin */
	GPIO_InitStructure.GPIO_Pin   = CONTROLLER_SPI_SS_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
	GPIO_Init(CONTROLLER_SPI_SS_PORT, &GPIO_InitStructure);
	
	/* DC pin */
	GPIO_InitStructure.GPIO_Pin = CONTROLLER_SPI_DC_PIN;
	GPIO_Init(CONTROLLER_SPI_DC_PORT, &GPIO_InitStructure);

	/* RESET pin */
	GPIO_InitStructure.GPIO_Pin = CONTROLLER_SPI_RST_PIN;
	GPIO_Init(CONTROLLER_SPI_RST_PORT, &GPIO_InitStructure);

	/* Make sure chip is de-selected by default */
	GLCD_DESELECT();

	/* Set up GPIO for SPI pins */
	GPIO_InitStructure.GPIO_Pin   = CONTROLLER_SPI_SCK_PIN | CONTROLLER_SPI_MISO_PIN | CONTROLLER_SPI_MOSI_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
	GPIO_Init(CONTROLLER_SPI_PORT, &GPIO_InitStructure);

	/* Configure alternate function mode for SPI pins */
	GPIO_PinAFConfig(GPIOA,CONTROLLER_SPI_SCK_PINSRC,GPIO_AF_0);
	GPIO_PinAFConfig(GPIOA,CONTROLLER_SPI_MOSI_PINSRC,GPIO_AF_0);
	GPIO_PinAFConfig(GPIOA,CONTROLLER_SPI_MISO_PINSRC,GPIO_AF_0);

	/* Initialise SPI */
	SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA              = SPI_CPHA_2Edge;
	SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; /* Set clock speed! */
	SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial     = 7;
	SPI_Init(CONTROLLER_SPI_NUMBER, &SPI_InitStructure);

	/* Enable SPI interupts */
	/*
	SPI_I2S_ITConfig(CONTROLLER_SPI_NUMBER, SPI_I2S_IT_TXE, ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
	NVIC_Init(&NVIC_InitStructure);
	*/
	
	/* Enable SPI */
	SPI_Cmd(CONTROLLER_SPI_NUMBER, ENABLE);

	/* Initialisation sequence of controller */
	glcd_reset();

	/* Get into the EXTENDED mode! */
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);

	/* LCD bias select (4 is optimal?) */
	glcd_command(PCD8544_SET_BIAS | 0x2);

	/* Set VOP */
	glcd_command(PCD8544_SET_VOP | 50); // Experimentally determined

	/* Back to standard instructions */
	glcd_command(PCD8544_FUNCTION_SET);

	/* Normal mode */
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);

	glcd_select_screen((uint8_t *)&glcd_buffer,&glcd_bbox);

	glcd_set_contrast(50);

	glcd_clear();


#else
	#error "Controller not supported by STM32F0xx"
#endif

}
Beispiel #17
0
void glcd_set_y_address(uint8_t y)
{
	glcd_command(ST7565R_PAGE_ADDRESS_SET | (0b00001111 & y));	
}
Beispiel #18
0
void glcd_init(void)
{
	
#if defined(GLCD_CONTROLLER_PCD8544)

	/* Set pin directions */
	
	/*
	 * Set up SPI for AVR8
	 * Note: AVR's SS pin must be set to output, regardless of whether we
	 * actually use it. This is a requirement of SPI mster mode.
	 */
	sbi(DDR(AVR_SS_PORT),AVR_SS_PIN);
	
	/*
	 *  Set MOSI, Master SS, SCK to output (otherwise SPI won't work)
	 *  Must be done even if native SS pin not used
	 */
	sbi(DDR(CONTROLLER_MOSI_PORT),CONTROLLER_MOSI_PIN);
	sbi(DDR(CONTROLLER_SS_PORT),CONTROLLER_SS_PIN);
	sbi(DDR(CONTROLLER_SCK_PORT),CONTROLLER_SCK_PIN);
		
	/* Set SS, DC and RST pins to output */
	sbi( DDR(CONTROLLER_SS_PORT), CONTROLLER_SS_PIN );
	sbi( DDR(CONTROLLER_DC_PORT), CONTROLLER_DC_PIN );
	sbi( DDR(CONTROLLER_RST_PORT), CONTROLLER_RST_PIN );
	
	/* Deselect LCD */
	GLCD_DESELECT();

	/*
	 * Max allowed SPI clock is 4 MHz from datasheet.
	 * Enable SPI, set master mode and clock rate to /4 (4MHz with F_CPU=8MHz)
	 */
	SPCR = (1<<SPE)|(1<<MSTR);
	SPSR = 0;
	
	glcd_reset();
	
	/* Get into the EXTENDED mode! */
	glcd_command(PCD8544_FUNCTION_SET | PCD8544_EXTENDED_INSTRUCTION);

	/* LCD bias select (4 is optimal?) */
	glcd_command(PCD8544_SET_BIAS | 0x2);
	
	/* Set VOP */
	glcd_command(PCD8544_SET_VOP | 50); // Experimentally determined
	
	/* Back to standard instructions */
	glcd_command(PCD8544_FUNCTION_SET); 
	
	/* Normal mode */
	glcd_command(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);

	/* Select screen buffer */
	glcd_select_screen(glcd_buffer,&glcd_bbox);
	
	/* Clear screen, we are now ready to go */
	glcd_clear();

#elif defined(GLCD_CONTROLLER_ST7565R)

	/* Set up GPIO directions */
	
	/*
	 * Set up SPI for AVR8
	 * Note: AVR's SS pin must be set to output, regardless of whether we
	 * actually use it. This is a requirement of SPI mster mode.
	 */
	sbi(DDR(AVR_SS_PORT),AVR_SS_PIN);
	
	/* Set SCK and MOSI as output */
	sbi(DDR(CONTROLLER_SCK_PORT),CONTROLLER_SCK_PIN);
	sbi(DDR(CONTROLLER_MOSI_PORT),CONTROLLER_MOSI_PIN);
	
	/*
	 * Set MISO as input with pullup. This needs to be set for
	 * SPI to work, even though we never use or read it.
	 */
	cbi(DDR(CONTROLLER_MISO_PORT),CONTROLLER_MISO_PIN); // B3 MISO as input
	sbi(CONTROLLER_MISO_PORT,CONTROLLER_MISO_PIN);
	
	/* Set pin to controller SS as output */
	sbi(DDR(CONTROLLER_SS_PORT),CONTROLLER_SS_PIN); // A5
	/* Set LCD A0 pin as output */
	sbi(DDR(CONTROLLER_A0_PORT),CONTROLLER_A0_PIN); // A6
		
	/* Init SS pin high (i.e LCD deselected) */
	sbi(CONTROLLER_SS_PORT,CONTROLLER_SS_PIN);

	/* Deselect LCD */
	GLCD_DESELECT();

	/* MSB first, double speed, SPI mode 0 */
	SPCR = (1<<SPE) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA);	
	sbi(SPSR,SPI2X);
	
	/* Enable interrupts */
	sei();
		
	delay_ms(30); // example in datasheet does this (20ms)

	glcd_command(ST7565R_RESET); // internal reset
	glcd_command(0xa2); // 1/9 bias
	glcd_command(0xa0); // ADC select, normal
	glcd_command(0xc8); // com output reverse
	glcd_command(0xa4); // display all points normal
	glcd_command(0x40); // display start line set
	glcd_command(0x25); // internal resistor ratio
	glcd_command(0x81); // electronic volume mode set
	//glcd_command(0x10); // electronic volume - datasheet's contrast example doesn't work
	glcd_command(45); // this works better
	glcd_command(0x2f); // power controller set
	glcd_command(0xaf); // display on
	
	glcd_all_on();
	
Beispiel #19
0
void glcd_normal(void)
{
	glcd_command(ST7565R_DISPLAY_NORMAL);
}
Beispiel #20
0
void glcd_refresh() {
    for (int y = 0; y < 8; y++) {

#ifdef ST7565_DIRTY_PAGES
        // Only copy this page if it is marked as "dirty"
        if (!(glcd_dirty_pages & (1 << y))) continue;
#endif

        glcd_command(GLCD_CMD_SET_PAGE | y);

        // Reset column to the left side. The internal memory of the
        // screen is 132*64, we need to account for this if the display
        // is flipped.
        //
        // Some screens seem to map the internal memory to the screen
        // pixels differently, the ST7565_REVERSE define allows this to
        // be controlled if necessary.
#ifdef ST7565_REVERSE
        if (!glcd_flipped) {
#else
        if (glcd_flipped) {
#endif
            glcd_command(GLCD_CMD_COLUMN_LOWER | 4);
        } else {
            glcd_command(GLCD_CMD_COLUMN_LOWER);
        }
        glcd_command(GLCD_CMD_COLUMN_UPPER);

        for (int x = 0; x < 128; x++) {
            glcd_data(glcd_buffer[y * 128 + x]);
        }
    }

#ifdef ST7565_DIRTY_PAGES
    // All pages have now been updated, reset the indicator.
    glcd_dirty_pages = 0;
#endif
}

void glcd_init() {

    // Select the chip
    GLCD_CS1 = 0;

    GLCD_RESET = 0;

    // Datasheet says "wait for power to stabilise" but gives
    // no specific time!
    DelayMs(50);

    GLCD_RESET = 1;
    // Datasheet says max 1ms here
    //DelayMs(1);

    // Set LCD bias to 1/9th
glcd_command(0b11100010); // Reset
glcd_command(0b10100010); // set the LCD bias to 1/9th
glcd_command(0x23); // Voltage Regulator internal Resisitor ratio set(the internal resistor divider set to 3 (from 0..7))
glcd_command(0x2F); // Power Control Set( power control, all internal blocks ON )
glcd_command(0b00000011); // Electronic volume Mode set ???
glcd_command(0x40); // go back to the top left of the display
glcd_command(0x81); // Electronic volume Mode set
glcd_command(0b11111000); // Booster ratio Select Mode Set
glcd_command(0b00000000); // Booster ratio register set ???
glcd_command(0b10100000); // ADC Select( 0xa0:Normal, 0xa1:Reverse )
glcd_command(0b11001000); // Common output Mode Set
glcd_command(0b10101111); // Display ON
glcd_command(0b10100110); // Display Normal/Reverse(Permet d'inverser Blanc/noir)
glcd_command(0xA4); // Display all points (0xa4:Normal display mode, 0xa5:display all points)

    // Unselect the chip
    GLCD_CS1 = 1;
}