Cleanup. Font writer included among examples
This commit is contained in:
		
							
								
								
									
										345
									
								
								examples/WriteMCM/WriteMCM.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								examples/WriteMCM/WriteMCM.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,345 @@
 | 
			
		||||
// Code to copy a MCM font file to the Arduino + Max7456 OSD
 | 
			
		||||
//
 | 
			
		||||
// MAX7456_font Sketch
 | 
			
		||||
// at 9600 baud it take about 3min to download a mcm file
 | 
			
		||||
// http://www.maxim-ic.com/tools/evkit/index.cfm?EVKit=558
 | 
			
		||||
// max7456 evaluation kit software
 | 
			
		||||
 | 
			
		||||
#define DATAOUT 11//11-MOSI
 | 
			
		||||
#define DATAIN  12//12-MISO 
 | 
			
		||||
#define SPICLOCK  13//13-sck
 | 
			
		||||
#define MAX7456SELECT 6 //6
 | 
			
		||||
#define USBSELECT 10//10-ss
 | 
			
		||||
#define VSYNC 2// INT0
 | 
			
		||||
 | 
			
		||||
//MAX7456 opcodes
 | 
			
		||||
#define VM0_reg   0x00
 | 
			
		||||
#define VM1_reg   0x01
 | 
			
		||||
#define DMM_reg   0x04
 | 
			
		||||
#define DMAH_reg  0x05
 | 
			
		||||
#define DMAL_reg  0x06
 | 
			
		||||
#define DMDI_reg  0x07
 | 
			
		||||
#define CMM_reg   0x08
 | 
			
		||||
#define CMAH_reg  0x09
 | 
			
		||||
#define CMAL_reg  0x0A
 | 
			
		||||
#define CMDI_reg  0x0B
 | 
			
		||||
#define STAT_reg  0xA0
 | 
			
		||||
 | 
			
		||||
//MAX7456 commands
 | 
			
		||||
#define CLEAR_display 0x04
 | 
			
		||||
#define CLEAR_display_vert 0x06
 | 
			
		||||
#define END_string 0xff
 | 
			
		||||
#define WRITE_nvr 0xa0
 | 
			
		||||
// with NTSC
 | 
			
		||||
#define ENABLE_display 0x08
 | 
			
		||||
#define ENABLE_display_vert 0x0c
 | 
			
		||||
#define MAX7456_reset 0x02
 | 
			
		||||
#define DISABLE_display 0x00
 | 
			
		||||
 | 
			
		||||
// with PAL
 | 
			
		||||
// all VM0_reg commands need bit 6 set
 | 
			
		||||
//#define ENABLE_display 0x48
 | 
			
		||||
//#define ENABLE_display_vert 0x4c
 | 
			
		||||
//#define MAX7456_reset 0x42
 | 
			
		||||
//#define DISABLE_display 0x40
 | 
			
		||||
 | 
			
		||||
#define WHITE_level_80 0x03
 | 
			
		||||
#define WHITE_level_90 0x02
 | 
			
		||||
#define WHITE_level_100 0x01
 | 
			
		||||
#define WHITE_level_120 0x00
 | 
			
		||||
 | 
			
		||||
#define MAX_font_rom 0xff
 | 
			
		||||
#define STATUS_reg_nvr_busy 0x20
 | 
			
		||||
#define NVM_ram_size 0x36
 | 
			
		||||
 | 
			
		||||
// with NTSC
 | 
			
		||||
#define MAX_screen_rows 0x0d //13
 | 
			
		||||
 | 
			
		||||
// with PAL
 | 
			
		||||
//#define MAX_screen_rows 0x10 //16
 | 
			
		||||
 | 
			
		||||
volatile byte screen_buffer[MAX_font_rom];
 | 
			
		||||
volatile byte character_bitmap[0x40];
 | 
			
		||||
volatile byte ascii_binary[0x08];
 | 
			
		||||
 | 
			
		||||
volatile byte bit_count;
 | 
			
		||||
volatile byte byte_count;
 | 
			
		||||
volatile int font_count;
 | 
			
		||||
volatile int  incomingByte;
 | 
			
		||||
volatile int  count;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
void setup()
 | 
			
		||||
{
 | 
			
		||||
  byte spi_junk;
 | 
			
		||||
  int x;
 | 
			
		||||
  Serial.begin(38400);
 | 
			
		||||
  Serial.flush();
 | 
			
		||||
 | 
			
		||||
  digitalWrite(USBSELECT,HIGH); //disable USB chip
 | 
			
		||||
 | 
			
		||||
  pinMode(MAX7456SELECT,OUTPUT);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH); //disable device
 | 
			
		||||
 | 
			
		||||
  pinMode(DATAOUT, OUTPUT);
 | 
			
		||||
  pinMode(DATAIN, INPUT);
 | 
			
		||||
  pinMode(SPICLOCK,OUTPUT);
 | 
			
		||||
  pinMode(VSYNC, INPUT);
 | 
			
		||||
 | 
			
		||||
  // SPCR = 01010000
 | 
			
		||||
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
 | 
			
		||||
  //sample on leading edge of clk,system clock/4 rate (4 meg)
 | 
			
		||||
  SPCR = (1<<SPE)|(1<<MSTR);
 | 
			
		||||
  spi_junk=SPSR;
 | 
			
		||||
  spi_junk=SPDR;
 | 
			
		||||
  delay(250);
 | 
			
		||||
 | 
			
		||||
  // force soft reset on Max7456
 | 
			
		||||
  digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
  spi_transfer(VM0_reg);
 | 
			
		||||
  spi_transfer(MAX7456_reset);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH);
 | 
			
		||||
  delay(500);
 | 
			
		||||
 | 
			
		||||
  // set all rows to same character white level, 90%
 | 
			
		||||
  digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
  for (x = 0; x < MAX_screen_rows; x++)
 | 
			
		||||
  {
 | 
			
		||||
    spi_transfer(x + 0x10);
 | 
			
		||||
    spi_transfer(WHITE_level_90);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // make sure the Max7456 is enabled
 | 
			
		||||
  spi_transfer(VM0_reg);
 | 
			
		||||
  spi_transfer(ENABLE_display);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH);
 | 
			
		||||
 | 
			
		||||
  incomingByte = 0;
 | 
			
		||||
  count = 0;
 | 
			
		||||
  bit_count = 0;
 | 
			
		||||
  byte_count = 0;
 | 
			
		||||
  font_count = 0;
 | 
			
		||||
 | 
			
		||||
  //display all 256 internal MAX7456 characters
 | 
			
		||||
  for (x = 0; x < MAX_font_rom; x++)
 | 
			
		||||
  {
 | 
			
		||||
    screen_buffer[x] = x;
 | 
			
		||||
  }
 | 
			
		||||
   count = MAX_font_rom;
 | 
			
		||||
   write_new_screen();  
 | 
			
		||||
 | 
			
		||||
  Serial.println("Ready for text file download");
 | 
			
		||||
  Serial.println("");
 | 
			
		||||
  delay(100);  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
void loop()
 | 
			
		||||
{
 | 
			
		||||
  byte x;
 | 
			
		||||
  
 | 
			
		||||
  if (Serial.available() > 0)
 | 
			
		||||
  {
 | 
			
		||||
    // read the incoming byte:
 | 
			
		||||
    incomingByte = Serial.read();
 | 
			
		||||
 | 
			
		||||
    switch(incomingByte) // parse and decode mcm file
 | 
			
		||||
    {
 | 
			
		||||
      case 0x0d: // carridge return, end of line
 | 
			
		||||
        //Serial.println("cr");
 | 
			
		||||
       if (bit_count == 8 && (ascii_binary[0] == 0x30 || ascii_binary[0] == 0x31))
 | 
			
		||||
       {
 | 
			
		||||
          // turn 8 ascii binary bytes to single byte '01010101' = 0x55
 | 
			
		||||
          // fill in 64 bytes of character data
 | 
			
		||||
         character_bitmap[byte_count] = decode_ascii_binary();
 | 
			
		||||
         byte_count++;
 | 
			
		||||
         bit_count = 0;
 | 
			
		||||
       }
 | 
			
		||||
       else
 | 
			
		||||
         bit_count = 0;
 | 
			
		||||
      break;
 | 
			
		||||
      case 0x0a: // line feed, ignore
 | 
			
		||||
        //Serial.println("ln");   
 | 
			
		||||
      break;
 | 
			
		||||
      case 0x30: // ascii '0'
 | 
			
		||||
      case 0x31: // ascii '1' 
 | 
			
		||||
        ascii_binary[bit_count] = incomingByte;
 | 
			
		||||
        bit_count++;
 | 
			
		||||
      break;
 | 
			
		||||
      default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // we have one completed character
 | 
			
		||||
  // write the character to NVM 
 | 
			
		||||
  if(byte_count == 64)
 | 
			
		||||
  {
 | 
			
		||||
    write_NVM();    
 | 
			
		||||
    byte_count = 0;
 | 
			
		||||
    font_count++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // we have burned all 256 characters in NVM
 | 
			
		||||
  if(font_count == 256)
 | 
			
		||||
  {
 | 
			
		||||
    font_count = 0;
 | 
			
		||||
 | 
			
		||||
    // force soft reset on Max7456
 | 
			
		||||
    digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
    spi_transfer(VM0_reg);
 | 
			
		||||
    spi_transfer(MAX7456_reset);
 | 
			
		||||
    digitalWrite(MAX7456SELECT,HIGH);
 | 
			
		||||
    delay(500);
 | 
			
		||||
 | 
			
		||||
   // display all 256 new internal MAX7456 characters
 | 
			
		||||
   for (x = 0; x < MAX_font_rom; x++)
 | 
			
		||||
   {
 | 
			
		||||
      screen_buffer[x] = x;
 | 
			
		||||
   }
 | 
			
		||||
    count = MAX_font_rom;
 | 
			
		||||
    write_new_screen(); 
 | 
			
		||||
    
 | 
			
		||||
    Serial.println("");
 | 
			
		||||
    Serial.println("Done with file download");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
byte spi_transfer(volatile byte data)
 | 
			
		||||
{
 | 
			
		||||
  SPDR = data;                    // Start the transmission
 | 
			
		||||
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
 | 
			
		||||
  {
 | 
			
		||||
  };
 | 
			
		||||
  return SPDR;                    // return the received byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
void write_new_screen()
 | 
			
		||||
{
 | 
			
		||||
  int x, local_count;
 | 
			
		||||
  byte char_address_hi, char_address_lo;
 | 
			
		||||
  byte screen_char;
 | 
			
		||||
  
 | 
			
		||||
  local_count = count;
 | 
			
		||||
  
 | 
			
		||||
  char_address_hi = 0;
 | 
			
		||||
  char_address_lo = 60; // start on third line
 | 
			
		||||
 //Serial.println("write_new_screen");   
 | 
			
		||||
 | 
			
		||||
  // clear the screen
 | 
			
		||||
  digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
  spi_transfer(DMM_reg);
 | 
			
		||||
  spi_transfer(CLEAR_display);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH);
 | 
			
		||||
 | 
			
		||||
  // disable display
 | 
			
		||||
  digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
  spi_transfer(VM0_reg); 
 | 
			
		||||
  spi_transfer(DISABLE_display);
 | 
			
		||||
 | 
			
		||||
  spi_transfer(DMM_reg); //dmm
 | 
			
		||||
  //spi_transfer(0x21); //16 bit trans background
 | 
			
		||||
  spi_transfer(0x01); //16 bit trans w/o background
 | 
			
		||||
 | 
			
		||||
  spi_transfer(DMAH_reg); // set start address high
 | 
			
		||||
  spi_transfer(char_address_hi);
 | 
			
		||||
 | 
			
		||||
  spi_transfer(DMAL_reg); // set start address low
 | 
			
		||||
  spi_transfer(char_address_lo);
 | 
			
		||||
 | 
			
		||||
  x = 0;
 | 
			
		||||
  while(local_count) // write out full screen
 | 
			
		||||
  {
 | 
			
		||||
    screen_char = screen_buffer[x];
 | 
			
		||||
    spi_transfer(DMDI_reg);
 | 
			
		||||
    spi_transfer(screen_char);
 | 
			
		||||
    x++;
 | 
			
		||||
    local_count--;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  spi_transfer(DMDI_reg);
 | 
			
		||||
  spi_transfer(END_string);
 | 
			
		||||
 | 
			
		||||
  spi_transfer(VM0_reg); // turn on screen next vertical
 | 
			
		||||
  spi_transfer(ENABLE_display_vert);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
byte decode_ascii_binary()
 | 
			
		||||
{
 | 
			
		||||
  byte ascii_byte;
 | 
			
		||||
 | 
			
		||||
  ascii_byte = 0;
 | 
			
		||||
  
 | 
			
		||||
  if (ascii_binary[0] == 0x31) // ascii '1'
 | 
			
		||||
    ascii_byte = ascii_byte + 128;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[1] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 64;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[2] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 32;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[3] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 16;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[4] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 8;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[5] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 4;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[6] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 2;
 | 
			
		||||
 | 
			
		||||
  if (ascii_binary[7] == 0x31)
 | 
			
		||||
    ascii_byte = ascii_byte + 1;
 | 
			
		||||
 | 
			
		||||
  //Serial.print(ascii_byte, HEX);
 | 
			
		||||
 | 
			
		||||
  return(ascii_byte);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////
 | 
			
		||||
void write_NVM()
 | 
			
		||||
{
 | 
			
		||||
  byte x;
 | 
			
		||||
  byte char_address_hi, char_address_lo;
 | 
			
		||||
  byte screen_char;
 | 
			
		||||
 | 
			
		||||
  char_address_hi = font_count;
 | 
			
		||||
  char_address_lo = 0;
 | 
			
		||||
 //Serial.println("write_new_screen");   
 | 
			
		||||
 | 
			
		||||
  // disable display
 | 
			
		||||
  digitalWrite(MAX7456SELECT,LOW);
 | 
			
		||||
  spi_transfer(VM0_reg); 
 | 
			
		||||
  spi_transfer(DISABLE_display);
 | 
			
		||||
 | 
			
		||||
  spi_transfer(CMAH_reg); // set start address high
 | 
			
		||||
  spi_transfer(char_address_hi);
 | 
			
		||||
 | 
			
		||||
  for(x = 0; x < NVM_ram_size; x++) // write out 54 (out of 64) bytes of character to shadow ram
 | 
			
		||||
  {
 | 
			
		||||
    screen_char = character_bitmap[x];
 | 
			
		||||
    spi_transfer(CMAL_reg); // set start address low
 | 
			
		||||
    spi_transfer(x);
 | 
			
		||||
    spi_transfer(CMDI_reg);
 | 
			
		||||
    spi_transfer(screen_char);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // transfer a 54 bytes from shadow ram to NVM
 | 
			
		||||
  spi_transfer(CMM_reg);
 | 
			
		||||
  spi_transfer(WRITE_nvr);
 | 
			
		||||
  
 | 
			
		||||
  // wait until bit 5 in the status register returns to 0 (12ms)
 | 
			
		||||
  while ((spi_transfer(STAT_reg) & STATUS_reg_nvr_busy) != 0x00);
 | 
			
		||||
 | 
			
		||||
  spi_transfer(VM0_reg); // turn on screen next vertical
 | 
			
		||||
  spi_transfer(ENABLE_display_vert);
 | 
			
		||||
  digitalWrite(MAX7456SELECT,HIGH);  
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user