PIC8-Bit Trainer - Module LCD - EA-DOGM204-A - SSD1803A - 4x20.

0.Contents

PIC18F Trainer : PIC18F2620 @8MHz Internal oscillator.

1.String & Custom Patterns - 8-Bit No Busy Flag, PWM Controlled Backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DOGM204-A - 4x20 - SSD1803A - 8-Bit No Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DOGM204-A - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 3V3.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> MCU.RB0.
// MODULE.08 -> MCU.RB1.
// MODULE.09 -> MCU.RB2.
// MODULE.10 -> MCU.RB3.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> MCU.RC2.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Open.
// JP4 - BCKL Open.

// Expansion Module.
// IM1 - Close //-SPI.
// IM2 - Close //.

// Definitions.
// SSD1803A Command Port & Data Port.
#define SSD1803A_DATA													LATB
#define SSD1803A_DATA_TRIS												TRISB
#define SSD1803A_RS_TRIS												TRISAbits.TRISA0
#define SSD1803A_E_TRIS													TRISAbits.TRISA1
#define SSD1803A_RS														LATAbits.LATA0
#define SSD1803A_E														LATAbits.LATA1
// DOGM204A Backlight.
#define BACKLIGHT														CCPR1L
#define DOGM204A_BACKLIGHT												LATCbits.LATC2
#define DOGM204A_BACKLIGHT_TRIS											TRISCbits.TRISC2
// Extension Register RE = 0 & IS = 0.
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_LEFT							0x10
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_RIGHT							0x14
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_LEFT							0x18
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_RIGHT							0x1C
#define SSD1803A_FS0_SET_CGRAM_ADDRESS									0x40
// Extension Register RE = 0 & IS = 1.
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F00						0x10
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F01						0x11
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F00						0x12
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F01						0x13
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F00						0x14
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F01						0x15
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F00						0x16
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F01						0x17
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F00						0x18
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F01						0x19
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F00						0x1A
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F01						0x1B
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F00						0x1C
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F01						0x1D
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00						0x1E
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F01						0x1F
#define SSD1803A_FS1_SET_SEGRAM_ADDRESS									0x40
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_0							0x50
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_1							0x51
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_2							0x52
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_3							0x53
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_0							0x54
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_1							0x55
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_2							0x56
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3							0x57
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_0 							0x58
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_1							0x59
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_2							0x5A
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_3							0x5B
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_0							0x5C
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_1							0x5D
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_2							0x5E
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_3							0x5F
#define SSD1803A_FS1_FOLLOWER_CONTROL_OFF								0x60
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_0							0x68
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_1							0x69
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_2							0x6A
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_3							0x6B
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_4							0x6C
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_5							0x6D
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6							0x6E
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_7							0x6F
#define SSD1803A_FS1_CONTRAST_LSB_0										0x70
#define SSD1803A_FS1_CONTRAST_LSB_1										0x71
#define SSD1803A_FS1_CONTRAST_LSB_2										0x72
#define SSD1803A_FS1_CONTRAST_LSB_3										0x73
#define SSD1803A_FS1_CONTRAST_LSB_4										0x74
#define SSD1803A_FS1_CONTRAST_LSB_5										0x75
#define SSD1803A_FS1_CONTRAST_LSB_6										0x76
#define SSD1803A_FS1_CONTRAST_LSB_7										0x77
#define SSD1803A_FS1_CONTRAST_LSB_8										0x78
#define SSD1803A_FS1_CONTRAST_LSB_9										0x79
#define SSD1803A_FS1_CONTRAST_LSB_10									0x7A
#define SSD1803A_FS1_CONTRAST_LSB_11									0x7B
#define SSD1803A_FS1_CONTRAST_LSB_12									0x7C
#define SSD1803A_FS1_CONTRAST_LSB_13									0x7D
#define SSD1803A_FS1_CONTRAST_LSB_14									0x7E
#define SSD1803A_FS1_CONTRAST_LSB_15									0x7F
// Extension Register RE = 1 & IS = 0.
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH0					0x10
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH1					0x11
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0					0x12
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH1					0x13
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH0					0x14
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH1					0x15
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH0					0x16
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH1					0x17
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH0					0x18
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH1					0x19
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH0					0x1A
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH1					0x1B
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH0					0x1C
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH1					0x1D
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH0					0x1E
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH1					0x1F
// Extension Register RE = 1 & IS = 1.
#define SSD1803A_FS3_NO_SHIFT											0x10
#define SSD1803A_FS3_SHIFT_LINE_1										0x11
#define SSD1803A_FS3_SHIFT_LINE_2										0x12
#define SSD1803A_FS3_SHIFT_LINE_12										0x13
#define SSD1803A_FS3_SHIFT_LINE_3										0x14
#define SSD1803A_FS3_SHIFT_LINE_13										0x15
#define SSD1803A_FS3_SHIFT_LINE_23										0x16
#define SSD1803A_FS3_SHIFT_LINE_123										0x17
#define SSD1803A_FS3_SHIFT_LINE_4										0x18
#define SSD1803A_FS3_SHIFT_LINE_14										0x19
#define SSD1803A_FS3_SHIFT_LINE_24										0x1A
#define SSD1803A_FS3_SHIFT_LINE_124										0x1B
#define SSD1803A_FS3_SHIFT_LINE_34										0x1C
#define SSD1803A_FS3_SHIFT_LINE_134										0x1D
#define SSD1803A_FS3_SHIFT_LINE_234										0x1E
#define SSD1803A_FS3_SHIFT_LINE_1234									0x1F
#define SSD1803A_FS3_NO_SCROLL										 	0x10
#define SSD1803A_FS3_SCROLL_LINE_1										0x11
#define SSD1803A_FS3_SCROLL_LINE_2										0x12
#define SSD1803A_FS3_SCROLL_LINE_12										0x13
#define SSD1803A_FS3_SCROLL_LINE_3										0x14
#define SSD1803A_FS3_SCROLL_LINE_13										0x15
#define SSD1803A_FS3_SCROLL_LINE_23										0x16
#define SSD1803A_FS3_SCROLL_LINE_123									0x17
#define SSD1803A_FS3_SCROLL_LINE_4										0x18
#define SSD1803A_FS3_SCROLL_LINE_14										0x19
#define SSD1803A_FS3_SCROLL_LINE_24										0x1A
#define SSD1803A_FS3_SCROLL_LINE_124									0x1B
#define SSD1803A_FS3_SCROLL_LINE_34										0x1C
#define SSD1803A_FS3_SCROLL_LINE_134									0x1D
#define SSD1803A_FS3_SCROLL_LINE_234									0x1E
#define SSD1803A_FS3_SCROLL_LINE_1234									0x1F
// Extension Register RE = 0 & IS = x.
#define SSD1803A_FS01_RETURN_HOME										0x02
#define SSD1803A_FS01_DISPLAY_OFF										0x08
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF								0x0C
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_NOBLINK						0x0E
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_BLINK						0x0F
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS0			0x20
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS1			0x21
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS0			0x24
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS1			0x25
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0			0x28
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1			0x29
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS0			0x2C
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS1			0x2D
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS0			0x30
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS1			0x31
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS0			0x34
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS1			0x35
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0			0x38
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1			0x39
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS0			0x3C
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS1			0x3D
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE						0x80
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE						0xA0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE						0xC0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE						0xE0
// Extension Register RE = 1 & IS = x.
#define SSD1803A_FS23_POWER_DOWN_OFF									0x02
#define SSD1803A_FS23_POWER_DOWN_ON										0x03
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW_MIRROR					0x04
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW							0x05
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW						0x06
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW_MIRROR					0x07
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_12LINE	0x08
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE	0x09
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_12LINE		0x0A
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_34LINE		0x0B
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_12LINE	0x0C
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_34LINE	0x0D
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_12LINE		0x0E
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_34LINE		0x0F
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_NORMAL			0x22
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_REVERSE			0x23
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_NORMAL			0x26
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_REVERSE			0x27
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL			0x2A
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_REVERSE			0x2B
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_NORMAL			0x2E
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_REVERSE			0x2F
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL			0x32
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE			0x33
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_NORMAL			0x36
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_REVERSE			0x37
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL			0x3A
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_REVERSE			0x3B
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_NORMAL			0x3E
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_REVERSE			0x3F
#define SSD1803A_FS23_SCROLL_QUANTITY									0x80
#define SSD1803A_FS23_TEMPERATURE_COEFFICIENT							0x76
#define SSD1803A_FS23_ROM_SELECTION_COMMAND								0x72
// Extension Register RE = x & IS = x.
#define SSD1803A_FS0123_CLEAR_DISPLAY									0x01
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT				0x04
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_SHIFT				0x05
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT				0x06
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_SHIFT				0x07
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_005					0x02
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_010					0x04
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_015					0x06
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_020					0x07
#define SSD1803A_FS0123_ROM_SELECTION_A									0x00
#define SSD1803A_FS0123_ROM_SELECTION_B									0x04
#define SSD1803A_FS0123_ROM_SELECTION_C									0x08

// Function prototypes.
void ssd1803a_displayClear(void);
void ssd1803a_initialize(void);
void ssd1803a_romSelection(uint8_t u8Data);
void ssd1803a_writeData(char cData);
void ssd1803a_writeInstruction(char cData);
void ssd1803a_writeString(const char * cData);
void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix I/O";
const char string1[] = "www.tronix.io";
const char string2[] = "Custom patterns";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	SSD1803A_RS = 0;
	SSD1803A_E = 0;
	SSD1803A_RS_TRIS = 0;
	SSD1803A_E_TRIS = 0;
	// Outputs for LCD data.
	SSD1803A_DATA = 0x00;
	SSD1803A_DATA_TRIS = 0x00;
	// Output for Backlight.
	DOGM204A_BACKLIGHT = 0;
	DOGM204A_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer 2 - 1kHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

	ssd1803a_initialize();
	ssd1803a_romSelection(SSD1803A_FS0123_ROM_SELECTION_A);

	// Write 5x8 Dots Custom Patterns in SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS0_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			ssd1803a_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	ssd1803a_writeStringSetCursor(string0, SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE + 0x05);
	ssd1803a_writeStringSetCursor(string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE + 0x03);
	ssd1803a_writeStringSetCursor(string2, SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE + 0x02);

	// Display Custom Patterns from SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x05);
	ssd1803a_writeData(0x00);
	ssd1803a_writeData(0x01);
	ssd1803a_writeData(0x02);
	ssd1803a_writeData(0x03);
	ssd1803a_writeData(0x04);
	ssd1803a_writeString(" - ");

	uint8_t backlight;
	while(1){
		for(backlight=0; backlight<128; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(50);
		}
		for(pattern=0; pattern<5; pattern++){
			ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x0d);
			ssd1803a_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void ssd1803a_displayClear(void)
{
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_initialize(void)
{
	__delay_ms(10);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE);
	ssd1803a_writeInstruction(SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW);
	ssd1803a_writeInstruction(SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0);
	ssd1803a_writeInstruction(SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1);
	ssd1803a_writeInstruction(SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6);
	ssd1803a_writeInstruction(SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3);
	ssd1803a_writeInstruction(SSD1803A_FS1_CONTRAST_LSB_10);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
	ssd1803a_writeInstruction(SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF);
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_romSelection(uint8_t u8Data)
{
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_ROM_SELECTION_COMMAND);
	ssd1803a_writeData(u8Data);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
}

void ssd1803a_writeData(char cData)
{
	SSD1803A_RS = 1;
	SSD1803A_E = 1;
	SSD1803A_DATA = cData;
	SSD1803A_E = 0;
	__delay_us(10);
}

void ssd1803a_writeInstruction(char cData)
{
	SSD1803A_RS = 0;
	SSD1803A_E = 1;
	SSD1803A_DATA = cData;
	SSD1803A_E = 0;
	__delay_us(30);
}

void ssd1803a_writeString(const char * cData)
{
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	ssd1803a_writeInstruction(u8Data);
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

2.String & Custom Patterns - 4-Bit Low Nibble No Busy Flag, PWM Controlled Backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DOGM204-A - 4x20 - SSD1803A - 4-Bit Low Nibble No Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DOGM204-A - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 3V3.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> VDD - 3V3.
// MODULE.08 -> VDD - 3V3.
// MODULE.09 -> VDD - 3V3.
// MODULE.10 -> VDD - 3V3.
// MODULE.11 -> MCU.RB0.
// MODULE.12 -> MCU.RB1.
// MODULE.13 -> MCU.RB2.
// MODULE.14 -> MCU.RB3.
// MODULE.15 -> MCU.RC2.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Open.
// JP4 - BCKL Open.

// Expansion Module.
// IM1 - Close //-SPI.
// IM2 - Close //.

// Definitions.
// SSD1803A Command Port & Data Port.
#define SSD1803A_DATA													LATB
#define SSD1803A_DATA_TRIS												TRISB
#define SSD1803A_RS_TRIS												TRISAbits.TRISA0
#define SSD1803A_E_TRIS													TRISAbits.TRISA1
#define SSD1803A_RS														LATAbits.LATA0
#define SSD1803A_E														LATAbits.LATA1
// DOGM204A Backlight.
#define BACKLIGHT														CCPR1L
#define DOGM204A_BACKLIGHT												LATCbits.LATC2
#define DOGM204A_BACKLIGHT_TRIS											TRISCbits.TRISC2
// Extension Register RE = 0 & IS = 0.
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_LEFT							0x10
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_RIGHT							0x14
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_LEFT							0x18
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_RIGHT							0x1C
#define SSD1803A_FS0_SET_CGRAM_ADDRESS									0x40
// Extension Register RE = 0 & IS = 1.
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F00						0x10
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F01						0x11
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F00						0x12
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F01						0x13
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F00						0x14
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F01						0x15
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F00						0x16
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F01						0x17
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F00						0x18
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F01						0x19
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F00						0x1A
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F01						0x1B
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F00						0x1C
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F01						0x1D
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00						0x1E
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F01						0x1F
#define SSD1803A_FS1_SET_SEGRAM_ADDRESS									0x40
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_0							0x50
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_1							0x51
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_2							0x52
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_3							0x53
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_0							0x54
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_1							0x55
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_2							0x56
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3							0x57
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_0 							0x58
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_1							0x59
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_2							0x5A
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_3							0x5B
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_0							0x5C
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_1							0x5D
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_2							0x5E
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_3							0x5F
#define SSD1803A_FS1_FOLLOWER_CONTROL_OFF								0x60
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_0							0x68
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_1							0x69
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_2							0x6A
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_3							0x6B
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_4							0x6C
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_5							0x6D
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6							0x6E
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_7							0x6F
#define SSD1803A_FS1_CONTRAST_LSB_0										0x70
#define SSD1803A_FS1_CONTRAST_LSB_1										0x71
#define SSD1803A_FS1_CONTRAST_LSB_2										0x72
#define SSD1803A_FS1_CONTRAST_LSB_3										0x73
#define SSD1803A_FS1_CONTRAST_LSB_4										0x74
#define SSD1803A_FS1_CONTRAST_LSB_5										0x75
#define SSD1803A_FS1_CONTRAST_LSB_6										0x76
#define SSD1803A_FS1_CONTRAST_LSB_7										0x77
#define SSD1803A_FS1_CONTRAST_LSB_8										0x78
#define SSD1803A_FS1_CONTRAST_LSB_9										0x79
#define SSD1803A_FS1_CONTRAST_LSB_10									0x7A
#define SSD1803A_FS1_CONTRAST_LSB_11									0x7B
#define SSD1803A_FS1_CONTRAST_LSB_12									0x7C
#define SSD1803A_FS1_CONTRAST_LSB_13									0x7D
#define SSD1803A_FS1_CONTRAST_LSB_14									0x7E
#define SSD1803A_FS1_CONTRAST_LSB_15									0x7F
// Extension Register RE = 1 & IS = 0.
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH0					0x10
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH1					0x11
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0					0x12
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH1					0x13
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH0					0x14
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH1					0x15
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH0					0x16
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH1					0x17
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH0					0x18
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH1					0x19
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH0					0x1A
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH1					0x1B
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH0					0x1C
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH1					0x1D
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH0					0x1E
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH1					0x1F
// Extension Register RE = 1 & IS = 1.
#define SSD1803A_FS3_NO_SHIFT											0x10
#define SSD1803A_FS3_SHIFT_LINE_1										0x11
#define SSD1803A_FS3_SHIFT_LINE_2										0x12
#define SSD1803A_FS3_SHIFT_LINE_12										0x13
#define SSD1803A_FS3_SHIFT_LINE_3										0x14
#define SSD1803A_FS3_SHIFT_LINE_13										0x15
#define SSD1803A_FS3_SHIFT_LINE_23										0x16
#define SSD1803A_FS3_SHIFT_LINE_123										0x17
#define SSD1803A_FS3_SHIFT_LINE_4										0x18
#define SSD1803A_FS3_SHIFT_LINE_14										0x19
#define SSD1803A_FS3_SHIFT_LINE_24										0x1A
#define SSD1803A_FS3_SHIFT_LINE_124										0x1B
#define SSD1803A_FS3_SHIFT_LINE_34										0x1C
#define SSD1803A_FS3_SHIFT_LINE_134										0x1D
#define SSD1803A_FS3_SHIFT_LINE_234										0x1E
#define SSD1803A_FS3_SHIFT_LINE_1234									0x1F
#define SSD1803A_FS3_NO_SCROLL										 	0x10
#define SSD1803A_FS3_SCROLL_LINE_1										0x11
#define SSD1803A_FS3_SCROLL_LINE_2										0x12
#define SSD1803A_FS3_SCROLL_LINE_12										0x13
#define SSD1803A_FS3_SCROLL_LINE_3										0x14
#define SSD1803A_FS3_SCROLL_LINE_13										0x15
#define SSD1803A_FS3_SCROLL_LINE_23										0x16
#define SSD1803A_FS3_SCROLL_LINE_123									0x17
#define SSD1803A_FS3_SCROLL_LINE_4										0x18
#define SSD1803A_FS3_SCROLL_LINE_14										0x19
#define SSD1803A_FS3_SCROLL_LINE_24										0x1A
#define SSD1803A_FS3_SCROLL_LINE_124									0x1B
#define SSD1803A_FS3_SCROLL_LINE_34										0x1C
#define SSD1803A_FS3_SCROLL_LINE_134									0x1D
#define SSD1803A_FS3_SCROLL_LINE_234									0x1E
#define SSD1803A_FS3_SCROLL_LINE_1234									0x1F
// Extension Register RE = 0 & IS = x.
#define SSD1803A_FS01_RETURN_HOME										0x02
#define SSD1803A_FS01_DISPLAY_OFF										0x08
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF								0x0C
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_NOBLINK						0x0E
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_BLINK						0x0F
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS0			0x20
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS1			0x21
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS0			0x24
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS1			0x25
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0			0x28
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1			0x29
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS0			0x2C
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS1			0x2D
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS0			0x30
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS1			0x31
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS0			0x34
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS1			0x35
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0			0x38
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1			0x39
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS0			0x3C
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS1			0x3D
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE						0x80
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE						0xA0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE						0xC0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE						0xE0
// Extension Register RE = 1 & IS = x.
#define SSD1803A_FS23_POWER_DOWN_OFF									0x02
#define SSD1803A_FS23_POWER_DOWN_ON										0x03
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW_MIRROR					0x04
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW							0x05
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW						0x06
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW_MIRROR					0x07
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_12LINE	0x08
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE	0x09
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_12LINE		0x0A
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_34LINE		0x0B
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_12LINE	0x0C
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_34LINE	0x0D
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_12LINE		0x0E
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_34LINE		0x0F
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_NORMAL			0x22
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_REVERSE			0x23
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_NORMAL			0x26
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_REVERSE			0x27
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL			0x2A
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_REVERSE			0x2B
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_NORMAL			0x2E
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_REVERSE			0x2F
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL			0x32
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE			0x33
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_NORMAL			0x36
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_REVERSE			0x37
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL			0x3A
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_REVERSE			0x3B
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_NORMAL			0x3E
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_REVERSE			0x3F
#define SSD1803A_FS23_SCROLL_QUANTITY									0x80
#define SSD1803A_FS23_TEMPERATURE_COEFFICIENT							0x76
#define SSD1803A_FS23_ROM_SELECTION_COMMAND								0x72
// Extension Register RE = x & IS = x.
#define SSD1803A_FS0123_CLEAR_DISPLAY									0x01
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT				0x04
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_SHIFT				0x05
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT				0x06
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_SHIFT				0x07
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_005					0x02
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_010					0x04
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_015					0x06
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_020					0x07
#define SSD1803A_FS0123_ROM_SELECTION_A									0x00
#define SSD1803A_FS0123_ROM_SELECTION_B									0x04
#define SSD1803A_FS0123_ROM_SELECTION_C									0x08

// Function prototypes.
void ssd1803a_displayClear(void);
void ssd1803a_initialize(void);
void ssd1803a_romSelection(uint8_t u8Data);
void ssd1803a_writeData(char cData);
void ssd1803a_writeInstruction(char cData);
void ssd1803a_writeString(const char * cData);
void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix I/O";
const char string1[] = "www.tronix.io";
const char string2[] = "Custom patterns";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
void mcu_initialize(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	SSD1803A_RS = 0;
	SSD1803A_E = 0;
	SSD1803A_RS_TRIS = 0;
	SSD1803A_E_TRIS = 0;
	// Outputs for LCD data.
	SSD1803A_DATA = 0x00;
	SSD1803A_DATA_TRIS = 0x00;
	// Output for Backlight.
	DOGM204A_BACKLIGHT = 0;
	DOGM204A_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer 2 - 1kHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

	ssd1803a_initialize();
	ssd1803a_romSelection(SSD1803A_FS0123_ROM_SELECTION_A);

	// Write 5x8 Dots Custom Patterns in SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS0_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			ssd1803a_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	ssd1803a_writeStringSetCursor(string0, SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE + 0x05);
	ssd1803a_writeStringSetCursor(string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE + 0x03);
	ssd1803a_writeStringSetCursor(string2, SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE + 0x02);

	// Display Custom Patterns from SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x05);
	ssd1803a_writeData(0x00);
	ssd1803a_writeData(0x01);
	ssd1803a_writeData(0x02);
	ssd1803a_writeData(0x03);
	ssd1803a_writeData(0x04);
	ssd1803a_writeString(" - ");
	
	uint8_t backlight;
	while(1){
		for(backlight=0; backlight<128; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(50);
		}
		for(pattern=0; pattern<5; pattern++){
			ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x0d);
			ssd1803a_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void ssd1803a_displayClear(void)
{
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_initialize(void)
{
	__delay_ms(10);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE);
	ssd1803a_writeInstruction(SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW);
	ssd1803a_writeInstruction(SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0);
	ssd1803a_writeInstruction(SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1);
	ssd1803a_writeInstruction(SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6);
	ssd1803a_writeInstruction(SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3);
	ssd1803a_writeInstruction(SSD1803A_FS1_CONTRAST_LSB_10);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0);
	ssd1803a_writeInstruction(SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF);
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_romSelection(uint8_t u8Data)
{
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_ROM_SELECTION_COMMAND);
	ssd1803a_writeData(u8Data);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0);
}

void ssd1803a_writeData(char cData)
{
	SSD1803A_RS = 1;
	SSD1803A_DATA &= 0xf0;
	SSD1803A_E = 1;
	SSD1803A_DATA |= ((cData>>4) & 0x0f);
	SSD1803A_E = 0;
	SSD1803A_DATA &= 0xf0;
	SSD1803A_E = 1;
	SSD1803A_DATA |= (cData & 0x0f);
	SSD1803A_E = 0;
	__delay_us(10);
}

void ssd1803a_writeInstruction(char cData)
{
	SSD1803A_RS = 0;
	SSD1803A_DATA &= 0xf0;
	SSD1803A_E = 1;
	SSD1803A_DATA |= ((cData>>4) & 0x0f);
	SSD1803A_E = 0;
	SSD1803A_DATA &= 0xf0;
	SSD1803A_E = 1;
	SSD1803A_DATA |= (cData & 0x0f);
	SSD1803A_E = 0;
	__delay_us(30);
}

void ssd1803a_writeString(const char * cData)
{
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	ssd1803a_writeInstruction(u8Data);
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

3.String & Custom Patterns - 4-Bit High Nibble No Busy Flag, PWM Controlled Backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DOGM204-A - 4x20 - SSD1803A - 4-Bit High Nibble No Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DOGM204-A - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 3V3.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> VDD - 3V3.
// MODULE.08 -> VDD - 3V3.
// MODULE.09 -> VDD - 3V3.
// MODULE.10 -> VDD - 3V3.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> MCU.RC2.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Open.
// JP4 - BCKL Open.

// Expansion Module.
// IM1 - Close //-SPI.
// IM2 - Close //.

// Definitions.
// SSD1803A Command Port & Data Port.
#define SSD1803A_DATA													LATB
#define SSD1803A_DATA_TRIS												TRISB
#define SSD1803A_RS_TRIS												TRISAbits.TRISA0
#define SSD1803A_E_TRIS													TRISAbits.TRISA1
#define SSD1803A_RS														LATAbits.LATA0
#define SSD1803A_E														LATAbits.LATA1
// DOGM204A Backlight.
#define BACKLIGHT														CCPR1L
#define DOGM204A_BACKLIGHT												LATCbits.LATC2
#define DOGM204A_BACKLIGHT_TRIS											TRISCbits.TRISC2
// Extension Register RE = 0 & IS = 0.
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_LEFT							0x10
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_RIGHT							0x14
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_LEFT							0x18
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_RIGHT							0x1C
#define SSD1803A_FS0_SET_CGRAM_ADDRESS									0x40
// Extension Register RE = 0 & IS = 1.
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F00						0x10
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F01						0x11
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F00						0x12
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F01						0x13
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F00						0x14
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F01						0x15
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F00						0x16
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F01						0x17
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F00						0x18
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F01						0x19
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F00						0x1A
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F01						0x1B
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F00						0x1C
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F01						0x1D
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00						0x1E
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F01						0x1F
#define SSD1803A_FS1_SET_SEGRAM_ADDRESS									0x40
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_0							0x50
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_1							0x51
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_2							0x52
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_3							0x53
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_0							0x54
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_1							0x55
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_2							0x56
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3							0x57
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_0 							0x58
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_1							0x59
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_2							0x5A
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_3							0x5B
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_0							0x5C
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_1							0x5D
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_2							0x5E
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_3							0x5F
#define SSD1803A_FS1_FOLLOWER_CONTROL_OFF								0x60
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_0							0x68
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_1							0x69
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_2							0x6A
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_3							0x6B
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_4							0x6C
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_5							0x6D
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6							0x6E
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_7							0x6F
#define SSD1803A_FS1_CONTRAST_LSB_0										0x70
#define SSD1803A_FS1_CONTRAST_LSB_1										0x71
#define SSD1803A_FS1_CONTRAST_LSB_2										0x72
#define SSD1803A_FS1_CONTRAST_LSB_3										0x73
#define SSD1803A_FS1_CONTRAST_LSB_4										0x74
#define SSD1803A_FS1_CONTRAST_LSB_5										0x75
#define SSD1803A_FS1_CONTRAST_LSB_6										0x76
#define SSD1803A_FS1_CONTRAST_LSB_7										0x77
#define SSD1803A_FS1_CONTRAST_LSB_8										0x78
#define SSD1803A_FS1_CONTRAST_LSB_9										0x79
#define SSD1803A_FS1_CONTRAST_LSB_10									0x7A
#define SSD1803A_FS1_CONTRAST_LSB_11									0x7B
#define SSD1803A_FS1_CONTRAST_LSB_12									0x7C
#define SSD1803A_FS1_CONTRAST_LSB_13									0x7D
#define SSD1803A_FS1_CONTRAST_LSB_14									0x7E
#define SSD1803A_FS1_CONTRAST_LSB_15									0x7F
// Extension Register RE = 1 & IS = 0.
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH0					0x10
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH1					0x11
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0					0x12
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH1					0x13
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH0					0x14
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH1					0x15
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH0					0x16
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH1					0x17
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH0					0x18
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH1					0x19
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH0					0x1A
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH1					0x1B
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH0					0x1C
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH1					0x1D
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH0					0x1E
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH1					0x1F
// Extension Register RE = 1 & IS = 1.
#define SSD1803A_FS3_NO_SHIFT											0x10
#define SSD1803A_FS3_SHIFT_LINE_1										0x11
#define SSD1803A_FS3_SHIFT_LINE_2										0x12
#define SSD1803A_FS3_SHIFT_LINE_12										0x13
#define SSD1803A_FS3_SHIFT_LINE_3										0x14
#define SSD1803A_FS3_SHIFT_LINE_13										0x15
#define SSD1803A_FS3_SHIFT_LINE_23										0x16
#define SSD1803A_FS3_SHIFT_LINE_123										0x17
#define SSD1803A_FS3_SHIFT_LINE_4										0x18
#define SSD1803A_FS3_SHIFT_LINE_14										0x19
#define SSD1803A_FS3_SHIFT_LINE_24										0x1A
#define SSD1803A_FS3_SHIFT_LINE_124										0x1B
#define SSD1803A_FS3_SHIFT_LINE_34										0x1C
#define SSD1803A_FS3_SHIFT_LINE_134										0x1D
#define SSD1803A_FS3_SHIFT_LINE_234										0x1E
#define SSD1803A_FS3_SHIFT_LINE_1234									0x1F
#define SSD1803A_FS3_NO_SCROLL										 	0x10
#define SSD1803A_FS3_SCROLL_LINE_1										0x11
#define SSD1803A_FS3_SCROLL_LINE_2										0x12
#define SSD1803A_FS3_SCROLL_LINE_12										0x13
#define SSD1803A_FS3_SCROLL_LINE_3										0x14
#define SSD1803A_FS3_SCROLL_LINE_13										0x15
#define SSD1803A_FS3_SCROLL_LINE_23										0x16
#define SSD1803A_FS3_SCROLL_LINE_123									0x17
#define SSD1803A_FS3_SCROLL_LINE_4										0x18
#define SSD1803A_FS3_SCROLL_LINE_14										0x19
#define SSD1803A_FS3_SCROLL_LINE_24										0x1A
#define SSD1803A_FS3_SCROLL_LINE_124									0x1B
#define SSD1803A_FS3_SCROLL_LINE_34										0x1C
#define SSD1803A_FS3_SCROLL_LINE_134									0x1D
#define SSD1803A_FS3_SCROLL_LINE_234									0x1E
#define SSD1803A_FS3_SCROLL_LINE_1234									0x1F
// Extension Register RE = 0 & IS = x.
#define SSD1803A_FS01_RETURN_HOME										0x02
#define SSD1803A_FS01_DISPLAY_OFF										0x08
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF								0x0C
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_NOBLINK						0x0E
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_BLINK						0x0F
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS0			0x20
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS1			0x21
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS0			0x24
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS1			0x25
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0			0x28
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1			0x29
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS0			0x2C
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS1			0x2D
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS0			0x30
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS1			0x31
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS0			0x34
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS1			0x35
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0			0x38
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1			0x39
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS0			0x3C
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS1			0x3D
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE						0x80
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE						0xA0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE						0xC0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE						0xE0
// Extension Register RE = 1 & IS = x.
#define SSD1803A_FS23_POWER_DOWN_OFF									0x02
#define SSD1803A_FS23_POWER_DOWN_ON										0x03
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW_MIRROR					0x04
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW							0x05
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW						0x06
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW_MIRROR					0x07
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_12LINE	0x08
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE	0x09
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_12LINE		0x0A
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_34LINE		0x0B
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_12LINE	0x0C
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_34LINE	0x0D
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_12LINE		0x0E
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_34LINE		0x0F
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_NORMAL			0x22
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_REVERSE			0x23
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_NORMAL			0x26
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_REVERSE			0x27
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL			0x2A
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_REVERSE			0x2B
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_NORMAL			0x2E
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_REVERSE			0x2F
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL			0x32
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE			0x33
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_NORMAL			0x36
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_REVERSE			0x37
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL			0x3A
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_REVERSE			0x3B
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_NORMAL			0x3E
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_REVERSE			0x3F
#define SSD1803A_FS23_SCROLL_QUANTITY									0x80
#define SSD1803A_FS23_TEMPERATURE_COEFFICIENT							0x76
#define SSD1803A_FS23_ROM_SELECTION_COMMAND								0x72
// Extension Register RE = x & IS = x.
#define SSD1803A_FS0123_CLEAR_DISPLAY									0x01
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT				0x04
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_SHIFT				0x05
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT				0x06
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_SHIFT				0x07
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_005					0x02
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_010					0x04
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_015					0x06
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_020					0x07
#define SSD1803A_FS0123_ROM_SELECTION_A									0x00
#define SSD1803A_FS0123_ROM_SELECTION_B									0x04
#define SSD1803A_FS0123_ROM_SELECTION_C									0x08

// Function prototypes.
void ssd1803a_displayClear(void);
void ssd1803a_initialize(void);
void ssd1803a_romSelection(uint8_t u8Data);
void ssd1803a_writeData(char cData);
void ssd1803a_writeInstruction(char cData);
void ssd1803a_writeString(const char * cData);
void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix I/O";
const char string1[] = "www.tronix.io";
const char string2[] = "Custom patterns";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
void mcu_initialize(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	SSD1803A_RS = 0;
	SSD1803A_E = 0;
	SSD1803A_RS_TRIS = 0;
	SSD1803A_E_TRIS = 0;
	// Outputs for LCD data.
	SSD1803A_DATA = 0x00;
	SSD1803A_DATA_TRIS = 0x00;
	// Output for Backlight.
	DOGM204A_BACKLIGHT = 0;
	DOGM204A_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer 2 - 1kHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

	ssd1803a_initialize();
	ssd1803a_romSelection(SSD1803A_FS0123_ROM_SELECTION_A);

	// Write 5x8 Dots Custom Patterns in SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS0_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			ssd1803a_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	ssd1803a_writeStringSetCursor(string0, SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE + 0x05);
	ssd1803a_writeStringSetCursor(string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE + 0x03);
	ssd1803a_writeStringSetCursor(string2, SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE + 0x02);

	// Display Custom Patterns from SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x05);
	ssd1803a_writeData(0x00);
	ssd1803a_writeData(0x01);
	ssd1803a_writeData(0x02);
	ssd1803a_writeData(0x03);
	ssd1803a_writeData(0x04);
	ssd1803a_writeString(" - ");
	
	uint8_t backlight;
	while(1){
		for(backlight=0; backlight<128; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(50);
		}
		for(pattern=0; pattern<5; pattern++){
			ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x0d);
			ssd1803a_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void ssd1803a_displayClear(void)
{
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_initialize(void)
{
	__delay_ms(10);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE);
	ssd1803a_writeInstruction(SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW);
	ssd1803a_writeInstruction(SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0);
	ssd1803a_writeInstruction(SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1);
	ssd1803a_writeInstruction(SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6);
	ssd1803a_writeInstruction(SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3);
	ssd1803a_writeInstruction(SSD1803A_FS1_CONTRAST_LSB_10);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0);
	ssd1803a_writeInstruction(SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF);
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_romSelection(uint8_t u8Data)
{
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_ROM_SELECTION_COMMAND);
	ssd1803a_writeData(u8Data);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0);
}

void ssd1803a_writeData(char cData)
{
	SSD1803A_RS = 1;
	SSD1803A_DATA &= 0x0f;
	SSD1803A_E = 1;
	SSD1803A_DATA |= (cData & 0xf0);
	SSD1803A_E = 0;
	SSD1803A_DATA &= 0x0f;
	SSD1803A_E = 1;
	SSD1803A_DATA |= ((cData<<4) & 0xf0);
	SSD1803A_E = 0;
	__delay_us(10);
}

void ssd1803a_writeInstruction(char cData)
{
	SSD1803A_RS = 0;
	SSD1803A_DATA &= 0x0f;
	SSD1803A_E = 1;
	SSD1803A_DATA |= (cData & 0xf0);
	SSD1803A_E = 0;
	SSD1803A_DATA &= 0x0f;
	SSD1803A_E = 1;
	SSD1803A_DATA |= ((cData<<4) & 0xf0);
	SSD1803A_E = 0;
	__delay_us(30);
}

void ssd1803a_writeString(const char * cData)
{
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	ssd1803a_writeInstruction(u8Data);
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

4.String & Custom Patterns - I2C, PWM Controlled Backlight.

// Configuration register.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DOGM204-A - 4x20 - SSD1803A - I2C.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DOGM204-A - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 3V3.
// MODULE.03 -> NC.
// MODULE.04 -> GND.
// MODULE.05 -> VDD - 3V3.
// MODULE.06 -> VDD - 3V3.
// MODULE.07 -> MCU.RC3.
// MODULE.08 -> MCU.RC4.
// MODULE.09 -> MCU.RC4.
// MODULE.10 -> VDD - 3V3.
// MODULE.11 -> VDD - 3V3.
// MODULE.12 -> VDD - 3V3.
// MODULE.13 -> VDD - 3V3.
// MODULE.14 -> VDD - 3V3.
// MODULE.15 -> MCU.RC2.
// MODULE.16 -> NC.

// JP1 - SCL Close.
// JP2 - SDA Close.
// JP3 - VEE Open.
// JP4 - BCKL Open.

// Expansion Module.
// IM1 - Close I2C.
// IM2 - Close SPI-I2C.

// Definitions.
// I2C Port.
#define I2C_SCL															LATCbits.LATC3
#define I2C_SDA															LATCbits.LATC4
#define I2C_SCL_TRIS													TRISCbits.TRISC3
#define I2C_SDA_TRIS													TRISCbits.TRISC4
// I2C.
#define I2C_WRITE														0x00
#define I2C_READ														0x01
// DOGM204A Backlight.
#define BACKLIGHT														CCPR1L
#define DOGM204A_BACKLIGHT												LATCbits.LATC2
#define DOGM204A_BACKLIGHT_TRIS											TRISCbits.TRISC2
// SSD1803A Address Select Bit A0.
#define SSD1803A_ADDRESS_78												0x78
#define SSD1803A_ADDRESS_7A												0x7A
#define SSD1803A_CONTROL_CONTINUOUS_COMMAND								0x00
#define SSD1803A_CONTROL_CONTINUOUS_DATA								0x40
#define SSD1803A_CONTROL_NO_CONTINUOUS_COMMAND							0x80
#define SSD1803A_CONTROL_NO_CONTINUOUS_DATA								0xC0
// Extension Register RE = 0 & IS = 0.
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_LEFT							0x10
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_RIGHT							0x14
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_LEFT							0x18
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_RIGHT							0x1C
#define SSD1803A_FS0_SET_CGRAM_ADDRESS									0x40
// Extension Register RE = 0 & IS = 1.
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F00						0x10
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F01						0x11
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F00						0x12
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F01						0x13
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F00						0x14
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F01						0x15
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F00						0x16
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F01						0x17
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F00						0x18
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F01						0x19
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F00						0x1A
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F01						0x1B
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F00						0x1C
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F01						0x1D
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00						0x1E
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F01						0x1F
#define SSD1803A_FS1_SET_SEGRAM_ADDRESS									0x40
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_0							0x50
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_1							0x51
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_2							0x52
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_3							0x53
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_0							0x54
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_1							0x55
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_2							0x56
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3							0x57
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_0 							0x58
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_1							0x59
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_2							0x5A
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_3							0x5B
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_0							0x5C
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_1							0x5D
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_2							0x5E
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_3							0x5F
#define SSD1803A_FS1_FOLLOWER_CONTROL_OFF								0x60
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_0							0x68
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_1							0x69
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_2							0x6A
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_3							0x6B
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_4							0x6C
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_5							0x6D
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6							0x6E
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_7							0x6F
#define SSD1803A_FS1_CONTRAST_LSB_0										0x70
#define SSD1803A_FS1_CONTRAST_LSB_1										0x71
#define SSD1803A_FS1_CONTRAST_LSB_2										0x72
#define SSD1803A_FS1_CONTRAST_LSB_3										0x73
#define SSD1803A_FS1_CONTRAST_LSB_4										0x74
#define SSD1803A_FS1_CONTRAST_LSB_5										0x75
#define SSD1803A_FS1_CONTRAST_LSB_6										0x76
#define SSD1803A_FS1_CONTRAST_LSB_7										0x77
#define SSD1803A_FS1_CONTRAST_LSB_8										0x78
#define SSD1803A_FS1_CONTRAST_LSB_9										0x79
#define SSD1803A_FS1_CONTRAST_LSB_10									0x7A
#define SSD1803A_FS1_CONTRAST_LSB_11									0x7B
#define SSD1803A_FS1_CONTRAST_LSB_12									0x7C
#define SSD1803A_FS1_CONTRAST_LSB_13									0x7D
#define SSD1803A_FS1_CONTRAST_LSB_14									0x7E
#define SSD1803A_FS1_CONTRAST_LSB_15									0x7F
// Extension Register RE = 1 & IS = 0.
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH0					0x10
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH1					0x11
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0					0x12
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH1					0x13
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH0					0x14
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH1					0x15
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH0					0x16
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH1					0x17
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH0					0x18
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH1					0x19
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH0					0x1A
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH1					0x1B
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH0					0x1C
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH1					0x1D
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH0					0x1E
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH1					0x1F
// Extension Register RE = 1 & IS = 1.
#define SSD1803A_FS3_NO_SHIFT											0x10
#define SSD1803A_FS3_SHIFT_LINE_1										0x11
#define SSD1803A_FS3_SHIFT_LINE_2										0x12
#define SSD1803A_FS3_SHIFT_LINE_12										0x13
#define SSD1803A_FS3_SHIFT_LINE_3										0x14
#define SSD1803A_FS3_SHIFT_LINE_13										0x15
#define SSD1803A_FS3_SHIFT_LINE_23										0x16
#define SSD1803A_FS3_SHIFT_LINE_123										0x17
#define SSD1803A_FS3_SHIFT_LINE_4										0x18
#define SSD1803A_FS3_SHIFT_LINE_14										0x19
#define SSD1803A_FS3_SHIFT_LINE_24										0x1A
#define SSD1803A_FS3_SHIFT_LINE_124										0x1B
#define SSD1803A_FS3_SHIFT_LINE_34										0x1C
#define SSD1803A_FS3_SHIFT_LINE_134										0x1D
#define SSD1803A_FS3_SHIFT_LINE_234										0x1E
#define SSD1803A_FS3_SHIFT_LINE_1234									0x1F
#define SSD1803A_FS3_NO_SCROLL										 	0x10
#define SSD1803A_FS3_SCROLL_LINE_1										0x11
#define SSD1803A_FS3_SCROLL_LINE_2										0x12
#define SSD1803A_FS3_SCROLL_LINE_12										0x13
#define SSD1803A_FS3_SCROLL_LINE_3										0x14
#define SSD1803A_FS3_SCROLL_LINE_13										0x15
#define SSD1803A_FS3_SCROLL_LINE_23										0x16
#define SSD1803A_FS3_SCROLL_LINE_123									0x17
#define SSD1803A_FS3_SCROLL_LINE_4										0x18
#define SSD1803A_FS3_SCROLL_LINE_14										0x19
#define SSD1803A_FS3_SCROLL_LINE_24										0x1A
#define SSD1803A_FS3_SCROLL_LINE_124									0x1B
#define SSD1803A_FS3_SCROLL_LINE_34										0x1C
#define SSD1803A_FS3_SCROLL_LINE_134									0x1D
#define SSD1803A_FS3_SCROLL_LINE_234									0x1E
#define SSD1803A_FS3_SCROLL_LINE_1234									0x1F
// Extension Register RE = 0 & IS = x.
#define SSD1803A_FS01_RETURN_HOME										0x02
#define SSD1803A_FS01_DISPLAY_OFF										0x08
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF								0x0C
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_NOBLINK						0x0E
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_BLINK						0x0F
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS0			0x20
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS1			0x21
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS0			0x24
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS1			0x25
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0			0x28
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1			0x29
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS0			0x2C
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS1			0x2D
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS0			0x30
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS1			0x31
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS0			0x34
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS1			0x35
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0			0x38
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1			0x39
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS0			0x3C
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS1			0x3D
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE						0x80
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE						0xA0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE						0xC0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE						0xE0
// Extension Register RE = 1 & IS = x.
#define SSD1803A_FS23_POWER_DOWN_OFF									0x02
#define SSD1803A_FS23_POWER_DOWN_ON										0x03
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW_MIRROR					0x04
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW							0x05
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW						0x06
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW_MIRROR					0x07
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_12LINE	0x08
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE	0x09
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_12LINE		0x0A
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_34LINE		0x0B
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_12LINE	0x0C
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_34LINE	0x0D
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_12LINE		0x0E
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_34LINE		0x0F
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_NORMAL			0x22
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_REVERSE			0x23
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_NORMAL			0x26
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_REVERSE			0x27
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL			0x2A
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_REVERSE			0x2B
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_NORMAL			0x2E
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_REVERSE			0x2F
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL			0x32
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE			0x33
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_NORMAL			0x36
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_REVERSE			0x37
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL			0x3A
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_REVERSE			0x3B
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_NORMAL			0x3E
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_REVERSE			0x3F
#define SSD1803A_FS23_SCROLL_QUANTITY									0x80
#define SSD1803A_FS23_TEMPERATURE_COEFFICIENT							0x76
#define SSD1803A_FS23_ROM_SELECTION_COMMAND								0x72
// Extension Register RE = x & IS = x.
#define SSD1803A_FS0123_CLEAR_DISPLAY									0x01
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT				0x04
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_SHIFT				0x05
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT				0x06
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_SHIFT				0x07
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_005					0x02
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_010					0x04
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_015					0x06
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_020					0x07
#define SSD1803A_FS0123_ROM_SELECTION_A									0x00
#define SSD1803A_FS0123_ROM_SELECTION_B									0x04
#define SSD1803A_FS0123_ROM_SELECTION_C									0x08

// Function prototypes.
void i2c_initializeMaster(void);
uint8_t i2c_read(void);
void i2c_restart(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_write(uint8_t u8Data);
void mcu_initialize(void);
void pwm_initialize(void);
void ssd1803a_displayClear(uint8_t u8Address);
void ssd1803a_initialize(uint8_t u8Address);
void ssd1803a_romSelection(uint8_t u8Address, uint8_t u8Data);
void ssd1803a_writeData(uint8_t u8Address, char cData);
void ssd1803a_writeInstruction(uint8_t u8Address, char cData);
void ssd1803a_writeString(uint8_t u8Address, const char * cData);
void ssd1803a_writeStringSetCursor(uint8_t u8Address, const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix I/O";
const char string1[] = "www.tronix.io";
const char string2[] = "Custom patterns";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	mcu_initialize();
	pwm_initialize();
	i2c_initializeMaster();
	ssd1803a_initialize(SSD1803A_ADDRESS_78);
	ssd1803a_romSelection(SSD1803A_ADDRESS_78, SSD1803A_FS0123_ROM_SELECTION_A);

	// Write 5x8 Dots Custom Patterns in SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_ADDRESS_78, SSD1803A_FS0_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			ssd1803a_writeData(SSD1803A_ADDRESS_78, custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	ssd1803a_writeStringSetCursor(SSD1803A_ADDRESS_78, string0, SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE + 0x05);
	ssd1803a_writeStringSetCursor(SSD1803A_ADDRESS_78, string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE + 0x03);
	ssd1803a_writeStringSetCursor(SSD1803A_ADDRESS_78, string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE + 0x02);

	// Display Custom Patterns from SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_ADDRESS_78, SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x05);
	ssd1803a_writeData(SSD1803A_ADDRESS_78, 0x00);
	ssd1803a_writeData(SSD1803A_ADDRESS_78, 0x01);
	ssd1803a_writeData(SSD1803A_ADDRESS_78, 0x02);
	ssd1803a_writeData(SSD1803A_ADDRESS_78, 0x03);
	ssd1803a_writeData(SSD1803A_ADDRESS_78, 0x04);
	ssd1803a_writeString(SSD1803A_ADDRESS_78, " - ");

	uint8_t backlight;
	while(1){
		for(backlight=0; backlight<128; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(50);
		}
		for(pattern=0; pattern<5; pattern++){
		ssd1803a_writeInstruction(SSD1803A_ADDRESS_78, SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x0d);
			ssd1803a_writeData(SSD1803A_ADDRESS_78, pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void i2c_initializeMaster(void)
{
	// I2C - Master.
	SSPSTAT = 0x80;
	SSPCON1 = 0x28;
	SSPCON2 = 0x00;
	// SSPADD = 0x03 ~400kHz @8MHz.
	// SSPADD = 0x12 ~100kHz @8MHz.
	SSPADD = 0x12;
}

void i2c_restart(void)
{
	SSPCON2bits.RSEN = 1;
	while(SSPCON2bits.RSEN);
}

void i2c_start(void)
{
	SSPCON2bits.SEN = 1;
	while(SSPCON2bits.SEN);
}

void i2c_stop(void)
{
	SSPCON2bits.PEN = 1;
	while(SSPCON2bits.PEN);
}

void i2c_write(uint8_t u8Data)
{
	PIR1bits.SSPIF = 0;
	SSPBUF = u8Data;
	while(!PIR1bits.SSPIF);
	while(SSPCON2bits.ACKSTAT);
}

void mcu_initialize(void)
{
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// I2C Port.
	I2C_SDA = 0;
	I2C_SCL = 0;
	I2C_SDA_TRIS = 1;
	I2C_SCL_TRIS = 1;
	// Output for Backlight.
	DOGM204A_BACKLIGHT = 0;
	DOGM204A_BACKLIGHT_TRIS = 0;
}

void pwm_initialize(void)
{
	// Timer 2 - 1kHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;
}

void ssd1803a_displayClear(uint8_t u8Address)
{
	ssd1803a_writeInstruction(u8Address, SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_initialize(uint8_t u8Address)
{
	__delay_ms(10);
	i2c_start();
	i2c_write(SSD1803A_ADDRESS_78);
	i2c_write(SSD1803A_CONTROL_CONTINUOUS_COMMAND);
	i2c_write(SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	i2c_write(SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE);
	i2c_write(SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW);
	i2c_write(SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0);
	i2c_write(SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00);
	i2c_write(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1);
	i2c_write(SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6);
	i2c_write(SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3);
	i2c_write(SSD1803A_FS1_CONTRAST_LSB_10);
	i2c_write(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
	i2c_write(SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF);
	i2c_write(SSD1803A_FS0123_CLEAR_DISPLAY);
	i2c_stop();
	__delay_ms(2);
}

void ssd1803a_romSelection(uint8_t u8Address, uint8_t u8Data)
{
	ssd1803a_writeInstruction(u8Address, SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(u8Address, SSD1803A_FS23_ROM_SELECTION_COMMAND);
	ssd1803a_writeData(u8Address, u8Data);
	ssd1803a_writeInstruction(u8Address, SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
}

void ssd1803a_writeData(uint8_t u8Address, char cData)
{
	i2c_start();
	i2c_write((uint8_t)(u8Address | I2C_WRITE));
	i2c_write(SSD1803A_CONTROL_NO_CONTINUOUS_DATA);
	i2c_write(cData);
	i2c_stop();
}

void ssd1803a_writeInstruction(uint8_t u8Address, char cData)
{
	i2c_start();
	i2c_write((uint8_t)(u8Address | I2C_WRITE));
	i2c_write(SSD1803A_CONTROL_NO_CONTINUOUS_COMMAND);
	i2c_write(cData);
	i2c_stop();
}

void ssd1803a_writeString(uint8_t u8Address, const char * cData)
{
	i2c_start();
	i2c_write((uint8_t)(u8Address | I2C_WRITE));
	i2c_write(SSD1803A_CONTROL_CONTINUOUS_DATA);
	while(*cData != '\0')
		i2c_write(*cData++);
	i2c_stop();
}

void ssd1803a_writeStringSetCursor(uint8_t u8Address, const char * cData, uint8_t u8Data)
{
	i2c_start();
	i2c_write((uint8_t)(u8Address | I2C_WRITE));
	i2c_write(SSD1803A_CONTROL_NO_CONTINUOUS_COMMAND);
	i2c_write(u8Data);
	i2c_write(SSD1803A_CONTROL_CONTINUOUS_DATA);
	while(*cData != '\0')
		i2c_write(*cData++);
	i2c_stop();
}

5.String & Custom Patterns - Software SPI, PWM Controlled Backlight.

// Configuration register.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DOGM204-A - 4x20 - SSD1803A - Software SPI.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DOGM204-A - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 3V3.
// MODULE.03 -> NC.
// MODULE.04 -> VDD - 3V3.
// MODULE.05 -> VDD - 3V3.
// MODULE.06 -> VDD - 3V3.
// MODULE.07 -> MCU.RC3.
// MODULE.08 -> MCU.RC5.
// MODULE.09 -> NC.
// MODULE.10 -> VDD - 3V3.
// MODULE.11 -> VDD - 3V3.
// MODULE.12 -> VDD - 3V3.
// MODULE.13 -> VDD - 3V3.
// MODULE.14 -> VDD - 3V3.
// MODULE.15 -> MCU.RC2.
// MODULE.16 -> NC.

// JP1 - SCL Open.
// JP2 - SDA Open.
// JP3 - VEE Open.
// JP4 - BCKL Open.

// Expansion Module.
// IM1 - Close //-SPI.
// IM2 - Close SPI-I2C.

// Definitions.
// SPI Port.
#define SPI_SCK															LATCbits.LATC3
#define SPI_SDI															LATCbits.LATC5
#define SPI_SCK_TRIS													TRISCbits.TRISC3
#define SPI_SDI_TRIS													TRISCbits.TRISC5
// DOGM204A Backlight.
#define BACKLIGHT														CCPR1L
#define DOGM204A_BACKLIGHT												LATCbits.LATC2
#define DOGM204A_BACKLIGHT_TRIS											TRISCbits.TRISC2
// SSD1803A Address Select Bit A0.
#define SSD1803A_ADDRESS_78												0x78
#define SSD1803A_ADDRESS_7A												0x7A
#define SSD1803A_CONTROL_CONTINUOUS_COMMAND								0x00
#define SSD1803A_CONTROL_CONTINUOUS_DATA								0x40
#define SSD1803A_CONTROL_NO_CONTINUOUS_COMMAND							0x80
#define SSD1803A_CONTROL_NO_CONTINUOUS_DATA								0xC0
// Extension Register RE = 0 & IS = 0.
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_LEFT							0x10
#define SSD1803A_FS0_DISPLAY_CURSOR_SHIFT_RIGHT							0x14
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_LEFT							0x18
#define SSD1803A_FS0_DISPLAY_SCREEN_SHIFT_RIGHT							0x1C
#define SSD1803A_FS0_SET_CGRAM_ADDRESS									0x40
// Extension Register RE = 0 & IS = 1.
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F00						0x10
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F10_F01						0x11
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F00						0x12
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F20_F11_F01						0x13
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F00						0x14
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F10_F01						0x15
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F00						0x16
#define SSD1803A_FS1_INTERNAL_OSC_BS00_F21_F11_F01						0x17
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F00						0x18
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F10_F01						0x19
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F00						0x1A
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F20_F11_F01						0x1B
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F00						0x1C
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F10_F01						0x1D
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00						0x1E
#define SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F01						0x1F
#define SSD1803A_FS1_SET_SEGRAM_ADDRESS									0x40
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_0							0x50
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_1							0x51
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_2							0x52
#define SSD1803A_FS1_ION0_BON0_CONTRAST_MSB_3							0x53
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_0							0x54
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_1							0x55
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_2							0x56
#define SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3							0x57
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_0 							0x58
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_1							0x59
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_2							0x5A
#define SSD1803A_FS1_ION1_BON0_CONTRAST_MSB_3							0x5B
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_0							0x5C
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_1							0x5D
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_2							0x5E
#define SSD1803A_FS1_ION1_BON1_CONTRAST_MSB_3							0x5F
#define SSD1803A_FS1_FOLLOWER_CONTROL_OFF								0x60
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_0							0x68
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_1							0x69
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_2							0x6A
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_3							0x6B
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_4							0x6C
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_5							0x6D
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6							0x6E
#define SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_7							0x6F
#define SSD1803A_FS1_CONTRAST_LSB_0										0x70
#define SSD1803A_FS1_CONTRAST_LSB_1										0x71
#define SSD1803A_FS1_CONTRAST_LSB_2										0x72
#define SSD1803A_FS1_CONTRAST_LSB_3										0x73
#define SSD1803A_FS1_CONTRAST_LSB_4										0x74
#define SSD1803A_FS1_CONTRAST_LSB_5										0x75
#define SSD1803A_FS1_CONTRAST_LSB_6										0x76
#define SSD1803A_FS1_CONTRAST_LSB_7										0x77
#define SSD1803A_FS1_CONTRAST_LSB_8										0x78
#define SSD1803A_FS1_CONTRAST_LSB_9										0x79
#define SSD1803A_FS1_CONTRAST_LSB_10									0x7A
#define SSD1803A_FS1_CONTRAST_LSB_11									0x7B
#define SSD1803A_FS1_CONTRAST_LSB_12									0x7C
#define SSD1803A_FS1_CONTRAST_LSB_13									0x7D
#define SSD1803A_FS1_CONTRAST_LSB_14									0x7E
#define SSD1803A_FS1_CONTRAST_LSB_15									0x7F
// Extension Register RE = 1 & IS = 0.
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH0					0x10
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS10_DH1					0x11
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0					0x12
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH1					0x13
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH0					0x14
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS10_DH1					0x15
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH0					0x16
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD11_BS11_DH1					0x17
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH0					0x18
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS10_DH1					0x19
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH0					0x1A
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD10_BS11_DH1					0x1B
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH0					0x1C
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS10_DH1					0x1D
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH0					0x1E
#define SSD1803A_FS2_DOUBLE_HEIGHT_UD21_UD11_BS11_DH1					0x1F
// Extension Register RE = 1 & IS = 1.
#define SSD1803A_FS3_NO_SHIFT											0x10
#define SSD1803A_FS3_SHIFT_LINE_1										0x11
#define SSD1803A_FS3_SHIFT_LINE_2										0x12
#define SSD1803A_FS3_SHIFT_LINE_12										0x13
#define SSD1803A_FS3_SHIFT_LINE_3										0x14
#define SSD1803A_FS3_SHIFT_LINE_13										0x15
#define SSD1803A_FS3_SHIFT_LINE_23										0x16
#define SSD1803A_FS3_SHIFT_LINE_123										0x17
#define SSD1803A_FS3_SHIFT_LINE_4										0x18
#define SSD1803A_FS3_SHIFT_LINE_14										0x19
#define SSD1803A_FS3_SHIFT_LINE_24										0x1A
#define SSD1803A_FS3_SHIFT_LINE_124										0x1B
#define SSD1803A_FS3_SHIFT_LINE_34										0x1C
#define SSD1803A_FS3_SHIFT_LINE_134										0x1D
#define SSD1803A_FS3_SHIFT_LINE_234										0x1E
#define SSD1803A_FS3_SHIFT_LINE_1234									0x1F
#define SSD1803A_FS3_NO_SCROLL										 	0x10
#define SSD1803A_FS3_SCROLL_LINE_1										0x11
#define SSD1803A_FS3_SCROLL_LINE_2										0x12
#define SSD1803A_FS3_SCROLL_LINE_12										0x13
#define SSD1803A_FS3_SCROLL_LINE_3										0x14
#define SSD1803A_FS3_SCROLL_LINE_13										0x15
#define SSD1803A_FS3_SCROLL_LINE_23										0x16
#define SSD1803A_FS3_SCROLL_LINE_123									0x17
#define SSD1803A_FS3_SCROLL_LINE_4										0x18
#define SSD1803A_FS3_SCROLL_LINE_14										0x19
#define SSD1803A_FS3_SCROLL_LINE_24										0x1A
#define SSD1803A_FS3_SCROLL_LINE_124									0x1B
#define SSD1803A_FS3_SCROLL_LINE_34										0x1C
#define SSD1803A_FS3_SCROLL_LINE_134									0x1D
#define SSD1803A_FS3_SCROLL_LINE_234									0x1E
#define SSD1803A_FS3_SCROLL_LINE_1234									0x1F
// Extension Register RE = 0 & IS = x.
#define SSD1803A_FS01_RETURN_HOME										0x02
#define SSD1803A_FS01_DISPLAY_OFF										0x08
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF								0x0C
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_NOBLINK						0x0E
#define SSD1803A_FS01_DISPLAY_ON_CURSOR_ON_BLINK						0x0F
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS0			0x20
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT0_RE0_IS1			0x21
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS0			0x24
#define SSD1803A_FS01_FUNCION_SET_4BIT_13LINE_DHFONT1_RE0_IS1			0x25
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS0			0x28
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT0_RE0_IS1			0x29
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS0			0x2C
#define SSD1803A_FS01_FUNCION_SET_4BIT_24LINE_DHFONT1_RE0_IS1			0x2D
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS0			0x30
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT0_RE0_IS1			0x31
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS0			0x34
#define SSD1803A_FS01_FUNCION_SET_8BIT_13LINE_DHFONT1_RE0_IS1			0x35
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0			0x38
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1			0x39
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS0			0x3C
#define SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT1_RE0_IS1			0x3D
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE						0x80
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE						0xA0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE						0xC0
#define SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE						0xE0
// Extension Register RE = 1 & IS = x.
#define SSD1803A_FS23_POWER_DOWN_OFF									0x02
#define SSD1803A_FS23_POWER_DOWN_ON										0x03
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW_MIRROR					0x04
#define SSD1803A_FS23_ENTRY_MODE_SET_TOP_VIEW							0x05
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW						0x06
#define SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW_MIRROR					0x07
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_12LINE	0x08
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE	0x09
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_12LINE		0x0A
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_INVERTING_34LINE		0x0B
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_12LINE	0x0C
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_NOINVERTING_34LINE	0x0D
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_12LINE		0x0E
#define SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT6_INVERTING_34LINE		0x0F
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_NORMAL			0x22
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE0_RE1_REVERSE			0x23
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_NORMAL			0x26
#define SSD1803A_FS23_FUNCION_SET_4BIT_13LINE_BE1_RE1_REVERSE			0x27
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_NORMAL			0x2A
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE0_RE1_REVERSE			0x2B
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_NORMAL			0x2E
#define SSD1803A_FS23_FUNCION_SET_4BIT_24LINE_BE1_RE1_REVERSE			0x2F
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_NORMAL			0x32
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE0_RE1_REVERSE			0x33
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_NORMAL			0x36
#define SSD1803A_FS23_FUNCION_SET_8BIT_13LINE_BE1_RE1_REVERSE			0x37
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL			0x3A
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_REVERSE			0x3B
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_NORMAL			0x3E
#define SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE1_RE1_REVERSE			0x3F
#define SSD1803A_FS23_SCROLL_QUANTITY									0x80
#define SSD1803A_FS23_TEMPERATURE_COEFFICIENT							0x76
#define SSD1803A_FS23_ROM_SELECTION_COMMAND								0x72
// Extension Register RE = x & IS = x.
#define SSD1803A_FS0123_CLEAR_DISPLAY									0x01
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT				0x04
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_DECREMENT_SHIFT				0x05
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT				0x06
#define SSD1803A_FS0123_ENTRY_MODE_DDRAM_INCREMENT_SHIFT				0x07
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_005					0x02
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_010					0x04
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_015					0x06
#define SSD1803A_FS0123_TEMPERATURE_COEFFICIENT_SET_020					0x07
#define SSD1803A_FS0123_ROM_SELECTION_A									0x00
#define SSD1803A_FS0123_ROM_SELECTION_B									0x04
#define SSD1803A_FS0123_ROM_SELECTION_C									0x08

// Function prototypes.
void ssd1803a_displayClear();
void ssd1803a_initialize();
void ssd1803a_romSelection(uint8_t u8Data);
void ssd1803a_writeData(char cData);
void ssd1803a_writeInstruction(char cData);
void ssd1803a_writeString(const char * cData);
void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix I/O";
const char string1[] = "www.tronix.io";
const char string2[] = "Custom patterns";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// SPI Output.
	SPI_SCK = 0;
	SPI_SDI = 0;
	SPI_SCK_TRIS = 0;
	SPI_SDI_TRIS = 0;
	// Output for Backlight.
	DOGM204A_BACKLIGHT = 0;
	DOGM204A_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer 2 - 1kHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

    ssd1803a_initialize();
    ssd1803a_romSelection(SSD1803A_FS0123_ROM_SELECTION_A);

	// Write 5x8 Dots Custom Patterns in SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS0_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			ssd1803a_writeData(custom_patterns[pattern][line]);
		}
	}
    
	// Display String.
	ssd1803a_writeStringSetCursor(string0, SSD1803A_FS01_SET_DDRAM_ADDRESS_FIRST_LINE + 0x05);
	ssd1803a_writeStringSetCursor(string1, SSD1803A_FS01_SET_DDRAM_ADDRESS_SECOND_LINE + 0x03);	
	ssd1803a_writeStringSetCursor(string2, SSD1803A_FS01_SET_DDRAM_ADDRESS_THIRD_LINE + 0x02);	

	// Display Custom Patterns from SSD1803A CGRAM.
	ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x05);
	ssd1803a_writeData(0x00);
	ssd1803a_writeData(0x01);
	ssd1803a_writeData(0x02);
	ssd1803a_writeData(0x03);
	ssd1803a_writeData(0x04);
	ssd1803a_writeString(" - ");
    
	uint8_t backlight;
    while(1){
		for(backlight=0; backlight<128; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(50);
		}
		for(pattern=0; pattern<5; pattern++){
			ssd1803a_writeInstruction(SSD1803A_FS01_SET_DDRAM_ADDRESS_FOURTH_LINE + 0x0d);
			ssd1803a_writeData(pattern);
			__delay_ms(800);
		}
    }
	return(0);
}

// Functions.
void ssd1803a_displayClear(void)
{
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_initialize(void)
{
	__delay_ms(15);
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_EXTENDED_FUNCTION_SET_FONT5_NOINVERTING_34LINE);
	ssd1803a_writeInstruction(SSD1803A_FS23_ENTRY_MODE_SET_BOTTOM_VIEW);
	ssd1803a_writeInstruction(SSD1803A_FS2_DOUBLE_HEIGHT_UD20_UD10_BS11_DH0);
	ssd1803a_writeInstruction(SSD1803A_FS1_INTERNAL_OSC_BS01_F21_F11_F00);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS1);
	ssd1803a_writeInstruction(SSD1803A_FS1_FOLLOWER_CONTROL_ON_RAB_6);
	ssd1803a_writeInstruction(SSD1803A_FS1_ION0_BON1_CONTRAST_MSB_3);
	ssd1803a_writeInstruction(SSD1803A_FS1_CONTRAST_LSB_10);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
	ssd1803a_writeInstruction(SSD1803A_FS01_DISPLAY_ON_CURSOR_OFF);
	ssd1803a_writeInstruction(SSD1803A_FS0123_CLEAR_DISPLAY);
	__delay_ms(2);
}

void ssd1803a_romSelection(uint8_t u8Data)
{
	ssd1803a_writeInstruction(SSD1803A_FS23_FUNCION_SET_8BIT_24LINE_BE0_RE1_NORMAL);
	ssd1803a_writeInstruction(SSD1803A_FS23_ROM_SELECTION_COMMAND);
	ssd1803a_writeData(u8Data);
	ssd1803a_writeInstruction(SSD1803A_FS01_FUNCION_SET_8BIT_24LINE_DHFONT0_RE0_IS0);
}

void ssd1803a_writeData(char cData)
{
	uint8_t byte, count;

    // Start Byte.
    count = 7;
    byte = 0b01011111;
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
    // Lower Data.
    count = 7;
    byte = 0x0F & cData;
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
    // Upper Data.
	count = 7;
    byte = 0x0F & (cData>>4);
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
	SPI_SDI = 0;
}

void ssd1803a_writeInstruction(char cData)
{
	uint8_t byte, count;

    // Start Byte.
    count = 7;
    byte = 0b00011111;
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
    // Lower Data.
    count = 7;
    byte = 0x0F & cData;
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
    // Upper Data.
	count = 7;
    byte = 0x0F & (cData>>4);
	do{
		if(byte & 0x01)
			SPI_SDI = 1;
		else
			SPI_SDI = 0;
		SPI_SCK = 1;
		SPI_SCK = 0;
		byte = byte>>1;
	}while(count--);
	SPI_SDI = 0;
}

void ssd1803a_writeString(const char * cData)
{
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

void ssd1803a_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	ssd1803a_writeInstruction(u8Data);
	while(*cData != '\0')
		ssd1803a_writeData(*cData++);
}

08.2018