<commit_before>#include "lcd-driver.h"

#include "fonts.h"
#include "macros.h"

#ifdef M_PC
#include <stdio.h>
#endif
#ifdef M_AVR
#include <util/delay.h>
#endif

/**
 * Set RESET pin of the LCD module
 * @param[in] aOn The value to be set
 */
static void lcd_set_reset_pin (uint8_t aOn);
/**
 * Low-level request to write byte to the LCD module
 * @param[in] aCommand TRUE - write a command byte; FALSE - write a data byte
 * @param[in] aByte The byte to be written to the LCD module
 */
static void lcd_write_byte (uint8_t aCommand, uint8_t aByte);

/**
 * Low-level request to read byte in the LCD module
 * @param[in] aCommand TRUE - read a command byte; FALSE - read a data byte
 * @return The read byte
 */
static uint8_t lcd_read_byte (uint8_t aCommand);

/**
 * Read the status of the LCD module
 * @return The status byte of the LCD module
 */
static inline uint8_t lcd_read_status () { return lcd_read_byte (TRUE); }

/**
 * Turn ON/OFF display
 * @param[in] aOn FALSE - Turn ON; TRUE - Turn OFF
 */
static void lcd_display_turn_off (uint8_t aOff) { lcd_write_byte (TRUE, 0xAEU | (0x01U & aOff)); }
/**
 * Set the start line of the LCD module [0..31]
 * @param[in] aStartLine The start line to be set
 */
static void lcd_set_start_line (uint8_t aStartLine)
{ lcd_write_byte (TRUE, 0xC0U | (aStartLine & 0x1FU)); }
/**
 * Set the current page [0..3]
 * @param[in] aPage The page to be set
 */
static void lcd_set_page (uint8_t aPage) { lcd_write_byte (TRUE, 0xACU | (aPage & 0x03U)); }
/**
 * Set the current address
 * @param[in] aAddress The address to be set
 */
static void lcd_set_address (uint8_t aAddress) { lcd_write_byte (TRUE, aAddress & 0x7FU); }
/**
 * Set ADC flag
 * @param[in] aAdc 0 - forward scan, 1 - backward scan
 */
static void lcd_select_adc (uint8_t aAdc) { lcd_write_byte (TRUE, 0xA0U | (aAdc & 0x01U)); }
/**
 * Turn ON/OFF static (power-saving) mode
 * @param[in] aStatic TRUE - turn ON static mode, FALSE - turn OFF static mode
 */
static void lcd_set_static_mode (uint8_t aStatic)
{ lcd_write_byte (TRUE, 0xA4U | (aStatic & 0x01U)); }
/**
 * Select duty for the LCD module
 * @param[in] aDuty Should be used '0'
 */
static void lcd_select_duty (uint8_t aDuty) { lcd_write_byte (TRUE, 0xA8U | (aDuty & 0x01U)); }
/**
 * Start read-modify mode
 */
static void lcd_read_modify_start (void) { lcd_write_byte (TRUE, 0xE0U); }
/**
 * End read-modify mode
 */
static void lcd_read_modify_end (void) { lcd_write_byte (TRUE, 0xEEU); }
/**
 * Reset the LCD module
 */
static inline void lcd_reset (void) { lcd_write_byte (TRUE, 0xE2U); }


#define M_LCD_WIDTH (61)
#define M_LCD_HEIGHT (16)
#define M_LCD_RAM (M_LCD_WIDTH*M_LCD_HEIGHT/8)
#define M_LCD_BANK_LENGTH M_LCD_WIDTH

/**
 * These buffers correspond to the real RAM buffers in the LCD module
 */
static uint8_t TheDisplayBank1[M_LCD_BANK_LENGTH];
static uint8_t TheDisplayBank2[M_LCD_BANK_LENGTH];

void lcd_init (void) {
    /* после подачи напряжения питания удерживать вывод RES
       в состоянии логического “0” еще не менее 10 мкс */
    lcd_set_reset_pin (FALSE);
    _delay_us(50);

    /* подать перепад на вывод RES c логического “0” в логическую “1”,
       длительность фронта не более 10 мкс */
    lcd_set_reset_pin (TRUE);

    /* ожидать сброса бита RESET в байте состояния или выждать не менее 2 мс */
    _delay_ms(2);
    while (0x10U & lcd_read_status ()) {}

    /* подать команду снятия флага RMW (END) */
    lcd_read_modify_end ();

    /* подать команду включения обычного режима работы (Static Drive ON/OFF) */
    lcd_set_static_mode (FALSE);

    /* подать команду выбора мультиплекса (Duty Select) */
    lcd_select_duty (0);

    /* подать команду включения дисплея (Display ON/OFF) */
    lcd_display_turn_off (FALSE);

    lcd_reset ();
    lcd_select_adc (0);
    lcd_read_modify_start ();
    lcd_read_modify_end ();

    lcd_set_start_line (0);
    lcd_set_page (0);
    lcd_set_address (0);
}

void lcd_deinit (void) {
}

void lcd_flash (void) {
}

void lcd_clear (void) {
    uint8_t i;

    for (i = 0; i < M_LCD_BANK_LENGTH; i++) {
        TheDisplayBank1[i] = 0;
        TheDisplayBank2[i] = 0;
    }
}

void lcd_debug_show_buffer (void) {
    uint8_t y;
    uint16_t x;
    uint8_t bank;
<commit_msg>Implemented flashing to the LCD module<commit_after>#include "lcd-driver.h"

#include "fonts.h"
#include "macros.h"

#ifdef M_PC
#include <stdio.h>
#endif
#ifdef M_AVR
#include <util/delay.h>
#endif

/**
 * Set RESET pin of the LCD module
 * @param[in] aOn The value to be set
 */
static void lcd_set_reset_pin (uint8_t aOn);
/**
 * Low-level request to write byte to the LCD module
 * @param[in] aCommand TRUE - write a command byte; FALSE - write a data byte
 * @param[in] aByte The byte to be written to the LCD module
 */
static void lcd_write_byte (uint8_t aCommand, uint8_t aByte);

/**
 * Low-level request to read byte in the LCD module
 * @param[in] aCommand TRUE - read a command byte; FALSE - read a data byte
 * @return The read byte
 */
static uint8_t lcd_read_byte (uint8_t aCommand);

/**
 * Read the status of the LCD module
 * @return The status byte of the LCD module
 */
static inline uint8_t lcd_read_status () { return lcd_read_byte (TRUE); }

/**
 * Turn ON/OFF display
 * @param[in] aOn FALSE - Turn ON; TRUE - Turn OFF
 */
static void lcd_display_turn_off (uint8_t aOff) { lcd_write_byte (TRUE, 0xAEU | (0x01U & aOff)); }
/**
 * Set the start line of the LCD module [0..31]
 * @param[in] aStartLine The start line to be set
 */
static void lcd_set_start_line (uint8_t aStartLine)
{ lcd_write_byte (TRUE, 0xC0U | (aStartLine & 0x1FU)); }
/**
 * Set the current page [0..3]
 * @param[in] aPage The page to be set
 */
static void lcd_set_page (uint8_t aPage) { lcd_write_byte (TRUE, 0xACU | (aPage & 0x03U)); }
/**
 * Set the current address
 * @param[in] aAddress The address to be set
 */
static void lcd_set_address (uint8_t aAddress) { lcd_write_byte (TRUE, aAddress & 0x7FU); }
/**
 * Set ADC flag
 * @param[in] aAdc 0 - forward scan, 1 - backward scan
 */
static void lcd_select_adc (uint8_t aAdc) { lcd_write_byte (TRUE, 0xA0U | (aAdc & 0x01U)); }
/**
 * Turn ON/OFF static (power-saving) mode
 * @param[in] aStatic TRUE - turn ON static mode, FALSE - turn OFF static mode
 */
static void lcd_set_static_mode (uint8_t aStatic)
{ lcd_write_byte (TRUE, 0xA4U | (aStatic & 0x01U)); }
/**
 * Select duty for the LCD module
 * @param[in] aDuty Should be used '0'
 */
static void lcd_select_duty (uint8_t aDuty) { lcd_write_byte (TRUE, 0xA8U | (aDuty & 0x01U)); }
/**
 * Start read-modify mode
 */
static void lcd_read_modify_start (void) { lcd_write_byte (TRUE, 0xE0U); }
/**
 * End read-modify mode
 */
static void lcd_read_modify_end (void) { lcd_write_byte (TRUE, 0xEEU); }
/**
 * Reset the LCD module
 */
static inline void lcd_reset (void) { lcd_write_byte (TRUE, 0xE2U); }


#define M_LCD_WIDTH (61)
#define M_LCD_HEIGHT (16)
#define M_LCD_RAM (M_LCD_WIDTH*M_LCD_HEIGHT/8)
#define M_LCD_BANK_LENGTH M_LCD_WIDTH

/**
 * These buffers correspond to the real RAM buffers in the LCD module
 */
static uint8_t TheDisplayBank1[M_LCD_BANK_LENGTH];
static uint8_t TheDisplayBank2[M_LCD_BANK_LENGTH];

void lcd_init (void) {
    /* после подачи напряжения питания удерживать вывод RES
       в состоянии логического “0” еще не менее 10 мкс */
    lcd_set_reset_pin (FALSE);
    _delay_us(50);

    /* подать перепад на вывод RES c логического “0” в логическую “1”,
       длительность фронта не более 10 мкс */
    lcd_set_reset_pin (TRUE);

    /* ожидать сброса бита RESET в байте состояния или выждать не менее 2 мс */
    _delay_ms(2);
    while (0x10U & lcd_read_status ()) {}

    /* подать команду снятия флага RMW (END) */
    lcd_read_modify_end ();

    /* подать команду включения обычного режима работы (Static Drive ON/OFF) */
    lcd_set_static_mode (FALSE);

    /* подать команду выбора мультиплекса (Duty Select) */
    lcd_select_duty (0);

    /* подать команду включения дисплея (Display ON/OFF) */
    lcd_display_turn_off (FALSE);

    lcd_reset ();
    lcd_select_adc (0);
    lcd_read_modify_start ();
    lcd_read_modify_end ();

    lcd_set_start_line (0);
    lcd_set_page (0);
    lcd_set_address (0);
}

void lcd_deinit (void) {
}

void lcd_flash (void) {
    uint8_t i;

    /* send our local buffers to the LCD module, the first buffer first */
    lcd_set_page (0);
    lcd_set_address (0);
    for (i = 0; i < M_LCD_BANK_LENGTH; i++) {
        lcd_write_byte (FALSE, TheDisplayBank1[i]);
    }

    /* and the other one the second */
    lcd_set_page (1);
    lcd_set_address (0);
    for (i = 0; i < M_LCD_BANK_LENGTH; i++) {
        lcd_write_byte (FALSE, TheDisplayBank2[i]);
    }
}

void lcd_clear (void) {
    uint8_t i;

    for (i = 0; i < M_LCD_BANK_LENGTH; i++) {
        TheDisplayBank1[i] = 0;
        TheDisplayBank2[i] = 0;
    }
}

void lcd_debug_show_buffer (void) {
    uint8_t y;
    uint16_t x;
    uint8_t bank;

{'fraction_non_alphanumeric': 0.11355475763016158, 'fraction_numerical': 0.021880610412926393, 'mean_word_length': 3.58016443987667, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2528442', 'n_tokens_mistral': 3573, 'n_tokens_neox': 3533, 'n_words': 1013}