tigp oled display test
[soft/lpc122x/tigp] / oled / main.c
1 /****************************************************************************
2  *   oled/main.c
3  *
4  * Test of Oled display on tigp board
5  *
6  * Copyright 2017 Nathael Pajani <nathael.pajani@ed3l.fr>
7  *
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  *************************************************************************** */
26 #include "core/system.h"
27 #include "core/systick.h"
28 #include "core/pio.h"
29 #include "lib/stdio.h"
30 #include "drivers/serial.h"
31 #include "drivers/gpio.h"
32 #include "drivers/ssp.h"
34 #include "extdrv/status_led.h"
35 #include "extdrv/ssd130x_oled_driver.h"
36 #include "extdrv/ssd130x_oled_buffer.h"
37 #include "lib/font.h"
40 #define MODULE_VERSION    0x01
41 #define MODULE_NAME "TIGP"
44 #define SELECTED_FREQ  FREQ_SEL_48MHz
47 /***************************************************************************** */
48 /* Pins configuration */
49 /* pins blocks are passed to set_pins() for pins configuration.
50  * Unused pin blocks can be removed safely with the corresponding set_pins() call
51  * All pins blocks may be safelly merged in a single block for single set_pins() call..
52  */
53 const struct pio_config common_pins[] = {
54         /* UART 0 : Config / Debug / USB */
55         { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
56         { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
57         /* I2C : RTC, Temp sensor, Accelerometer */
58         { LPC_I2C0_SCL_PIO_0_10, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
59         { LPC_I2C0_SDA_PIO_0_11, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
60         /* SPI : Display and uSD card */
61         { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL },
62         { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL },
63         { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL },
64         /* Buttons */
65         { LPC_GPIO_0_3, LPC_IO_DIGITAL },  /* B1 */
66         { LPC_GPIO_0_4, LPC_IO_DIGITAL },  /* B2 */
67         { LPC_GPIO_0_5, LPC_IO_DIGITAL },  /* B3 */
68         { LPC_GPIO_0_6, LPC_IO_DIGITAL },  /* B4 */
69         { LPC_GPIO_0_7, LPC_IO_DIGITAL },  /* B6 */
70         { LPC_GPIO_0_8, LPC_IO_DIGITAL },  /* B7 */
71         { LPC_GPIO_0_9, LPC_IO_DIGITAL },  /* B8 */
72         { LPC_GPIO_0_12, LPC_IO_DIGITAL }, /* ISP / B5 */
73         /* GPIO */
74         { LPC_GPIO_0_0, LPC_IO_DIGITAL },  /* Clkout / interrupt from RTC */
75         { LPC_GPIO_0_15, LPC_IO_DIGITAL }, /* Buzer */
76         { LPC_GPIO_0_18, LPC_IO_DIGITAL }, /* WS2812B Leds */
77         { LPC_GPIO_0_29, LPC_IO_DIGITAL }, /* Charging state */
78         { LPC_GPIO_1_0, LPC_IO_DIGITAL }, /* SD Card Chip select */
79         { LPC_GPIO_1_1, LPC_IO_DIGITAL }, /* Oled Ctrl */
80         { LPC_GPIO_1_2, LPC_IO_DIGITAL }, /* Oled Chip select */
81         /* Debug */
82         /* FIXME : SWDIO and SWCLK on PIO0_25 and PIO0_26 */
83         /* ADC */
84         { LPC_ADC_AD0_PIO_0_30, LPC_IO_ANALOG },  /* ADC0 */
85         { LPC_ADC_AD1_PIO_0_31, LPC_IO_ANALOG },  /* ADC1 */
86         ARRAY_LAST_PIO,
87 };
89 const struct pio status_led_green = LPC_GPIO_0_27;
90 const struct pio status_led_red = LPC_GPIO_0_28;
94 /***************************************************************************** */
95 /* Basic system init and configuration */
97 void system_init()
98 {
99         /* Stop the Watchdog */
100         startup_watchdog_disable(); /* Do it right now, before it gets a chance to break in */
101         system_set_default_power_state();
102         clock_config(SELECTED_FREQ);
103         set_pins(common_pins);
104         gpio_on();
105         status_led_config(&status_led_green, &status_led_red);
106         /* System tick timer MUST be configured and running in order to use the sleeping
107          * functions */
108         systick_timer_on(1); /* 1ms */
109         systick_start();
112 /* Define our fault handler. This one is not mandatory, the dummy fault handler
113  * will be used when it's not overridden here.
114  * Note : The default one does a simple infinite loop. If the watchdog is deactivated
115  * the system will hang.
116  */
117 void fault_info(const char* name, uint32_t len)
119         uprintf(UART0, name);
120         while (1);
124 /***************************************************************************** */
125 /* Oled Display */
126 static uint8_t gddram[ 4 + GDDRAM_SIZE ];
127 struct oled_display display = {
128         .bus_type = SSD130x_BUS_SPI,
129         .bus_num = SSP_BUS_0,
130         .charge_pump = SSD130x_INTERNAL_PUMP,
131         .video_mode = SSD130x_DISP_NORMAL,
132         .contrast = 128,
133         .scan_dir = SSD130x_SCAN_BOTTOM_TOP,
134         .read_dir = SSD130x_RIGHT_TO_LEFT,
135         .display_offset_dir = SSD130x_MOVE_TOP,
136         .display_offset = 4,
137         .gddram = gddram,
138         .gpio_cs = LPC_GPIO_1_2,
139         .gpio_dc = LPC_GPIO_1_1,
140         .gpio_rst = LPC_GPIO_1_3,
141 };
143 #define ROW(x)   VERTICAL_REV(x)
144 DECLARE_FONT(font);
146 void display_char(uint8_t line, uint8_t col, uint8_t c)
148         uint8_t tile = (c > FIRST_FONT_CHAR) ? (c - FIRST_FONT_CHAR) : 0;
149         uint8_t* tile_data = (uint8_t*)(&font[tile]);
150         ssd130x_buffer_set_tile(gddram, col, line, tile_data);
152 int display_line(uint8_t line, uint8_t col, char* text)
154         int len = strlen((char*)text);
155         int i = 0;
157         for (i = 0; i < len; i++) {
158                 uint8_t tile = (text[i] > FIRST_FONT_CHAR) ? (text[i] - FIRST_FONT_CHAR) : 0;
159                 uint8_t* tile_data = (uint8_t*)(&font[tile]);
160                 ssd130x_buffer_set_tile(gddram, col++, line, tile_data);
161                 if (col >= (SSD130x_NB_COL / 8)) {
162                         col = 0;
163                         line++;
164                         if (line >= SSD130x_NB_PAGES) {
165                                 return i;
166                         }
167                 }
168         }
169         return len;
172 /***************************************************************************** */
173 /* Communication over USB */
174 uint8_t text_received = 0;
175 #define NB_CHARS  15
176 char inbuff[NB_CHARS + 1];
177 void data_rx(uint8_t c)
179         static int idx = 0;
180         if ((c != 0) && (c != '\n') && (c != '\r')) {
181                 inbuff[idx++] = c;
182                 if (idx >= NB_CHARS) {
183                         inbuff[NB_CHARS] = 0;
184                         idx = 0;
185                         text_received = 1;
186                 }
187         } else {
188                 if (idx != 0) {
189                         inbuff[idx] = 0;
190                         text_received = 1;
191                 }
192                 idx = 0;
193         }
197 const struct pio sd_cs = LPC_GPIO_1_0;
198 /***************************************************************************** */
199 int main(void)
201         int ret = 0;
202         system_init();
204         uart_on(UART0, 115200, data_rx);
205         ssp_master_on(SSP_BUS_0, LPC_SSP_FRAME_SPI, 8, 4*1000*1000);
207         status_led(green_only);
209         config_gpio(&sd_cs, 0, GPIO_DIR_OUT, 1);
211         /* Configure and start display */
212         ret = ssd130x_display_on(&display);
213         uprintf(UART0, "display on : %d\n", ret);
214         /* Erase screen with lines, makes it easier to know things are going right */
215         ssd130x_buffer_set(gddram, 0x10);
216         ret = ssd130x_display_full_screen(&display);
217         uprintf(UART0, "full screen : %d\n", ret);
219         while (1) {
220                 chenillard(500);
221                 if (text_received != 0) {
222                         display_line(2, 1, inbuff);
223                         ret = ssd130x_display_full_screen(&display);
224                         if (ret != 0) {
225                                 uprintf(UART0, "Display update error: %d\n", ret);
226                         } else {
227                                 uprintf(UART0, "Display updated.\n");
228                         }
229                         text_received = 0;
230                 }
231         }
232         return 0;