| Line No. | Rev | Author | Line |
|---|---|---|---|
| 1 | 32 | kaklik | /****************************************************************************** |
| 2 | ESC/POS Printer Language Support |
||
| 3 | |||
| 4 | Summary: |
||
| 5 | This file provides support for the ESC/POS printer language when using the |
||
| 6 | USB Embedded Host Printer Client Driver. |
||
| 7 | |||
| 8 | Description: |
||
| 9 | This file provides support for the ESC/POS printer language when using the |
||
| 10 | USB Embedded Host Printer Client Driver. |
||
| 11 | |||
| 12 | The exact implementation of ESC/POS varies across manufacturers and even |
||
| 13 | across different models from the same manufacturer. Some POS printers use |
||
| 14 | specialized Device ID strings (obtained with the GET DEVICE ID class- |
||
| 15 | specific request) to indicate the deviations from the strict ESC/POS |
||
| 16 | specification. Also, many printers indicate a custom USB Peripheral Device |
||
| 17 | rather than the Printer Class, and therefore do not support the |
||
| 18 | GET DEVICE ID device request. For example: |
||
| 19 | <code> |
||
| 20 | Printer Tested VID/PID Class Device ID Substring |
||
| 21 | ------------------------------------------------------------- |
||
| 22 | Bixolon SRP-270 0x0419/0x3C01 Printer ESC |
||
| 23 | Epson TM-T88IV 0x04B8/0x0202 Custom Not supported |
||
| 24 | Seiko DPU-V445 0x0619/0x0111 Printer Not present |
||
| 25 | Seiko MPU-L465 0x0619/0x0109 Printer SIIMPU |
||
| 26 | </code> |
||
| 27 | Therefore, dynamic language determination is not recommended for POS |
||
| 28 | printers. Instead, create your application to target a either a single |
||
| 29 | printer model or a group of printer models with identical requirements, |
||
| 30 | and indicate specific VID, PID, and printer language via the USB |
||
| 31 | Configuration Tool, and test the application to ensure consistent behavior |
||
| 32 | across all supported printer models. |
||
| 33 | |||
| 34 | The ESC/POS language support code provides several #defines that allow the |
||
| 35 | language support file to automatically configure itself for different |
||
| 36 | printer models. These #defines can be set using the USB Configuration Tool |
||
| 37 | (USBConfig.exe or MPLAB VDI). Note that they are determined at compile |
||
| 38 | time, not run time, so only one type of printer can be utilized by an |
||
| 39 | application. Printer models other that the ones explicitly tested may |
||
| 40 | require other modifications to the language support code. |
||
| 41 | |||
| 42 | Notes: |
||
| 43 | Currently, only standard mode is supported. |
||
| 44 | |||
| 45 | The black and white bit image polarity is 0=white, 1=black, which is |
||
| 46 | reversed from the Microchip Graphics Library polarity. This driver will |
||
| 47 | automatically convert the image data to the required format, as long as the |
||
| 48 | image data is located in ROM (USB_PRINTER_TRANSFER_FROM_ROM) or it is |
||
| 49 | copied from a RAM buffer (USB_PRINTER_TRANSFER_COPY_DATA). If the data is |
||
| 50 | to be sent directly from its original RAM location, the data must already |
||
| 51 | be in the format required by the printer language. |
||
| 52 | |||
| 53 | |||
| 54 | *******************************************************************************/ |
||
| 55 | //DOM-IGNORE-BEGIN |
||
| 56 | /****************************************************************************** |
||
| 57 | |||
| 58 | * FileName: usb_host_printer_esc_pos.h |
||
| 59 | * Dependencies: None |
||
| 60 | * Processor: PIC24/dsPIC30/dsPIC33/PIC32MX |
||
| 61 | * Compiler: C30 v3.10b/C32 v1.02 |
||
| 62 | * Company: Microchip Technology, Inc. |
||
| 63 | |||
| 64 | Software License Agreement |
||
| 65 | |||
| 66 | The software supplied herewith by Microchip Technology Incorporated |
||
| 67 | (the Company) for its PICmicro® Microcontroller is intended and |
||
| 68 | supplied to you, the Companys customer, for use solely and |
||
| 69 | exclusively on Microchip PICmicro Microcontroller products. The |
||
| 70 | software is owned by the Company and/or its supplier, and is |
||
| 71 | protected under applicable copyright laws. All rights are reserved. |
||
| 72 | Any use in violation of the foregoing restrictions may subject the |
||
| 73 | user to criminal sanctions under applicable laws, as well as to |
||
| 74 | civil liability for the breach of the terms and conditions of this |
||
| 75 | license. |
||
| 76 | |||
| 77 | THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES, |
||
| 78 | WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED |
||
| 79 | TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||
| 80 | PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, |
||
| 81 | IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR |
||
| 82 | CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
||
| 83 | |||
| 84 | Change History: |
||
| 85 | Rev Description |
||
| 86 | ---- ---------------------------------------- |
||
| 87 | 2.6a- No change |
||
| 88 | 2.7a |
||
| 89 | *******************************************************************************/ |
||
| 90 | //DOM-IGNORE-END |
||
| 91 | |||
| 92 | |||
| 93 | // ***************************************************************************** |
||
| 94 | // ***************************************************************************** |
||
| 95 | // Section: Constants |
||
| 96 | // ***************************************************************************** |
||
| 97 | // ***************************************************************************** |
||
| 98 | |||
| 99 | // This is the string that the printer language support determination |
||
| 100 | // routine will look for to determine if the printer supports this |
||
| 101 | // printer language. This string is case sensive. See the function |
||
| 102 | // USBHostPrinterLanguageESCPOSIsSupported() for more information |
||
| 103 | // about using or changing this string. Dynamic language determination |
||
| 104 | // is not recommended when using POS printers. |
||
| 105 | #define LANGUAGE_ID_STRING_ESCPOS "ESC" |
||
| 106 | // These are the support flags that are set for this language. |
||
| 107 | #define LANGUAGE_SUPPORT_FLAGS_ESCPOS USB_PRINTER_FUNCTION_SUPPORT_POS |
||
| 108 | |||
| 109 | |||
| 110 | /**************************************************************************** |
||
| 111 | Function: |
||
| 112 | BYTE USBHostPrinterLanguageESCPOS( BYTE address, |
||
| 113 | USB_PRINTER_COMMAND command, USB_DATA_POINTER data, DWORD size, BYTE transferFlags ) |
||
| 114 | |||
| 115 | Summary: |
||
| 116 | This function executes printer commands for an ESC/POS printer. |
||
| 117 | |||
| 118 | Description: |
||
| 119 | This function executes printer commands for an ESC/POS printer. When |
||
| 120 | the application issues a printer command, the printer client driver |
||
| 121 | determines what language to use to communicate with the printer, and |
||
| 122 | transfers the command to that language support routine. As much as |
||
| 123 | possible, commands are designed to produce the same output regardless |
||
| 124 | of what printer language is used. |
||
| 125 | |||
| 126 | Not all printer commands support data from both RAM and ROM. Unless |
||
| 127 | otherwise noted, the data pointer is assumed to point to RAM, regardless of |
||
| 128 | the value of transferFlags. Refer to the specific command to see if ROM |
||
| 129 | data is supported. |
||
| 130 | |||
| 131 | Preconditions: |
||
| 132 | None |
||
| 133 | |||
| 134 | Parameters: |
||
| 135 | BYTE address - Device's address on the bus |
||
| 136 | USB_PRINTER_COMMAND command - Command to execute. See the enumeration |
||
| 137 | USB_PRINTER_COMMAND for the list of |
||
| 138 | valid commands and their requirements. |
||
| 139 | USB_DATA_POINTER data - Pointer to the required data. Note that |
||
| 140 | the caller must set transferFlags |
||
| 141 | appropriately to indicate if the pointer is |
||
| 142 | a RAM pointer or a ROM pointer. |
||
| 143 | DWORD size - Size of the data. For some commands, this |
||
| 144 | parameter is used to hold the data itself. |
||
| 145 | BYTE transferFlags - Flags that indicate details about the |
||
| 146 | transfer operation. Refer to these flags |
||
| 147 | * USB_PRINTER_TRANSFER_COPY_DATA |
||
| 148 | * USB_PRINTER_TRANSFER_STATIC_DATA |
||
| 149 | * USB_PRINTER_TRANSFER_NOTIFY |
||
| 150 | * USB_PRINTER_TRANSFER_FROM_ROM |
||
| 151 | * USB_PRINTER_TRANSFER_FROM_RAM |
||
| 152 | |||
| 153 | Return Values: |
||
| 154 | USB_PRINTER_SUCCESS - The command was executed successfully. |
||
| 155 | USB_PRINTER_UNKNOWN_DEVICE - A printer with the indicated address is not |
||
| 156 | attached |
||
| 157 | USB_PRINTER_TOO_MANY_DEVICES - The printer status array does not have |
||
| 158 | space for another printer. |
||
| 159 | USB_PRINTER_OUT_OF_MEMORY - Not enough available heap space to |
||
| 160 | execute the command. |
||
| 161 | other - See possible return codes from the |
||
| 162 | function USBHostPrinterWrite(). |
||
| 163 | |||
| 164 | Remarks: |
||
| 165 | When developing new commands, keep in mind that the function |
||
| 166 | USBHostPrinterCommandReady() will be used before calling this function to |
||
| 167 | see if there is space available in the output transfer queue. |
||
| 168 | USBHostPrinterCommandReady() will routine TRUE if a single space is |
||
| 169 | available in the output queue. Therefore, each command can generate only |
||
| 170 | one output transfer. |
||
| 171 | |||
| 172 | Multiple printer languages may be used in a single application. The USB |
||
| 173 | Embedded Host Printer Client Driver will call the routine required for the |
||
| 174 | attached device. |
||
| 175 | ***************************************************************************/ |
||
| 176 | |||
| 177 | BYTE USBHostPrinterLanguageESCPOS( BYTE address, |
||
| 178 | USB_PRINTER_COMMAND command, USB_DATA_POINTER data, DWORD size, BYTE transferFlags ); |
||
| 179 | |||
| 180 | |||
| 181 | /**************************************************************************** |
||
| 182 | Function: |
||
| 183 | BOOL USBHostPrinterLanguageESCPOSIsSupported( char *deviceID, |
||
| 184 | USB_PRINTER_FUNCTION_SUPPORT *support ) |
||
| 185 | |||
| 186 | Description: |
||
| 187 | This function determines if the printer with the given device ID string |
||
| 188 | supports the ESC/POS printer language. |
||
| 189 | |||
| 190 | Preconditions: |
||
| 191 | None |
||
| 192 | |||
| 193 | Parameters: |
||
| 194 | char *deviceID - Pointer to the "COMMAND SET:" portion of the device ID |
||
| 195 | string of the attached printer. |
||
| 196 | USB_PRINTER_FUNCTION_SUPPORT *support - Pointer to returned information |
||
| 197 | about what types of functions this printer supports. |
||
| 198 | |||
| 199 | Return Values: |
||
| 200 | TRUE - The printer supports ESC/POS. |
||
| 201 | FALSE - The printer does not support ESC/POS. |
||
| 202 | |||
| 203 | Remarks: |
||
| 204 | The caller must first locate the "COMMAND SET:" section of the device ID |
||
| 205 | string. To ensure that only the "COMMAND SET:" section of the device ID |
||
| 206 | string is checked, the ";" at the end of the section should be temporarily |
||
| 207 | replaced with a NULL. Otherwise, this function may find the printer |
||
| 208 | language string in the comments or other section, and incorrectly indicate |
||
| 209 | that the printer supports the language. |
||
| 210 | |||
| 211 | Device ID strings are case sensitive. |
||
| 212 | |||
| 213 | See the file header comments for this file (usb_host_printer_esc_pos.h) |
||
| 214 | for cautions regarding dynamic printer language selection with POS |
||
| 215 | printers. |
||
| 216 | ***************************************************************************/ |
||
| 217 | |||
| 218 | BOOL USBHostPrinterLanguageESCPOSIsSupported( char *deviceID, |
||
| 219 | USB_PRINTER_FUNCTION_SUPPORT *support ); |
||
| 220 | |||
| 221 | |||
| 222 | /**************************************************************************** |
||
| 223 | Function: |
||
| 224 | USB_DATA_POINTER USBHostPrinterPOSImageDataFormat( USB_DATA_POINTER image, |
||
| 225 | BYTE imageLocation, WORD imageHeight, WORD imageWidth, WORD *currentRow, |
||
| 226 | BYTE byteDepth, BYTE *imageData ) |
||
| 227 | |||
| 228 | Summary: |
||
| 229 | This function formats data for a bitmapped image into the format required |
||
| 230 | for sending to a POS printer. |
||
| 231 | |||
| 232 | Description: |
||
| 233 | This function formats data for a bitmapped image into the format required |
||
| 234 | for sending to a POS printer. Bitmapped images are stored one row of pixels |
||
| 235 | at a time. Suppose we have an image with vertical black bars, eight pixels |
||
| 236 | wide and eight pixels deep. The image would appear as the following pixels, |
||
| 237 | where 0 indicates a black dot and 1 indicates a white dot: |
||
| 238 | <code> |
||
| 239 | |||
| 240 | |||
| 241 | |||
| 242 | |||
| 243 | |||
| 244 | |||
| 245 | |||
| 246 | |||
| 247 | </code> |
||
| 248 | The stored bitmap of the data would contain the data bytes, where each byte |
||
| 249 | is one row of data: |
||
| 250 | <code> |
||
| 251 | 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 |
||
| 252 | </code> |
||
| 253 | When printing to a full sheet printer, eight separate |
||
| 254 | USB_PRINTER_IMAGE_DATA_HEADER / USB_PRINTER_IMAGE_DATA command combinations |
||
| 255 | are required to print this image. |
||
| 256 | |||
| 257 | POS printers, however, require image data formated either 8 dots or 24 dots |
||
| 258 | deep, depending on the desired (and supported) vertical print density. For |
||
| 259 | a POS printer performing an 8-dot vertical density print, the data needs to |
||
| 260 | be in this format: |
||
| 261 | <code> |
||
| 262 | 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF |
||
| 263 | </code> |
||
| 264 | When printing to a POS printer, only one |
||
| 265 | USB_PRINTER_IMAGE_DATA_HEADER / USB_PRINTER_IMAGE_DATA command combination |
||
| 266 | is required to print this image. |
||
| 267 | |||
| 268 | This function supports 8-dot and 24-dot vertical densities by specifying |
||
| 269 | the byteDepth parameter as either 1 (8-dot) or 3 (24-dot). |
||
| 270 | |||
| 271 | Precondition: |
||
| 272 | None |
||
| 273 | |||
| 274 | Parameters: |
||
| 275 | USB_DATA_POINTER image Pointer to the image bitmap data. |
||
| 276 | BYTE imageLocation Location of the image bitmap data. Valid values |
||
| 277 | are USB_PRINTER_TRANSFER_FROM_ROM and |
||
| 278 | USB_PRINTER_TRANSFER_FROM_RAM. |
||
| 279 | WORD imageHeight Height of the image in pixels. |
||
| 280 | WORD imageWidth Width of the image in pixels. |
||
| 281 | WORD *currentRow The current pixel row. Upon return, this value is |
||
| 282 | updated to the next pixel row to print. |
||
| 283 | BYTE byteDepth The byte depth of the print. Valid values are 1 |
||
| 284 | (8-dot vertical density) and 3 (24-dot vertical |
||
| 285 | density). |
||
| 286 | BYTE *imageData Pointer to a RAM data buffer that will receive the |
||
| 287 | manipulated data to send to the printer. |
||
| 288 | |||
| 289 | Returns: |
||
| 290 | The function returns a pointer to the next byte of image data. |
||
| 291 | |||
| 292 | Example: |
||
| 293 | The following example code will send a complete bitmapped image to a POS |
||
| 294 | printer. |
||
| 295 | <code> |
||
| 296 | WORD currentRow; |
||
| 297 | BYTE depthBytes; |
||
| 298 | BYTE *imageDataPOS; |
||
| 299 | USB_PRINTER_IMAGE_INFO imageInfo; |
||
| 300 | BYTE returnCode; |
||
| 301 | #if defined (__C30__) |
||
| 302 | BYTE __prog__ *ptr; |
||
| 303 | ptr = (BYTE __prog__ *)logoMCHP.address; |
||
| 304 | #elif defined (__PIC32MX__) |
||
| 305 | const BYTE *ptr; |
||
| 306 | ptr = (const BYTE *)logoMCHP.address; |
||
| 307 | #endif |
||
| 308 | |||
| 309 | imageInfo.densityVertical = 24; // 24-dot density |
||
| 310 | imageInfo.densityHorizontal = 2; // Double density |
||
| 311 | |||
| 312 | // Extract the image height and width |
||
| 313 | imageInfo.width = ((WORD)ptr[5] << 8) + ptr[4]; |
||
| 314 | imageInfo.height = ((WORD)ptr[3] << 8) + ptr[2]; |
||
| 315 | |||
| 316 | depthBytes = imageInfo.densityVertical / 8; |
||
| 317 | imageDataPOS = (BYTE *)malloc( imageInfo.width * |
||
| 318 | depthBytes ); |
||
| 319 | |||
| 320 | if (imageDataPOS == NULL) |
||
| 321 | { |
||
| 322 | // Error - not enough heap space |
||
| 323 | } |
||
| 324 | |||
| 325 | USBHostPrinterCommandWithReadyWait( &returnCode, |
||
| 326 | printerInfo.deviceAddress, USB_PRINTER_IMAGE_START, |
||
| 327 | USB_DATA_POINTER_RAM(&imageInfo), |
||
| 328 | sizeof(USB_PRINTER_IMAGE_INFO ), |
||
| 329 | |||
| 330 | |||
| 331 | ptr += 10; // skip the header info |
||
| 332 | |||
| 333 | currentRow = 0; |
||
| 334 | while (currentRow < imageInfo.height) |
||
| 335 | { |
||
| 336 | USBHostPrinterCommandWithReadyWait( &returnCode, |
||
| 337 | printerInfo.deviceAddress, |
||
| 338 | USB_PRINTER_IMAGE_DATA_HEADER, USB_NULL, |
||
| 339 | imageInfo.width, 0 ); |
||
| 340 | |||
| 341 | ptr = USBHostPrinterPOSImageDataFormat( |
||
| 342 | USB_DATA_POINTER_ROM(ptr), |
||
| 343 | USB_PRINTER_TRANSFER_FROM_ROM, imageInfo.height, |
||
| 344 | imageInfo.width, ¤tRow, depthBytes, |
||
| 345 | imageDataPOS ).pointerROM; |
||
| 346 | |||
| 347 | USBHostPrinterCommandWithReadyWait( &returnCode, |
||
| 348 | printerInfo.deviceAddress, USB_PRINTER_IMAGE_DATA, |
||
| 349 | USB_DATA_POINTER_RAM(imageDataPOS), imageInfo.width, |
||
| 350 | USB_PRINTER_TRANSFER_COPY_DATA); |
||
| 351 | } |
||
| 352 | |||
| 353 | free( imageDataPOS ); |
||
| 354 | |||
| 355 | USBHostPrinterCommandWithReadyWait( &returnCode, |
||
| 356 | printerInfo.deviceAddress, USB_PRINTER_IMAGE_STOP, |
||
| 357 | USB_NULL, 0, 0 ); |
||
| 358 | </code> |
||
| 359 | |||
| 360 | Remarks: |
||
| 361 | This routine currently does not support 36-dot density printing. Since |
||
| 362 | the output for 36-dot vertical density is identical to 24-dot vertical |
||
| 363 | density, 24-dot vertical density should be used instead. |
||
| 364 | |||
| 365 | This routine does not yet support reading from external memory. |
||
| 366 | ***************************************************************************/ |
||
| 367 | |||
| 368 | USB_DATA_POINTER USBHostPrinterPOSImageDataFormat( USB_DATA_POINTER image, |
||
| 369 | BYTE imageLocation, WORD imageHeight, WORD imageWidth, WORD *currentRow, |
||
| 370 | BYTE byteDepth, BYTE *imageData ); |
||
| 371 |
Powered by WebSVN v2.8.3