/* Read Font Demonstration of reading font data from the TellyMate This requires a TellyMate with firmware version 1.1.00+ */ #define BAUD_RATE 57600 #define CHAR_ESC "\x1B" #define CHAR_DLE "\x10" static byte g_maxfontbank = 0; static byte g_character = 0 ; static byte g_fontbank = 0; void setup( void ) { Serial.begin( BAUD_RATE ) ; Serial.flush(); // The pixel plotting routine needs the TellyMate to send data back to the Arduino. tellymate_enable_transmit(); Serial.print( CHAR_ESC "E" ) ; // clear screen Serial.print( CHAR_ESC "f" ) ; // turn off cursor // find the number of fontbanks this tellymate has... g_maxfontbank = tellymate_data_read('7') ; // and draw the title... draw_title( g_fontbank ) ; } void loop( void ) { // work out where to draw the next character... uint8_t pos = (g_character & 0b1111) ; uint8_t x = 1 + (pos & 0b0011) * 9 ; uint8_t y = 2 + ((pos & 0b0100) >> 2) * 11 ; // and then draw it! draw_character( g_character , y , x, g_fontbank ) ; tm_cursor_move( y + 9, x + 3 ); // and give the large character a label. Serial.print( (int)g_character ); Serial.print( " " ) ; // and now increment the character to draw (and possibly the fontbank as well) g_character++ ; if (g_character == 0) { g_fontbank ++ ; if (g_fontbank >= g_maxfontbank) g_fontbank = 0 ; draw_title( g_fontbank ) ; } delay(250) ; } void draw_title( byte fontbank ) { tm_cursor_move( 0, 0 ); Serial.write( "fontbank:" ); Serial.print( (int)g_fontbank ); Serial.print( ' ' ) ; } void draw_character( byte c, byte row, byte col, byte fontbank ) { for( byte slice = 0 ; slice < 9 ; slice++ ) { draw_slice( c , slice, row + slice, col, fontbank ); } } void draw_slice( byte c , byte slice, byte row, byte col, byte fontbank ) { byte pattern = read_character_definition( c, slice, fontbank ) ; byte bitmask = 0b10000000 ; tm_cursor_move( row , (col < 0) ? 0 : col ) ; for( byte pos = 0 ; pos < 8 ; pos++ ) { Serial.write( (pattern & bitmask) ? 219 : ' ' ) ; bitmask >>= 1 ; } } inline byte nybble_to_hex( byte n ) { return( (n > 9) ? ('a' + (n - 10)) : ('0' + n) ); } inline void write_byte_as_hex( byte b ) { Serial.write( nybble_to_hex( b >> 4 ) ) ; Serial.write( nybble_to_hex( b & 0xf ) ) ; } int read_character_definition( byte c, byte slice, byte fontbank ) { tm_cursor_move( slice, fontbank ) ; Serial.print( CHAR_ESC "S" ) ; write_byte_as_hex( c ) ; return( tellymate_get_response() ) ; } //================================= // Helper routines //================================= void tm_cursor_move( uint8_t row , uint8_t col ) { // Yrc Serial.print( CHAR_ESC ) ; Serial.print( 'Y' ) ; Serial.print((unsigned char)(32 + row)) ; Serial.print((unsigned char)(32 + col)) ; } void tellymate_enable_transmit( void ) { // enable transmit sequence: Serial.print( CHAR_ESC ) ; for( byte i = 0 ; i < 4 ; i++ ){ Serial.print( '~' ) ; } } int tellymate_get_response() { // a command has been sent to the tellymate that should cause // a byte to be returned. // // I now need to wait *at least* 20 bit durations to receive the reply. // (the [remainder] of the send sequence to the TellyMate will take 10 bits, and the receive from the TellyMate will take 10 bits // It might be twice that (depending on when the character is read on the other end), and how long it takes to send the reply. // // each bit is 1/57600th of a second. // There are 1000000 microseconds in a second, so there are 1000000/57600 microseconds per bit int result = -1 ; // default result delayMicroseconds( 20 * (1000000 / BAUD_RATE )) ; for( uint8_t i = 0 ; i < 30 ; i++ ) { if (Serial.available() > 0) { result = Serial.read(); break ; } // delay a short while delayMicroseconds( 1000000 / BAUD_RATE ) ; // approximately one bit duration } // If no character is received after 50 bit durations, the default value of -1 is returned. return result ; } int tellymate_data_read( char param ) { // {n where n is the param passed. // As at tellymate firmware 1.0.10, n can be as follows: // '0' - read current row // '1' - read current column // '2' - read firmware major version (e.g. 1) // '3' - read firmware minor version (e.g. 0) // '4' - read firmware revision (e.g.10) // '5' - read output format 0 = NTSC, 1 = PAL // '6' - read Row/Column (returns 2 bytes) // '7' - read number of fontbanks Serial.print( CHAR_ESC "^" ) ; Serial.print( param ) ; return( tellymate_get_response() ) ; } void tellymate_get_cursor( int &row , int &col ) { Serial.print( CHAR_ESC "^6" ) ; row = tellymate_get_response() ; col = tellymate_get_response() ; } int tellymate_cursor_read() { // | Serial.print( CHAR_ESC "|" ); return( tellymate_get_response() ) ; } int tellymate_cursor_read( byte row, byte col ) { // }rc Serial.print( CHAR_ESC "`" ) ; Serial.print( (char)(32+row) ) ; Serial.print( (char)(32+col) ) ; return( tellymate_get_response() ) ; }