This is the Adafruit thermal printer, whose Arduino library is published here: http://www.ladyada.net/products/thermalprinter/. This is a basic port to mbed that needs proper testing. The first printBitmap function is implemented but not fully tested, the stream versions are not ported yet.

Dependents:   SMS_LEDMatrixPrinter

Fork of AdafruitThermalPrinter by Ashley Mills

Files at this revision

API Documentation at this revision

Comitter:
SomeRandomBloke
Date:
Wed Dec 05 10:00:33 2012 +0000
Parent:
2:6c38e763c285
Child:
4:871ca02007be
Commit message:
updates to remove dependancy on putc - hack to use uart2.

Changed in this revision

AdafruitThermal.cpp Show annotated file Show diff for this revision Revisions of this file
AdafruitThermal.h Show annotated file Show diff for this revision Revisions of this file
--- a/AdafruitThermal.cpp	Tue Nov 20 13:07:13 2012 +0000
+++ b/AdafruitThermal.cpp	Wed Dec 05 10:00:33 2012 +0000
@@ -1,178 +1,240 @@
-/*************************************************** 
+/***************************************************
   This is a library for the Adafruit Thermal Printer
-  
+
   Pick one up at --> http://www.adafruit.com/products/597
   These printers use TTL serial to communicate, 2 pins are required
 
-  Adafruit invests time and resources providing this open source code, 
-  please support Adafruit and open-source hardware by purchasing 
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing
   products from Adafruit!
 
-  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  Written by Limor Fried/Ladyada for Adafruit Industries.
   MIT license, all text above must be included in any redistribution
  ****************************************************/
- 
+
 /** Ported hastily to mbed by Ashley Mills - NOTE: printBitmap not ported, nothing tested **/
-#include "mbed.h" 
+#include "mbed.h"
 #include "AdafruitThermal.h"
+/*
+#define LPC_UART0             ((LPC_UART0_TypeDef     *) LPC_UART0_BASE    )
+#define LPC_UART1             ((LPC_UART1_TypeDef     *) LPC_UART1_BASE    )
+#define LPC_UART2             ((LPC_UART_TypeDef      *) LPC_UART2_BASE    )
+#define LPC_UART3             ((LPC_UART_TypeDef      *) LPC_UART3_BASE    )
+
+Set correct UART
+
+UART3
+p9 = P0_0 (tx)
+p10 = P0_1 (rx)
+
+UART1
+p13 = P0_15 (tx)
+p14 = P0_16 (rx)
+
+UART2
+p28 = P0_10 (tx)
+p27 = P0_11 (rx)
+
+UART0
+USBTX = P0_2
+USBRX = P0_3
+*/
+
+LPC_UART_TypeDef *lpcUart;
 
 
-AdafruitThermal::AdafruitThermal(PinName RX_Pin, PinName TX_Pin) {
-  _RX_Pin = RX_Pin;
-  _TX_Pin = TX_Pin;
+AdafruitThermal::AdafruitThermal(PinName RX_Pin, PinName TX_Pin)
+{
+    _RX_Pin = RX_Pin;
+    _TX_Pin = TX_Pin;
+//    if( TX_Pin == p28 )
+//        lpcUart = ((LPC_UART_TypeDef *)LPC_UART2_BASE);
+//    else  if( TX_Pin == p9 )
+//        lpcUart = ((LPC_UART_TypeDef *)LPC_UART3_BASE);
 }
 
-void AdafruitThermal::begin(int heatTime) {
-  _printer = new Serial(_RX_Pin, _TX_Pin);
-  _printer->baud(19200);
+void AdafruitThermal::begin(int heatTime)
+{
+    _printer = new Serial(_RX_Pin, _TX_Pin);
+    _printer->baud(19200);
 
-  // The printer can't start receiving data immediately
-  // upon power up -- needs a moment to initialize.  If
-  // Arduino & printer are powered from the same supply,
-  // they're starting simultaneously.  Need to pause for
-  // a moment so the printer is ready for commands.
-  // (A more robust approach might be to wait in a loop
-  // issuing status commands until valid response.)
-  wait(0.5);
-  
-  reset();
+    // The printer can't start receiving data immediately
+    // upon power up -- needs a moment to initialize.  If
+    // Arduino & printer are powered from the same supply,
+    // they're starting simultaneously.  Need to pause for
+    // a moment so the printer is ready for commands.
+    // (A more robust approach might be to wait in a loop
+    // issuing status commands until valid response.)
+    wait(0.5);
+
+    reset();
 
-  // Description of print settings from page 23 of the manual:
-  // ESC 7 n1 n2 n3 Setting Control Parameter Command
-  // Decimal: 27 55 n1 n2 n3
-  // Set "max heating dots", "heating time", "heating interval"
-  // n1 = 0-255 Max printing dots, Unit (8dots), Default: 7 (64 dots)
-  // n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us)
-  // n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us)
-  // The more max heating dots, the more peak current will cost
-  // when printing, the faster printing speed. The max heating
-  // dots is 8*(n1+1).  The more heating time, the more density,
-  // but the slower printing speed.  If heating time is too short,
-  // blank page may occur.  The more heating interval, the more
-  // clear, but the slower printing speed.
+    // Description of print settings from page 23 of the manual:
+    // ESC 7 n1 n2 n3 Setting Control Parameter Command
+    // Decimal: 27 55 n1 n2 n3
+    // Set "max heating dots", "heating time", "heating interval"
+    // n1 = 0-255 Max printing dots, Unit (8dots), Default: 7 (64 dots)
+    // n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us)
+    // n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us)
+    // The more max heating dots, the more peak current will cost
+    // when printing, the faster printing speed. The max heating
+    // dots is 8*(n1+1).  The more heating time, the more density,
+    // but the slower printing speed.  If heating time is too short,
+    // blank page may occur.  The more heating interval, the more
+    // clear, but the slower printing speed.
 
-  writeBytes(27, 55);   // Esc 7 (print settings)
-  writeBytes(20);       // Heating dots (20=balance of darkness vs no jams)
-  writeBytes(heatTime); // Library default = 255 (max)
-  writeBytes(250);      // Heat interval (500 uS = slower, but darker)
+    writeBytes(27, 55);   // Esc 7 (print settings)
+    writeBytes(20);       // Heating dots (20=balance of darkness vs no jams)
+    writeBytes(heatTime); // Library default = 255 (max)
+    writeBytes(250);      // Heat interval (500 uS = slower, but darker)
 
-  // Description of print density from page 23 of the manual:
-  // DC2 # n Set printing density
-  // Decimal: 18 35 n
-  // D4..D0 of n is used to set the printing density.  Density is
-  // 50% + 5% * n(D4-D0) printing density.
-  // D7..D5 of n is used to set the printing break time.  Break time
-  // is n(D7-D5)*250us.
-  // (Unsure of the default value for either -- not documented)
+    // Description of print density from page 23 of the manual:
+    // DC2 # n Set printing density
+    // Decimal: 18 35 n
+    // D4..D0 of n is used to set the printing density.  Density is
+    // 50% + 5% * n(D4-D0) printing density.
+    // D7..D5 of n is used to set the printing break time.  Break time
+    // is n(D7-D5)*250us.
+    // (Unsure of the default value for either -- not documented)
 
-  const int
+    const int
     printDensity   = 14, // 120% (? can go higher, text is darker but fuzzy)
     printBreakTime = 4;  // 500 uS
-  writeBytes(18, 35); // DC2 # (print density)
-  writeBytes((printBreakTime << 5) | printDensity);
+    writeBytes(18, 35); // DC2 # (print density)
+    writeBytes((printBreakTime << 5) | printDensity);
 }
 
 // reset printer
-void AdafruitThermal::reset() {
-  writeBytes(27, 64);
+void AdafruitThermal::reset()
+{
+    writeBytes(27, 64);
 }
 
 // reset formatting
-void AdafruitThermal::setDefault(){
-  online();
-  justify('L');
-  inverseOff();
-  doubleHeightOff();
-  setLineHeight(32);
-  boldOff();
-  underlineOff();
-  setBarcodeHeight(50);
-  setSize('s');
+void AdafruitThermal::setDefault()
+{
+    online();
+    justify('L');
+    inverseOff();
+    doubleHeightOff();
+    setLineHeight(32);
+    boldOff();
+    underlineOff();
+    setBarcodeHeight(50);
+    setSize('s');
 }
 
-void AdafruitThermal::test(){
-  write('h');
-  write('e');
-  write('l');
-  write('l');
-  write('o');
-  write('!');
-  write('\n');
-  feed(2);
+//void AdafruitThermal::printNothing( char ch ) { }
+
+void AdafruitThermal::test()
+{
+    write('h');
+    write('e');
+    write('l');
+    write('l');
+    write('o');
+    write('!');
+    write('\n');
+    feed(2);
 }
 
-void AdafruitThermal::print(char *string) {
+void AdafruitThermal::print(char *string)
+{
     while(*string!=0) {
         write(*string);
         string++;
     }
 }
 
-void AdafruitThermal::testPage() {
-  writeBytes(18, 84);
+void AdafruitThermal::testPage()
+{
+    writeBytes(18, 84);
 }
 
+
+void AdafruitThermal::directPutc( uint8_t c ) {
+
+    do {
+    } while ((LPC_UART2->LSR & 0x20)==0) ;
+    //write character to UART
+    LPC_UART2->THR = c ;
+/*
+    do {
+    } while ((lpcUart->LSR & 0x20)==0) ;
+    //write character to UART
+    lpcUart->THR = c ;
+*/
+}
+
+
 // this is the basic function for all printing, the rest is taken care of by the
 // inherited Print class!
-size_t AdafruitThermal::write(uint8_t c) {
-  if (c == 0x13) return 0;
-
-  if (c != 0xA)
-    linefeedneeded = true;
-  else
-    linefeedneeded = false;
+size_t AdafruitThermal::write(uint8_t c)
+{
+    if (c == 0x13) return 0;
 
-  //DBG(" 0x");
-  //DBG(c, HEX);
-  //DBG(" ("); 
-  
-  PRINTER_PRINT(c);
+    if (c != 0xA)
+        linefeedneeded = true;
+    else
+        linefeedneeded = false;
 
-  return 1;
+    //DBG(" 0x");
+    //DBG(c, HEX);
+    //DBG(" (");
+
+    PRINTER_PRINT(c);
+
+    return 1;
 
 }
 
-void AdafruitThermal::setBarcodeHeight(int val){
-  //default is 50
-  writeBytes(29, 104, val);
+void AdafruitThermal::setBarcodeHeight(int val)
+{
+    //default is 50
+    writeBytes(29, 104, val);
 }
 
-void AdafruitThermal::printBarcode(char * text, uint8_t type) {
-  int i;
-  uint8_t c;
+void AdafruitThermal::printBarcode(char * text, uint8_t type)
+{
+    int i;
+    uint8_t c;
 
-  delay(1000); // Need these delays else barcode doesn't always print. ???
-  writeBytes(29, 107, type); // set the type first
-  delay(500);
-  // Copy string, not including NUL terminator
-  for(i=0; (c = text[i]); i++) PRINTER_PRINT(c);
-  delay(500);
-  PRINTER_PRINT(c); // Terminator must follow delay. ???
+    delay(1000); // Need these delays else barcode doesn't always print. ???
+    writeBytes(29, 107, type); // set the type first
+    delay(500);
+    // Copy string, not including NUL terminator
+    for(i=0; (c = text[i]); i++) PRINTER_PRINT(c);
+    delay(500);
+    PRINTER_PRINT(c); // Terminator must follow delay. ???
 
-  delay(3000); // For some reason we can't immediately have line feeds here
-  feed(2);
+    delay(3000); // For some reason we can't immediately have line feeds here
+    feed(2);
 }
 
-void AdafruitThermal::writeBytes(uint8_t a) {
-  PRINTER_PRINT(a);
+void AdafruitThermal::writeBytes(uint8_t a)
+{
+    PRINTER_PRINT(a);
 }
 
-void AdafruitThermal::writeBytes(uint8_t a, uint8_t b) {
-  PRINTER_PRINT(a);
-  PRINTER_PRINT(b);
+void AdafruitThermal::writeBytes(uint8_t a, uint8_t b)
+{
+    PRINTER_PRINT(a);
+    PRINTER_PRINT(b);
 }
 
-void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c) {
-  PRINTER_PRINT(a);
-  PRINTER_PRINT(b);
-  PRINTER_PRINT(c);
+void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c)
+{
+    PRINTER_PRINT(a);
+    PRINTER_PRINT(b);
+    PRINTER_PRINT(c);
 }
 
-void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
-  PRINTER_PRINT(a);
-  PRINTER_PRINT(b);
-  PRINTER_PRINT(c);
-  PRINTER_PRINT(d);
+void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
+{
+    PRINTER_PRINT(a);
+    PRINTER_PRINT(b);
+    PRINTER_PRINT(c);
+    PRINTER_PRINT(d);
 }
 
 // === Character commands ===
@@ -184,139 +246,163 @@
 #define DOUBLE_WIDTH_MASK (1 << 5)
 #define STRIKE_MASK (1 << 6)
 
-void AdafruitThermal::setPrintMode(uint8_t mask) {
-  printMode |= mask;
-  writePrintMode();
+void AdafruitThermal::setPrintMode(uint8_t mask)
+{
+    printMode |= mask;
+    writePrintMode();
 }
-void AdafruitThermal::unsetPrintMode(uint8_t mask) {
-  printMode &= ~mask;
-  writePrintMode();
+void AdafruitThermal::unsetPrintMode(uint8_t mask)
+{
+    printMode &= ~mask;
+    writePrintMode();
 }
 
-void AdafruitThermal::writePrintMode() {
-  writeBytes(27, 33, printMode);
+void AdafruitThermal::writePrintMode()
+{
+    writeBytes(27, 33, printMode);
 }
 
-void AdafruitThermal::normal() {
-  printMode = 0;
-  writePrintMode();
+void AdafruitThermal::normal()
+{
+    printMode = 0;
+    writePrintMode();
 }
 
-void AdafruitThermal::inverseOn(){
-  setPrintMode(INVERSE_MASK);
+void AdafruitThermal::inverseOn()
+{
+    setPrintMode(INVERSE_MASK);
 }
 
-void AdafruitThermal::inverseOff(){
-  unsetPrintMode(INVERSE_MASK);
+void AdafruitThermal::inverseOff()
+{
+    unsetPrintMode(INVERSE_MASK);
 }
 
-void AdafruitThermal::upsideDownOn(){
-  setPrintMode(UPDOWN_MASK);
+void AdafruitThermal::upsideDownOn()
+{
+    setPrintMode(UPDOWN_MASK);
 }
 
-void AdafruitThermal::upsideDownOff(){
-  unsetPrintMode(UPDOWN_MASK);
+void AdafruitThermal::upsideDownOff()
+{
+    unsetPrintMode(UPDOWN_MASK);
 }
 
-void AdafruitThermal::doubleHeightOn(){
-  setPrintMode(DOUBLE_HEIGHT_MASK);
+void AdafruitThermal::doubleHeightOn()
+{
+    setPrintMode(DOUBLE_HEIGHT_MASK);
 }
 
-void AdafruitThermal::doubleHeightOff(){
-  unsetPrintMode(DOUBLE_HEIGHT_MASK);
+void AdafruitThermal::doubleHeightOff()
+{
+    unsetPrintMode(DOUBLE_HEIGHT_MASK);
 }
 
-void AdafruitThermal::doubleWidthOn(){
-  setPrintMode(DOUBLE_WIDTH_MASK);
+void AdafruitThermal::doubleWidthOn()
+{
+    setPrintMode(DOUBLE_WIDTH_MASK);
 }
 
-void AdafruitThermal::doubleWidthOff(){
-  unsetPrintMode(DOUBLE_WIDTH_MASK);
+void AdafruitThermal::doubleWidthOff()
+{
+    unsetPrintMode(DOUBLE_WIDTH_MASK);
 }
 
-void AdafruitThermal::strikeOn(){
-  setPrintMode(STRIKE_MASK);
+void AdafruitThermal::strikeOn()
+{
+    setPrintMode(STRIKE_MASK);
 }
 
-void AdafruitThermal::strikeOff(){
-  unsetPrintMode(STRIKE_MASK);
+void AdafruitThermal::strikeOff()
+{
+    unsetPrintMode(STRIKE_MASK);
 }
 
-void AdafruitThermal::boldOn(){
-  setPrintMode(BOLD_MASK);
+void AdafruitThermal::boldOn()
+{
+    setPrintMode(BOLD_MASK);
 }
 
-void AdafruitThermal::boldOff(){
-  unsetPrintMode(BOLD_MASK);
+void AdafruitThermal::boldOff()
+{
+    unsetPrintMode(BOLD_MASK);
 }
 
-void AdafruitThermal::justify(char value){
-  uint8_t pos = 0;
+void AdafruitThermal::justify(char value)
+{
+    uint8_t pos = 0;
 
-  if(value == 'l' || value == 'L') pos = 0;
-  if(value == 'c' || value == 'C') pos = 1;
-  if(value == 'r' || value == 'R') pos = 2;
+    if(value == 'l' || value == 'L') pos = 0;
+    if(value == 'c' || value == 'C') pos = 1;
+    if(value == 'r' || value == 'R') pos = 2;
 
-  writeBytes(0x1B, 0x61, pos);
+    writeBytes(0x1B, 0x61, pos);
 }
 
 // Feeds by the specified number of lines
-void AdafruitThermal::feed(uint8_t x){
-  // The datasheet claims sending bytes 27, 100, <x> will work
-  // but it feeds much much more.
-  while (x--)
-    write('\n');
+void AdafruitThermal::feed(uint8_t x)
+{
+    // The datasheet claims sending bytes 27, 100, <x> will work
+    // but it feeds much much more.
+    while (x--)
+        write('\n');
 }
 
 // Feeds by the specified number of rows of pixels
-void AdafruitThermal::feedRows(uint8_t rows) {
-  writeBytes(27, 74, rows);
+void AdafruitThermal::feedRows(uint8_t rows)
+{
+    writeBytes(27, 74, rows);
 }
 
-void AdafruitThermal::flush() {
-  writeBytes(12);
+void AdafruitThermal::flush()
+{
+    writeBytes(12);
 }
 
-void AdafruitThermal::setSize(char value){
-  int size = 0;
+void AdafruitThermal::setSize(char value)
+{
+    int size = 0;
 
-  if(value == 's' || value == 'S') size = 0;
-  if(value == 'm' || value == 'M') size = 10;
-  if(value == 'l' || value == 'L') size = 25;
+    if(value == 's' || value == 'S') size = 0;
+    if(value == 'm' || value == 'M') size = 10;
+    if(value == 'l' || value == 'L') size = 25;
 
-  writeBytes(29, 33, size, 10);
-  // if (linefeedneeded)
-  //  println("lfn"); //feed();
-  //linefeedneeded = false;
+    writeBytes(29, 33, size, 10);
+    // if (linefeedneeded)
+    //  println("lfn"); //feed();
+    //linefeedneeded = false;
 }
 
 // Underlines of different weights can be produced:
 // 0 - no underline
 // 1 - normal underline
 // 2 - thick underline
-void AdafruitThermal::underlineOn(uint8_t weight) {
-  writeBytes(27, 45, weight);
+void AdafruitThermal::underlineOn(uint8_t weight)
+{
+    writeBytes(27, 45, weight);
 }
 
-void AdafruitThermal::underlineOff() {
-  underlineOn(0);
+void AdafruitThermal::underlineOff()
+{
+    underlineOn(0);
 }
 
 
-void AdafruitThermal::printBitmap(int w, int h, const uint8_t *bitmap) {
-  if (w > 384) return; // maximum width of the printer
-  for (int rowStart=0; rowStart < h; rowStart += 256) {
-    int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
-    delay(500); // Need these delays else bitmap doesn't always print. ???
-    writeBytes(18, 42);
-    writeBytes(chunkHeight, w/8);
-    delay(500);
-    for (int i=0; i<((w/8)*chunkHeight); i++) {
-      PRINTER_PRINT(bitmap[(rowStart*(w/8)) + i]);
+void AdafruitThermal::printBitmap(int w, int h, const uint8_t *bitmap)
+{
+    if (w > 384) return; // maximum width of the printer
+    for (int rowStart=0; rowStart < h; rowStart += 256) {
+        int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
+        delay(500); // Need these delays else bitmap doesn't always print. ???
+        writeBytes(18, 42);
+        writeBytes(chunkHeight, w/8);
+        delay(500);
+        for (int i=0; i<((w/8)*chunkHeight); i++) {
+            PRINTER_PRINT(bitmap[(rowStart*(w/8)) + i]);
 //      PRINTER_PRINT(pgm_read_byte(bitmap + (rowStart*(w/8)) + i));
+        }
+        delay(500);
     }
-    delay(500);
-  }
 }
 
 /*
@@ -351,42 +437,50 @@
 
 // Take the printer offline. Print commands sent after this will be
 // ignored until `online` is called
-void AdafruitThermal::offline(){
-  writeBytes(27, 61, 0);
+void AdafruitThermal::offline()
+{
+    writeBytes(27, 61, 0);
 }
 
 // Take the printer back online. Subsequent print commands will be
 // obeyed.
-void AdafruitThermal::online(){
-  writeBytes(27, 61, 1);
+void AdafruitThermal::online()
+{
+    writeBytes(27, 61, 1);
 }
 
 // Put the printer into a low-energy state immediately
-void AdafruitThermal::sleep() {
-  sleepAfter(0);
+void AdafruitThermal::sleep()
+{
+    sleepAfter(0);
 }
 
 // Put the printer into a low-energy state after the given number
 // of seconds
-void AdafruitThermal::sleepAfter(uint8_t seconds) {
-  writeBytes(27, 56, seconds);
+void AdafruitThermal::sleepAfter(uint8_t seconds)
+{
+    writeBytes(27, 56, seconds);
 }
 
 // Wake the printer from a low-energy state. This command will wait
 // for 50ms (as directed by the datasheet) before allowing further
 // commands to be send.
-void AdafruitThermal::wake() {
-  writeBytes(255);
-  delay(50);
+void AdafruitThermal::wake()
+{
+    writeBytes(255);
+    delay(50);
 }
 
 ////////////////////// not working?
-void AdafruitThermal::tab(){
-  PRINTER_PRINT(9);
+void AdafruitThermal::tab()
+{
+    PRINTER_PRINT(9);
 }
-void AdafruitThermal::setCharSpacing(int spacing) {
-  writeBytes(27, 32, 0, 10);
+void AdafruitThermal::setCharSpacing(int spacing)
+{
+    writeBytes(27, 32, 0, 10);
 }
-void AdafruitThermal::setLineHeight(int val){
-  writeBytes(27, 51, val); // default is 32
+void AdafruitThermal::setLineHeight(int val)
+{
+    writeBytes(27, 51, val); // default is 32
 }
--- a/AdafruitThermal.h	Tue Nov 20 13:07:13 2012 +0000
+++ b/AdafruitThermal.h	Wed Dec 05 10:00:33 2012 +0000
@@ -17,6 +17,7 @@
 #pragma once
 
 #include "mbed.h"
+#include "rtos.h"
 
 #define UPC_A 0
 #define UPC_E 1
@@ -31,8 +32,10 @@
 #define MSI 10
 
 
-#define PRINTER_PRINT(a) _printer->putc(a);
-#define delay(a) wait(a/1000)
+//#define PRINTER_PRINT(a) _printer->putc(a);
+#define PRINTER_PRINT(a) directPutc(a);
+//#define delay(a) wait(a/1000)
+#define delay(a) Thread::wait(a)
 
 
 
@@ -46,6 +49,7 @@
     void test();
     void testPage();
 
+    void directPutc( uint8_t c );
     size_t write(uint8_t c);