Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
// Code to copy a MCM font file to the Arduino + Max7456 OSD
2
//
3
// MAX7456_font Sketch
4
// at 9600 baud it take about 3min to download a mcm file
5
// http://www.maxim-ic.com/tools/evkit/index.cfm?EVKit=558
6
// max7456 evaluation kit software
7
 
8
#define DATAOUT 11//11-MOSI
9
#define DATAIN  12//12-MISO
10
#define SPICLOCK  13//13-sck
11
#define MAX7456SELECT 6 //6
12
#define USBSELECT 10//10-ss
13
#define VSYNC 2// INT0
14
 
15
//MAX7456 opcodes
16
#define VM0_reg   0x00
17
#define VM1_reg   0x01
18
#define DMM_reg   0x04
19
#define DMAH_reg  0x05
20
#define DMAL_reg  0x06
21
#define DMDI_reg  0x07
22
#define CMM_reg   0x08
23
#define CMAH_reg  0x09
24
#define CMAL_reg  0x0A
25
#define CMDI_reg  0x0B
26
#define STAT_reg  0xA0
27
 
28
//MAX7456 commands
29
#define CLEAR_display 0x04
30
#define CLEAR_display_vert 0x06
31
#define END_string 0xff
32
#define WRITE_nvr 0xa0
33
// with NTSC
34
#define ENABLE_display 0x08
35
#define ENABLE_display_vert 0x0c
36
#define MAX7456_reset 0x02
37
#define DISABLE_display 0x00
38
 
39
// with PAL
40
// all VM0_reg commands need bit 6 set
41
//#define ENABLE_display 0x48
42
//#define ENABLE_display_vert 0x4c
43
//#define MAX7456_reset 0x42
44
//#define DISABLE_display 0x40
45
 
46
#define WHITE_level_80 0x03
47
#define WHITE_level_90 0x02
48
#define WHITE_level_100 0x01
49
#define WHITE_level_120 0x00
50
 
51
#define MAX_font_rom 0xff
52
#define STATUS_reg_nvr_busy 0x20
53
#define NVM_ram_size 0x36
54
 
55
// with NTSC
56
#define MAX_screen_rows 0x0d //13
57
 
58
// with PAL
59
//#define MAX_screen_rows 0x10 //16
60
 
61
volatile byte screen_buffer[MAX_font_rom];
62
volatile byte character_bitmap[0x40];
63
volatile byte ascii_binary[0x08];
64
 
65
volatile byte bit_count;
66
volatile byte byte_count;
67
volatile int font_count;
68
volatile int  incomingByte;
69
volatile int  count;
70
 
71
 
72
//////////////////////////////////////////////////////////////
73
void setup()
74
{
75
  byte spi_junk;
76
  int x;
77
  Serial.begin(38400);
78
  Serial.flush();
79
 
80
  digitalWrite(USBSELECT,HIGH); //disable USB chip
81
 
82
  pinMode(MAX7456SELECT,OUTPUT);
83
  digitalWrite(MAX7456SELECT,HIGH); //disable device
84
 
85
  pinMode(DATAOUT, OUTPUT);
86
  pinMode(DATAIN, INPUT);
87
  pinMode(SPICLOCK,OUTPUT);
88
  pinMode(VSYNC, INPUT);
89
 
90
  // SPCR = 01010000
91
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
92
  //sample on leading edge of clk,system clock/4 rate (4 meg)
93
  SPCR = (1<<SPE)|(1<<MSTR);
94
  spi_junk=SPSR;
95
  spi_junk=SPDR;
96
  delay(250);
97
 
98
  // force soft reset on Max7456
99
  digitalWrite(MAX7456SELECT,LOW);
100
  spi_transfer(VM0_reg);
101
  spi_transfer(MAX7456_reset);
102
  digitalWrite(MAX7456SELECT,HIGH);
103
  delay(500);
104
 
105
  // set all rows to same character white level, 90%
106
  digitalWrite(MAX7456SELECT,LOW);
107
  for (x = 0; x < MAX_screen_rows; x++)
108
  {
109
    spi_transfer(x + 0x10);
110
    spi_transfer(WHITE_level_90);
111
  }
112
 
113
  // make sure the Max7456 is enabled
114
  spi_transfer(VM0_reg);
115
  spi_transfer(ENABLE_display);
116
  digitalWrite(MAX7456SELECT,HIGH);
117
 
118
  incomingByte = 0;
119
  count = 0;
120
  bit_count = 0;
121
  byte_count = 0;
122
  font_count = 0;
123
 
124
  //display all 256 internal MAX7456 characters
125
  for (x = 0; x < MAX_font_rom; x++)
126
  {
127
    screen_buffer[x] = x;
128
  }
129
   count = MAX_font_rom;
130
   write_new_screen();
131
 
132
  Serial.println("Ready for text file download");
133
  Serial.println("");
134
  delay(100);
135
}
136
 
137
//////////////////////////////////////////////////////////////
138
void loop()
139
{
140
  byte x;
141
 
142
  if (Serial.available() > 0)
143
  {
144
    // read the incoming byte:
145
    incomingByte = Serial.read();
146
 
147
    switch(incomingByte) // parse and decode mcm file
148
    {
149
      case 0x0d: // carridge return, end of line
150
        //Serial.println("cr");
151
       if (bit_count == 8 && (ascii_binary[0] == 0x30 || ascii_binary[0] == 0x31))
152
       {
153
          // turn 8 ascii binary bytes to single byte '01010101' = 0x55
154
          // fill in 64 bytes of character data
155
         character_bitmap[byte_count] = decode_ascii_binary();
156
         byte_count++;
157
         bit_count = 0;
158
       }
159
       else
160
         bit_count = 0;
161
      break;
162
      case 0x0a: // line feed, ignore
163
        //Serial.println("ln");
164
      break;
165
      case 0x30: // ascii '0'
166
      case 0x31: // ascii '1'
167
        ascii_binary[bit_count] = incomingByte;
168
        bit_count++;
169
      break;
170
      default:
171
      break;
172
    }
173
  }
174
 
175
  // we have one completed character
176
  // write the character to NVM
177
  if(byte_count == 64)
178
  {
179
    write_NVM();
180
    byte_count = 0;
181
    font_count++;
182
  }
183
 
184
  // we have burned all 256 characters in NVM
185
  if(font_count == 256)
186
  {
187
    font_count = 0;
188
 
189
    // force soft reset on Max7456
190
    digitalWrite(MAX7456SELECT,LOW);
191
    spi_transfer(VM0_reg);
192
    spi_transfer(MAX7456_reset);
193
    digitalWrite(MAX7456SELECT,HIGH);
194
    delay(500);
195
 
196
   // display all 256 new internal MAX7456 characters
197
   for (x = 0; x < MAX_font_rom; x++)
198
   {
199
      screen_buffer[x] = x;
200
   }
201
    count = MAX_font_rom;
202
    write_new_screen();
203
 
204
    Serial.println("");
205
    Serial.println("Done with file download");
206
  }
207
}
208
 
209
//////////////////////////////////////////////////////////////
210
byte spi_transfer(volatile byte data)
211
{
212
  SPDR = data;                    // Start the transmission
213
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
214
  {
215
  };
216
  return SPDR;                    // return the received byte
217
}
218
 
219
//////////////////////////////////////////////////////////////
220
void write_new_screen()
221
{
222
  int x, local_count;
223
  byte char_address_hi, char_address_lo;
224
  byte screen_char;
225
 
226
  local_count = count;
227
 
228
  char_address_hi = 0;
229
  char_address_lo = 60; // start on third line
230
 //Serial.println("write_new_screen");
231
 
232
  // clear the screen
233
  digitalWrite(MAX7456SELECT,LOW);
234
  spi_transfer(DMM_reg);
235
  spi_transfer(CLEAR_display);
236
  digitalWrite(MAX7456SELECT,HIGH);
237
 
238
  // disable display
239
  digitalWrite(MAX7456SELECT,LOW);
240
  spi_transfer(VM0_reg);
241
  spi_transfer(DISABLE_display);
242
 
243
  spi_transfer(DMM_reg); //dmm
244
  //spi_transfer(0x21); //16 bit trans background
245
  spi_transfer(0x01); //16 bit trans w/o background
246
 
247
  spi_transfer(DMAH_reg); // set start address high
248
  spi_transfer(char_address_hi);
249
 
250
  spi_transfer(DMAL_reg); // set start address low
251
  spi_transfer(char_address_lo);
252
 
253
  x = 0;
254
  while(local_count) // write out full screen
255
  {
256
    screen_char = screen_buffer[x];
257
    spi_transfer(DMDI_reg);
258
    spi_transfer(screen_char);
259
    x++;
260
    local_count--;
261
  }
262
 
263
  spi_transfer(DMDI_reg);
264
  spi_transfer(END_string);
265
 
266
  spi_transfer(VM0_reg); // turn on screen next vertical
267
  spi_transfer(ENABLE_display_vert);
268
  digitalWrite(MAX7456SELECT,HIGH);
269
}
270
 
271
//////////////////////////////////////////////////////////////
272
byte decode_ascii_binary()
273
{
274
  byte ascii_byte;
275
 
276
  ascii_byte = 0;
277
 
278
  if (ascii_binary[0] == 0x31) // ascii '1'
279
    ascii_byte = ascii_byte + 128;
280
 
281
  if (ascii_binary[1] == 0x31)
282
    ascii_byte = ascii_byte + 64;
283
 
284
  if (ascii_binary[2] == 0x31)
285
    ascii_byte = ascii_byte + 32;
286
 
287
  if (ascii_binary[3] == 0x31)
288
    ascii_byte = ascii_byte + 16;
289
 
290
  if (ascii_binary[4] == 0x31)
291
    ascii_byte = ascii_byte + 8;
292
 
293
  if (ascii_binary[5] == 0x31)
294
    ascii_byte = ascii_byte + 4;
295
 
296
  if (ascii_binary[6] == 0x31)
297
    ascii_byte = ascii_byte + 2;
298
 
299
  if (ascii_binary[7] == 0x31)
300
    ascii_byte = ascii_byte + 1;
301
 
302
  //Serial.print(ascii_byte, HEX);
303
 
304
  return(ascii_byte);
305
}
306
 
307
//////////////////////////////////////////////////////////////
308
void write_NVM()
309
{
310
  byte x;
311
  byte char_address_hi, char_address_lo;
312
  byte screen_char;
313
 
314
  char_address_hi = font_count;
315
  char_address_lo = 0;
316
 //Serial.println("write_new_screen");
317
 
318
  // disable display
319
  digitalWrite(MAX7456SELECT,LOW);
320
  spi_transfer(VM0_reg);
321
  spi_transfer(DISABLE_display);
322
 
323
  spi_transfer(CMAH_reg); // set start address high
324
  spi_transfer(char_address_hi);
325
 
326
  for(x = 0; x < NVM_ram_size; x++) // write out 54 (out of 64) bytes of character to shadow ram
327
  {
328
    screen_char = character_bitmap[x];
329
    spi_transfer(CMAL_reg); // set start address low
330
    spi_transfer(x);
331
    spi_transfer(CMDI_reg);
332
    spi_transfer(screen_char);
333
  }
334
 
335
  // transfer a 54 bytes from shadow ram to NVM
336
  spi_transfer(CMM_reg);
337
  spi_transfer(WRITE_nvr);
338
 
339
  // wait until bit 5 in the status register returns to 0 (12ms)
340
  while ((spi_transfer(STAT_reg) & STATUS_reg_nvr_busy) != 0x00);
341
 
342
  spi_transfer(VM0_reg); // turn on screen next vertical
343
  spi_transfer(ENABLE_display_vert);
344
  digitalWrite(MAX7456SELECT,HIGH);
345
}