Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
MAX7456.c
00001 /**************************************************************************** 00002 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd 00003 * 00004 * This file is part of the Satellite Observers Workbench (SOWB). 00005 * 00006 * SOWB is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * SOWB is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with SOWB. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ 00020 * 00021 ***************************************************************************/ 00022 00023 /* 00024 Design notes. 00025 The MAX7456 is connected to SSP1 on the Mbed. Additionally, the vertical sync 00026 is connected to Pxx, horizontal sync to Pxx, LOS to Pxx, RST to Pxx. These IO 00027 pins are setup and macros made available via gpio.c and the interrupts (vsync) 00028 via gpioirq.c so for information regarding those see those modules. 00029 */ 00030 00031 #include "sowb.h" 00032 #include "gpio.h" 00033 #include "gpioirq.h" 00034 #include "utils.h" 00035 #include "user.h" 00036 #include "MAX7456.h" 00037 #include "MAX7456_chars.h" 00038 #include "debug.h" 00039 00040 /* Forward local function prototypes. */ 00041 static void SSP1_init(void); 00042 00043 /* Declare the custom character map (CM) definitions. 00044 See MAX7456_chars.c for more details. */ 00045 extern MAX7456_CUSTOM_CHAR custom_chars[]; 00046 00047 /* Map ASCII table to the MAX7456 character map. 00048 Note, the MAX7456 in-built character map is no where near the ascii 00049 table mapping and very few characters are abailable to map. Where 00050 possible we create new characters for those we need that are missing 00051 from the MAX7456 that we want to use and also we create some special 00052 characters of our own that are not ASCII chars (crosshair for example). 00053 These additional character definitions are listed below the table. 00054 Character maps we have create can be found in MAX7456_chars.c */ 00055 const unsigned char MAX7456_ascii[256] = { 00056 00057 /* Regular ASCII table. */ 00058 /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ 00059 /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00060 /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00061 /* 20 */ 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x46, 0x3F, 0x40, 0x00, 0x4d, 0x45, 0x49, 0x41, 0x47, 00062 /* 30 */ 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x44, 0x43, 0x4A, 0x00, 0x4B, 0x42, 00063 /* 40 */ 0x4C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 00064 /* 50 */ 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0X1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 00065 /* 60 */ 0x46, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 00066 /* 70 */ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 00067 00068 /* Extended ASCII table. */ 00069 /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ 00070 /* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00071 /* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00072 /* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00073 /* B0 */ 0xB0, 0x00, 0x00, 0xB3, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 00074 /* C0 */ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00075 /* D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 00076 /* E0 */ 0xe0, 0xe1, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00077 /* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00078 }; 00079 00080 /** MAX7456_map_char 00081 * 00082 * Convert the supplied ASCII character to a MAX7456 character. 00083 * Note, the MAX7456 does not support all ASCII chars. Those it 00084 * cannot convert are converted to spaces. Proceedure is a simple 00085 * table look-up. 00086 * 00087 * @See const unsigned char MAX7456_ascii 00088 * 00089 * @param unsigned char c The character to convert. 00090 * @return unsigned char The converted character. 00091 */ 00092 unsigned char MAX7456_map_char(unsigned char c) { 00093 return MAX7456_ascii[c]; 00094 } 00095 00096 /** MAX7456_init 00097 */ 00098 void MAX7456_init(void) { 00099 00100 /* Setup SSP1 to interface to the MAX7456 chip. */ 00101 SSP1_init(); 00102 00103 DEBUG_INIT_START; 00104 00105 /* Reset the MAX7456 device. */ 00106 MAX7456_RST_ASSERT; 00107 user_wait_ms_blocking(100); 00108 MAX7456_RST_DEASSERT; 00109 user_wait_ms_blocking(100); 00110 00111 /* Write the custom CM map. */ 00112 MAX7456_write_byte(0, MAX7456_read_byte(0) & 0xF7); 00113 for (int index = 0; custom_chars[index].ascii != 0; index++) { 00114 MAX7456_write_char_map(custom_chars[index].ascii, custom_chars[index].map); 00115 } 00116 user_wait_ms_blocking(100); 00117 00118 /* Change the vertical offset. */ 00119 MAX7456_write_byte(0x3, 0x16); 00120 00121 /* Enable display of OSD image. */ 00122 MAX7456_write_byte(0x0, 0x48); 00123 00124 DEBUG_INIT_END; 00125 } 00126 00127 /** MAX7456_vsync_fall 00128 * 00129 * Interrupt handler for the vertical sync signal from the MAX7456 chip. 00130 * Note, this is called from gpioirq.c module which handles GPIO interrupts. 00131 */ 00132 void osd_vsync(void); 00133 void MAX7456_vsync_fall(void) { 00134 osd_vsync(); 00135 } 00136 00137 /** MAX7456_vsync_rise 00138 * 00139 * Interrupt handler for the vertical sync signal from the MAX7456 chip. 00140 * Note, this is called from gpioirq.c module which handles GPIO interrupts. 00141 */ 00142 void MAX7456_vsync_rise(void) { 00143 // Does nothing. 00144 } 00145 00146 /** MAX7456_write_byte 00147 * 00148 * Used to write a byte to a specific address. 00149 * This function also doubles up to allow a byte 00150 * to be written without an address (less than 0x80) 00151 * and this is used to make 16bit transfer from two 00152 * 8bit transfers or to construct continuous 8bit 00153 * transfer where the MAX7456 auto-increments an 00154 * internal location pointer on each write operation. 00155 * 00156 * Note, this function effectivly "blocks". However, the 00157 * speed of the SSP serial bus is pretty high to say the 00158 * least and experimentation has show it, so far, to have 00159 * had no adverse effects. 00160 * 00161 * @param unsigned char address The register address to write to. 00162 * @param unsigned char byte The byte to write to teh register. 00163 */ 00164 void MAX7456_write_byte(unsigned char address, unsigned char byte) { 00165 volatile int dev_null __attribute__((unused)); 00166 00167 MAX7456_CS_ASSERT; 00168 00169 /* MAX7456 addresses are always less than 0x80 so if the 00170 address is > 0x7F then the caller is requesting an direct 00171 8bit data transfer. */ 00172 if (address < 0x80) { 00173 LPC_SSP1->DR = (uint32_t)(address & 0xFF); 00174 while(LPC_SSP1->SR & 0x10); 00175 dev_null = LPC_SSP1->DR; 00176 } 00177 00178 LPC_SSP1->DR = (uint32_t)byte & 0xFF; 00179 while(LPC_SSP1->SR & 0x10); 00180 dev_null = LPC_SSP1->DR; 00181 00182 MAX7456_CS_DEASSERT; 00183 } 00184 00185 /** MAX7456_read_byte 00186 * 00187 * Read a byte from a specific address. 00188 * 00189 * Note, this function effectivly "blocks". However, the 00190 * speed of the SSP serial bus is pretty high to say the 00191 * least and experimentation has show it, so far, to have 00192 * had no adverse effects. 00193 * 00194 * @param unsigned char address The address of the register to read. 00195 * @return int data The value of the register addressed. 00196 */ 00197 int MAX7456_read_byte(unsigned char address) { 00198 int data; 00199 00200 MAX7456_CS_ASSERT; 00201 00202 LPC_SSP1->DR = (uint32_t)address & 0xFF; 00203 while(LPC_SSP1->SR & 0x10); 00204 data = LPC_SSP1->DR; /* Discarded. */ 00205 00206 LPC_SSP1->DR = 0; 00207 while(LPC_SSP1->SR & 0x10); 00208 data = LPC_SSP1->DR & 0xFF; 00209 00210 MAX7456_CS_DEASSERT; 00211 00212 return data; 00213 } 00214 00215 /** MAX7456_cursor 00216 * 00217 * Move the MAX7456 "cursor" (next display memory write) 00218 * to the specified position. 00219 * 00220 * @param int x The X position. 00221 * @param int y The Y position. 00222 */ 00223 void MAX7456_cursor(int x, int y) { 00224 int pos = (y * 30) + x; 00225 MAX7456_write_byte(0x05, (unsigned char)((pos >> 8) & 0xFF)); 00226 MAX7456_write_byte(0x06, (unsigned char)(pos & 0xFF)); 00227 } 00228 00229 /** MAX7456_convert_string 00230 * 00231 * Convert the NULL terminated raw string to MAX7456 character set compat bytes. 00232 * Note, alters the string passed, doesn't make a copy of the string so cannot 00233 * be a const value. 00234 * 00235 * @param unisgned char *s A pointer to the string to convert. 00236 */ 00237 void MAX7456_convert_string(unsigned char *s) { 00238 while(*(s)) { 00239 *(s) = MAX7456_ascii[*(s)]; 00240 s++; 00241 } 00242 } 00243 00244 /** MAX7456_string 00245 * 00246 * Send the NULL terminated ASCII string to the display memory. 00247 * 00248 * @param unisgned char *s A pointer to the ASCII string to write. 00249 */ 00250 void MAX7456_string(unsigned char *s) { 00251 MAX7456_write_byte(0x04, 0x01); /* Enable 8bit write */ 00252 while(*(s)) { 00253 MAX7456_write_byte(0x80, MAX7456_map_char(*s++)); 00254 } 00255 MAX7456_write_byte(0x80, 0xFF); 00256 } 00257 00258 /** MAX7456_stringl 00259 * 00260 * Send the ASCII string to the display memory. A null will terminate the write. 00261 * 00262 * @param int x The X position to write the string to. 00263 * @param int y The Y position to write the string to. 00264 * @param unisgned char *s A pointer to the string to write. 00265 * @param int len The length of the string to send. 00266 */ 00267 void MAX7456_stringl(int x, int y, unsigned char *s, int len) { 00268 MAX7456_cursor(x, y); 00269 MAX7456_write_byte(0x04, 0x01); /* Enable 8bit write */ 00270 while(len--) { 00271 if (*s == '\0') break; 00272 MAX7456_write_byte(0x80, MAX7456_map_char(*s++)); 00273 } 00274 MAX7456_write_byte(0x80, 0xFF); 00275 } 00276 00277 /** MAX7456_read_char_map 00278 * 00279 * Reads the 54byte character make-up bytes and stores them into a buffer. 00280 * 00281 */ 00282 void MAX7456_read_char_map(unsigned char address, unsigned char *data54) { 00283 MAX7456_write_byte(0x9, address); 00284 MAX7456_write_byte(0x8, 0x50); 00285 user_wait_ms_blocking(100); 00286 for (int index = 0; index < 54; index++) { 00287 MAX7456_write_byte(0xA, index); 00288 user_wait_ms_blocking(1); 00289 *(data54 + index) = MAX7456_read_byte(0xC0); 00290 } 00291 } 00292 00293 /** MAX7456_write_char_map 00294 * 00295 * Used to write the 54bytes that make up a character into 00296 * the MAX7456 CM non-volatile memory. Note, it tests the 00297 * current non-v memory against the supplied buffer and only 00298 * writes the buffer out if they don't match. Used to ensure 00299 * we don't keep writing the same data into non-v memory which 00300 * has a "lifetime" associated with it. 00301 * 00302 * @param unsigned char address The character address we are writing. 00303 * @param unsigned char *data54 An array that contains the 54bytes of CM data. 00304 */ 00305 void MAX7456_write_char_map(unsigned char address, const unsigned char *data54) { 00306 unsigned char index, c, match = 1; 00307 00308 MAX7456_write_byte(0x9, address); 00309 MAX7456_write_byte(0x8, 0x50); 00310 user_wait_ms_blocking(20); 00311 for (index = 0; index < 54; index++) { 00312 MAX7456_write_byte(0xA, index); 00313 c = MAX7456_read_byte(0xC0); 00314 if (c != data54[index]) { 00315 match = 0; 00316 break; 00317 } 00318 } 00319 00320 if (!match) { 00321 MAX7456_write_byte(0x9, address); 00322 for (index = 0; index < 0x36; index++) { 00323 MAX7456_write_byte(0x0A, index); 00324 MAX7456_write_byte(0x0B, data54[index]); 00325 } 00326 MAX7456_write_byte(0x08, 0xA0); 00327 user_wait_ms_blocking(20); 00328 while ((MAX7456_read_byte(0xA0) & 0x20) != 0x00); 00329 } 00330 } 00331 00332 /** SSP1_init 00333 */ 00334 static void SSP1_init(void) { 00335 00336 DEBUG_INIT_START; 00337 00338 /* The MAX7456 device is connected to SSP1 via the Mbed pins. 00339 So this init is about configuring just the SSP1, other 00340 MAX7456 signals (vsync, etc) are setup elsewhere although 00341 make call backs to this module as the "clearing house" for 00342 MAX7456 signals. */ 00343 00344 /* Enable the SSP1 peripheral. */ 00345 LPC_SC->PCONP |= (1UL << 10); 00346 00347 /* Select the clock required for SSP1. */ 00348 LPC_SC->PCLKSEL0 &= ~(3UL << 20); 00349 LPC_SC->PCLKSEL0 |= (3UL << 20); 00350 00351 /* Select the GPIO pins for the SSP1 functions. */ 00352 /* SCK1 */ 00353 LPC_PINCON->PINSEL0 &= ~(3UL << 14); 00354 LPC_PINCON->PINSEL0 |= (2UL << 14); 00355 /* MISO1 */ 00356 LPC_PINCON->PINSEL0 &= ~(3UL << 16); 00357 LPC_PINCON->PINSEL0 |= (2UL << 16); 00358 /* MOSI1 */ 00359 LPC_PINCON->PINSEL0 &= ~(3UL << 18); 00360 LPC_PINCON->PINSEL0 |= (2UL << 18); 00361 00362 /* Note, we don't use SSEL1 in our design, we just use a standard GPIO 00363 because a) the MAX7456 didn't really like the speed! and b) writing 00364 16bit data is somewhat simpler than reconfiguring the SSP each time 00365 when all we need to do is hold CS low across 2 8bit operations. */ 00366 00367 /* Setup the control registers for SSP1 */ 00368 LPC_SSP1->CR0 = 0x7; 00369 LPC_SSP1->CPSR = 0x2; 00370 LPC_SSP1->CR1 = 0x2; 00371 00372 DEBUG_INIT_END; 00373 } 00374
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2