Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
 
2
#include <FastSerial.h>
3
 
4
#include "ArduCam_Max7456.h"
5
// Get the common arduino functions
6
#if defined(ARDUINO) && ARDUINO >= 100
7
        #include "Arduino.h"
8
#else
9
        #include "wiring.h"
10
#endif
11
#include "Spi.h"
12
 
13
volatile int x;
14
volatile int font_count;
15
volatile byte character_bitmap[0x40];
16
 
17
OSD::OSD()
18
{
19
}
20
 
21
//------------------ init ---------------------------------------------------
22
 
23
void OSD::init()
24
{
25
  pinMode(MAX7456_SELECT,OUTPUT);
26
  pinMode(MAX7456_VSYNC, INPUT);
27
  digitalWrite(MAX7456_VSYNC,HIGH); //enabling pull-up resistor
28
 
29
  detectMode();
30
 
31
  digitalWrite(MAX7456_SELECT,LOW);
32
  //read black level register
33
  Spi.transfer(MAX7456_OSDBL_reg_read);//black level read register
34
  byte osdbl_r = Spi.transfer(0xff);
35
  Spi.transfer(MAX7456_VM0_reg);
36
  Spi.transfer(MAX7456_RESET | video_mode);
37
  delay(50);
38
  //set black level
39
  byte osdbl_w = (osdbl_r & 0xef); //Set bit 4 to zero 11101111
40
  Spi.transfer(MAX7456_OSDBL_reg); //black level write register
41
  Spi.transfer(osdbl_w);
42
 
43
  // set all rows to same charactor white level, 90%
44
  for (x = 0; x < MAX7456_screen_rows; x++)
45
  {
46
    Spi.transfer(x + 0x10);
47
    Spi.transfer(MAX7456_WHITE_level_120);
48
  }
49
  // define sync (auto,int,ext) and
50
  // making sure the Max7456 is enabled
51
  control(1);
52
}
53
 
54
//------------------ Detect Mode (PAL/NTSC) ---------------------------------
55
 
56
void OSD::detectMode()
57
{
58
  digitalWrite(MAX7456_SELECT,LOW);
59
  //read STAT and auto detect Mode PAL/NTSC
60
  Spi.transfer(MAX7456_STAT_reg_read);//status register
61
  byte osdstat_r = Spi.transfer(0xff);
62
 
63
  if ((B00000001 & osdstat_r) == 1){
64
    setMode(1);  
65
  }
66
  else if((B00000010 & osdstat_r) == 1){
67
    setMode(0);
68
  }
69
#ifdef MinimOSD
70
  else if (digitalRead(3) == 1){
71
    setMode(1);
72
  }
73
#endif
74
  else setMode(0);
75
  digitalWrite(MAX7456_SELECT,LOW);
76
}
77
 
78
//------------------ Set Mode (PAL/NTSC) ------------------------------------
79
 
80
void OSD::setMode(int themode)
81
{
82
  switch(themode){
83
    case 0:
84
      video_mode = MAX7456_MODE_MASK_NTCS;
85
      video_center = MAX7456_CENTER_NTSC;
86
      break;
87
    case 1:
88
      video_mode = MAX7456_MODE_MASK_PAL;
89
      video_center = MAX7456_CENTER_PAL;
90
      break;
91
  }
92
}
93
 
94
//------------------ Get Mode (PAL 0/NTSC 1) --------------------------------
95
 
96
int OSD::getMode()
97
{
98
  switch(video_mode){
99
    case MAX7456_MODE_MASK_NTCS:
100
      return 0;
101
      break;
102
    case MAX7456_MODE_MASK_PAL:
103
      return 1;
104
      break;
105
  }
106
  return 0;
107
}
108
 
109
//------------------ Get Center (PAL/NTSC) ----------------------------------
110
 
111
int OSD::getCenter()
112
{
113
  return video_center; //first line for center panel
114
}
115
 
116
//------------------ plug ---------------------------------------------------
117
 
118
void OSD::plug()
119
{
120
  digitalWrite(MAX7456_SELECT,LOW);
121
}
122
 
123
//------------------ clear ---------------------------------------------------
124
 
125
void OSD::clear()
126
{
127
  // clear the screen
128
  digitalWrite(MAX7456_SELECT,LOW);
129
  Spi.transfer(MAX7456_DMM_reg);
130
  Spi.transfer(MAX7456_CLEAR_display);
131
  digitalWrite(MAX7456_SELECT,HIGH);
132
}
133
 
134
//------------------ set panel -----------------------------------------------
135
 
136
void
137
OSD::setPanel(uint8_t st_col, uint8_t st_row){
138
  start_col = st_col;
139
  start_row = st_row;
140
  col = st_col;
141
  row = st_row;
142
}
143
 
144
//------------------ open panel ----------------------------------------------
145
 
146
void
147
OSD::openPanel(void){
148
  unsigned int linepos;
149
  byte settings, char_address_hi, char_address_lo;
150
 
151
  //find [start address] position
152
  linepos = row*30+col;
153
 
154
  // divide 16 bits into hi & lo byte
155
  char_address_hi = linepos >> 8;
156
  char_address_lo = linepos;
157
 
158
  //Auto increment turn writing fast (less SPI commands).
159
  //No need to set next char address. Just send them
160
  settings = MAX7456_INCREMENT_auto; //To Enable DMM Auto Increment
161
  digitalWrite(MAX7456_SELECT,LOW);
162
  Spi.transfer(MAX7456_DMM_reg); //dmm
163
  Spi.transfer(settings);
164
 
165
  Spi.transfer(MAX7456_DMAH_reg); // set start address high
166
  Spi.transfer(char_address_hi);
167
 
168
  Spi.transfer(MAX7456_DMAL_reg); // set start address low
169
  Spi.transfer(char_address_lo);
170
  //Serial.printf("setPos -> %d %d\n", col, row);
171
}
172
 
173
//------------------ close panel ---------------------------------------------
174
 
175
void
176
OSD::closePanel(void){  
177
  Spi.transfer(MAX7456_DMDI_reg);
178
  Spi.transfer(MAX7456_END_string); //This is needed "trick" to finish auto increment
179
  digitalWrite(MAX7456_SELECT,HIGH);
180
  //Serial.println("close");
181
  row++; //only after finish the auto increment the new row will really act as desired
182
}
183
 
184
//------------------ write single char ---------------------------------------------
185
 
186
void
187
OSD::openSingle(uint8_t x, uint8_t y){
188
  unsigned int linepos;
189
  byte char_address_hi, char_address_lo;
190
 
191
  //find [start address] position
192
  linepos = y*30+x;
193
 
194
  // divide 16 bits into hi & lo byte
195
  char_address_hi = linepos >> 8;
196
  char_address_lo = linepos;
197
 
198
  digitalWrite(MAX7456_SELECT,LOW);
199
 
200
  Spi.transfer(MAX7456_DMAH_reg); // set start address high
201
  Spi.transfer(char_address_hi);
202
 
203
  Spi.transfer(MAX7456_DMAL_reg); // set start address low
204
  Spi.transfer(char_address_lo);
205
  //Serial.printf("setPos -> %d %d\n", col, row);
206
}
207
 
208
//------------------ write ---------------------------------------------------
209
 
210
size_t
211
OSD::write(uint8_t c){
212
  if(c == '|'){
213
    closePanel(); //It does all needed to finish auto increment and change current row
214
    openPanel(); //It does all needed to re-enable auto increment
215
  }
216
  else{
217
    Spi.transfer(MAX7456_DMDI_reg);
218
    Spi.transfer(c);
219
  }
220
  return 1;
221
}
222
 
223
//---------------------------------
224
 
225
void
226
OSD::control(uint8_t ctrl){
227
  digitalWrite(MAX7456_SELECT,LOW);
228
  Spi.transfer(MAX7456_VM0_reg);
229
  switch(ctrl){
230
    case 0:
231
      Spi.transfer(MAX7456_DISABLE_display | video_mode);
232
      break;
233
    case 1:
234
      //Spi.transfer((MAX7456_ENABLE_display_vert | video_mode) | MAX7456_SYNC_internal);
235
      //Spi.transfer((MAX7456_ENABLE_display_vert | video_mode) | MAX7456_SYNC_external);
236
      Spi.transfer((MAX7456_ENABLE_display_vert | video_mode) | MAX7456_SYNC_autosync);
237
      break;
238
  }
239
  digitalWrite(MAX7456_SELECT,HIGH);
240
}
241
 
242
void
243
OSD::write_NVM(int font_count, uint8_t *character_bitmap)
244
{
245
  byte x;
246
  byte char_address_hi, char_address_lo;
247
  byte screen_char;
248
 
249
  char_address_hi = font_count;
250
  char_address_lo = 0;
251
 //Serial.println("write_new_screen");   
252
 
253
  // disable display
254
  digitalWrite(MAX7456_SELECT,LOW);
255
  Spi.transfer(MAX7456_VM0_reg);
256
  Spi.transfer(MAX7456_DISABLE_display);
257
 
258
  Spi.transfer(MAX7456_CMAH_reg); // set start address high
259
  Spi.transfer(char_address_hi);
260
 
261
  for(x = 0; x < NVM_ram_size; x++) // write out 54 (out of 64) bytes of character to shadow ram
262
  {
263
    screen_char = character_bitmap[x];
264
    Spi.transfer(MAX7456_CMAL_reg); // set start address low
265
    Spi.transfer(x);
266
    Spi.transfer(MAX7456_CMDI_reg);
267
    Spi.transfer(screen_char);
268
  }
269
 
270
  // transfer a 54 bytes from shadow ram to NVM
271
  Spi.transfer(MAX7456_CMM_reg);
272
  Spi.transfer(WRITE_nvr);
273
 
274
  // wait until bit 5 in the status register returns to 0 (12ms)
275
  while ((Spi.transfer(MAX7456_STAT_reg_read) & STATUS_reg_nvr_busy) != 0x00);
276
 
277
  Spi.transfer(MAX7456_VM0_reg); // turn on screen next vertical
278
  Spi.transfer(MAX7456_ENABLE_display_vert);
279
  digitalWrite(MAX7456_SELECT,HIGH);  
280
}
281
 
282
//------------------ pure virtual ones (just overriding) ---------------------
283
 
284
int  OSD::available(void){
285
        return 0;
286
}
287
int  OSD::read(void){
288
        return 0;
289
}
290
int  OSD::peek(void){
291
        return 0;
292
}
293
void OSD::flush(void){
294
}
295