-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathusb_host_printer_esc_pos.c
More file actions
1707 lines (1413 loc) · 62.7 KB
/
usb_host_printer_esc_pos.c
File metadata and controls
1707 lines (1413 loc) · 62.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
/******************************************************************************
Change History:
Rev Description
---------- ----------------------------------------------------------
2.6 - 2.7a No change
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GenericTypeDefs.h"
#include "usb.h"
#include "usb_host_printer.h"
#include "usb_host_printer_esc_pos.h"
//#define DEBUG_MODE
#if defined( DEBUG_MODE )
#include "uart2.h"
#endif
#ifdef USB_PRINTER_LANGUAGE_ESCPOS
// *****************************************************************************
// *****************************************************************************
// Section: Configuration
// *****************************************************************************
// *****************************************************************************
#if !defined(USB_ENABLE_TRANSFER_EVENT)
#error The USB Host Printer Client Driver requires transfer events.
#endif
// *****************************************************************************
// *****************************************************************************
// Section: Constants
// *****************************************************************************
// *****************************************************************************
#define DC2 "\x12"
#define DC2_CHAR '\x12'
#define ESC "\x1B" //"\033"
#define ESC_CHAR '\x1B'
#define FF "\x0C"
#define FF_CHAR '\x0C'
#define LF "\x0A"
#define LF_CHAR '\x0A'
#define GS "\x1D"
#define GS_CHAR '\x1D'
#define NUL "\x00"
#define NUL_CHAR '\x00'
#define COMMAND_COLOR_BLACK ESC "r0"
#define COMMAND_COLOR_RED ESC "r1"
#define COMMAND_FILL_SHADED DC2 "$4\x01"
#define COMMAND_FILL_SOLID DC2 "$4\x02"
#define COMMAND_FONT_REVERSE_ON GS "B1"
#define COMMAND_FONT_REVERSE_OFF GS "B0"
#define COMMAND_FORMFEED FF
#define COMMAND_JOB_START ESCAPE "@"
#define COMMAND_JUSTIFY_CENTER ESC "a1"
#define COMMAND_JUSTIFY_LEFT ESC "a0"
#define COMMAND_JUSTIFY_RIGHT ESC "a2"
//#define COMMAND_LINE_TYPE_DASHED DC2 "$2\x01"
//#define COMMAND_LINE_TYPE_DOTTED DC2 "$2\x02"
//#define COMMAND_LINE_TYPE_SOLID DC2 "$2\x00"
//#define COMMAND_LINE_WIDTH DC2 "$3\xFF"
#define COMMAND_MODE_PAGE ESC "L"
#define COMMAND_MODE_STANDARD ESC "S"
#define COMMAND_ORIENTATION_HORIZONTAL ESC "V0" ESC "{0"
#define COMMAND_ORIENTATION_VERTICAL ESC "V1"
#define COMMAND_ORIENTATION_UPSIDE_DOWN ESC "{1"
//#define COMMAND_PRINT_AND_FEED ESC "J\xFF"
//#define COMMAND_PRINT_LENGTH DC2 "H"
//#define COMMAND_PRINT_WIDTH DC2 "K"
//#define COMMAND_RECTANGLE DC2 "$1"
//#define COMMAND_SET_PITCH GS "P\xFF\xFF"
//#define COMMAND_SET_POSITION_X ESC "$"
//#define COMMAND_SET_POSITION_X_RELATIVE ESC "\"
//#define COMMAND_SET_POSITION_Y GS "$"
//#define COMMAND_SET_POSITION_Y_RELATIVE GS "\"
#define COMMAND_SET_LEFT_MARGIN GS "L\xFF\xFF"
// *****************************************************************************
// *****************************************************************************
// Section: Data Structures
// *****************************************************************************
// *****************************************************************************
//-----------------------------------------------------------------------------
/* Printer Status Structure
This structure holds the information about an attached printer. One instance
of this structure is needed for each attached printer.
*/
typedef struct
{
USB_PRINTER_FUNCTION_SUPPORT support; // The functions supported by this printer.
uint16_t currentHeight; // The current height of the page in points.
uint16_t currentWidth; // The current width of the page in points.
uint16_t currentX; // Current X-axis position.
uint16_t currentY; // Current Y-axis position.
uint8_t deviceAddress; // Address of the attached printer
uint8_t fontName; // Currently selected font, translated
uint8_t fontSize; // Size of the current font, vertical and horizontal scaling
uint8_t density; // Vertical and horizontal dot density specification
// of the currently printing image.
uint8_t imageDataWidth; // Number of bytes to send for each column of the
// currently printing image;
uint16_t imageWidth; // Dot width of the currently printing image.
union
{
uint8_t value;
struct
{
uint8_t isLandscape : 1; // Landscape(1) or portrait(0)
uint8_t isBold : 1; // If the font is bold
uint8_t isUnderlined : 1; // If the font is underlined
uint8_t reversePrint : 1; // Text is printed in reversed colors.
uint8_t inPageMode : 1; // If the printer is in Page or Standard mode.
};
} printerFlags;
} PRINTER_STATUS_ESC_POS;
// *****************************************************************************
// *****************************************************************************
// Section: Global Variables
// *****************************************************************************
// *****************************************************************************
#ifdef USE_PRINTER_POS_EXTENDED_BARCODE_FORMAT
uint8_t barCodeFormats[USB_PRINTER_POS_BARCODE_MAX] =
{
65, // USB_PRINTER_POS_BARCODE_UPC_A
66, // USB_PRINTER_POS_BARCODE_UPC_E
67, // USB_PRINTER_POS_BARCODE_EAN13
68, // USB_PRINTER_POS_BARCODE_EAN8
69, // USB_PRINTER_POS_BARCODE_CODE39
70, // USB_PRINTER_POS_BARCODE_ITF
71, // USB_PRINTER_POS_BARCODE_CODABAR
72, // USB_PRINTER_POS_BARCODE_CODE93
73, // USB_PRINTER_POS_BARCODE_CODE128
74 // USB_PRINTER_POS_BARCODE_EAN128
};
#endif
USB_PRINTER_GRAPHICS_PARAMETERS localParams;
PRINTER_STATUS_ESC_POS printerListESCPOS[USB_MAX_PRINTER_DEVICES];
// *****************************************************************************
// *****************************************************************************
// Section: Macros
// *****************************************************************************
// *****************************************************************************
#define PAGE_IS_LANDSCAPE(x) ((x & 0x01) == 0x01)
#define PAGE_IS_PORTRAIT(x) ((x & 0x01) == 0x00)
#define FONT_IS_BOLD(x) ((x & 0x02) == 0x02)
#define FONT_IS_ITALIC(x) ((x & 0x04) == 0x04)
#define _SetCurrentPosition(x,y) \
{ \
printerListESCPOS[printer].currentX = x; \
printerListESCPOS[printer].currentY = y; \
}
#ifndef USB_MALLOC
#define USB_MALLOC(size) malloc(size)
#endif
#ifndef USB_FREE
#define USB_FREE(ptr) free(ptr)
#endif
#define USB_FREE_AND_CLEAR(ptr) {USB_FREE(ptr); ptr = NULL;}
// *****************************************************************************
// *****************************************************************************
// Section: Local Prototypes
// *****************************************************************************
// *****************************************************************************
#if defined( USB_PRINTER_POS_BARCODE_SUPPORT )
static uint8_t _BarcodeCharacterValueCodabar( char c );
static uint8_t _BarcodeCharacterValueCode39( char c );
static char _BarcodeValueCharacterCodabar( uint8_t v );
static char _BarcodeValueCharacterCode39( uint8_t v );
#endif
static uint8_t _PrintFontCommand( uint8_t printer, uint8_t transferFlags );
static uint8_t _PrintStaticCommand( uint8_t printer, char *command, uint8_t transferFlags );
// *****************************************************************************
// *****************************************************************************
// Section: Interface Functions
// *****************************************************************************
// *****************************************************************************
/****************************************************************************
Function:
uint8_t USBHostPrinterLanguageESCPOS( uint8_t address,
USB_PRINTER_COMMAND command, USB_DATA_POINTER data, uint32_t size, uint8_t transferFlags )
Summary:
This function executes printer commands for an ESC/POS printer.
Description:
This function executes printer commands for an ESC/POS printer. When
the application issues a printer command, the printer client driver
determines what language to use to communicate with the printer, and
transfers the command to that language support routine. As much as
possible, commands are designed to produce the same output regardless
of what printer language is used.
Not all printer commands support data from both RAM and ROM. Unless
otherwise noted, the data pointer is assumed to point to RAM, regardless of
the value of transferFlags. Refer to the specific command to see if ROM
data is supported.
Preconditions:
None
Parameters:
uint8_t address - Device's address on the bus
USB_PRINTER_COMMAND command - Command to execute. See the enumeration
USB_PRINTER_COMMAND for the list of
valid commands and their requirements.
USB_DATA_POINTER data - Pointer to the required data. Note that
the caller must set transferFlags
appropriately to indicate if the pointer is
a RAM pointer or a ROM pointer.
uint32_t size - Size of the data. For some commands, this
parameter is used to hold the data itself.
uint8_t transferFlags - Flags that indicate details about the
transfer operation. Refer to these flags
* USB_PRINTER_TRANSFER_COPY_DATA
* USB_PRINTER_TRANSFER_STATIC_DATA
* USB_PRINTER_TRANSFER_NOTIFY
* USB_PRINTER_TRANSFER_FROM_ROM
* USB_PRINTER_TRANSFER_FROM_RAM
Return Values:
USB_PRINTER_SUCCESS - The command was executed successfully.
USB_PRINTER_UNKNOWN_DEVICE - A printer with the indicated address is not
attached
USB_PRINTER_TOO_MANY_DEVICES - The printer status array does not have
space for another printer.
USB_PRINTER_OUT_OF_MEMORY - Not enough available heap space to
execute the command.
other - See possible return codes from the
function USBHostPrinterWrite().
Remarks:
When developing new commands, keep in mind that the function
USBHostPrinterCommandReady() will be used before calling this function to
see if there is space available in the output transfer queue.
USBHostPrinterCommandReady() will routine true if a single space is
available in the output queue. Therefore, each command can generate only
one output transfer.
Multiple printer languages may be used in a single application. The USB
Embedded Host Printer Client Driver will call the routine required for the
attached device.
***************************************************************************/
uint8_t USBHostPrinterLanguageESCPOS( uint8_t address,
USB_PRINTER_COMMAND command, USB_DATA_POINTER data, uint32_t size, uint8_t transferFlags )
{
char *buffer;
int i;
uint8_t printer = 0;
if (command != USB_PRINTER_ATTACHED)
{
// Try to find the current printer. If we can't find the printer in the list,
// put it in the list at the first available location.
for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListESCPOS[printer].deviceAddress != address); printer++ );
if (printer == USB_MAX_PRINTER_DEVICES)
{
return USB_PRINTER_UNKNOWN_DEVICE;
}
}
switch( command )
{
//---------------------------------------------------------------------
case USB_PRINTER_ATTACHED:
for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListESCPOS[printer].deviceAddress != 0); printer++ );
if (printer != USB_MAX_PRINTER_DEVICES)
{
printerListESCPOS[printer].deviceAddress = address;
printerListESCPOS[printer].support = *((USB_PRINTER_FUNCTION_SUPPORT *)(data.pointerRAM));
printerListESCPOS[printer].printerFlags.value = 0;
return USB_PRINTER_SUCCESS;
}
return USB_PRINTER_TOO_MANY_DEVICES;
break;
//---------------------------------------------------------------------
case USB_PRINTER_DETACHED:
for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListESCPOS[printer].deviceAddress != address); printer++ );
if (printer != USB_MAX_PRINTER_DEVICES)
{
printerListESCPOS[printer].deviceAddress = 0;
}
return USB_PRINTER_SUCCESS;
break;
//---------------------------------------------------------------------
case USB_PRINTER_JOB_START:
_SetCurrentPosition( 0, 0 );
buffer = (char *)USB_MALLOC( 2 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
// Initialize printer
buffer[0] = ESC_CHAR;
buffer[1] = '@';
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, 2, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_JOB_STOP:
// For compatibility with full sheet operation, if we are in page
// mode, perform the USB_PRINTER_EJECT_PAGE command.
if (printerListESCPOS[printer].printerFlags.inPageMode)
{
goto EjectPage;
}
return USB_PRINTER_SUCCESS;
break;
//---------------------------------------------------------------------
case USB_PRINTER_FONT_NAME:
// If an illegal size is specified, return with an error.
if (size >= USB_PRINTER_FONT_POS_MAX_FONT)
{
return USB_PRINTER_BAD_PARAMETER;
}
switch ((uint8_t)size)
{
case USB_PRINTER_FONT_POS_18x36:
size = 0x00;
break;
case USB_PRINTER_FONT_POS_18x72:
size = 0x10;
break;
case USB_PRINTER_FONT_POS_36x36:
size = 0x20;
break;
case USB_PRINTER_FONT_POS_36x72:
size = 0x30;
break;
case USB_PRINTER_FONT_POS_12x24:
size = 0x01;
break;
case USB_PRINTER_FONT_POS_12x48:
size = 0x11;
break;
case USB_PRINTER_FONT_POS_24x24:
size = 0x21;
break;
case USB_PRINTER_FONT_POS_24x48:
size = 0x31;
break;
}
printerListESCPOS[printer].fontName = (uint8_t)size;
return _PrintFontCommand( printer, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_FONT_UPRIGHT:
// Italic printing is not supported, but we will not return an
// error if the user specifies upright.
return USB_PRINTER_SUCCESS;
break;
//---------------------------------------------------------------------
case USB_PRINTER_FONT_BOLD:
printerListESCPOS[printer].printerFlags.isBold = 1;
return _PrintFontCommand( printer, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_FONT_MEDIUM:
printerListESCPOS[printer].printerFlags.isBold = 0;
return _PrintFontCommand( printer, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_EJECT_PAGE:
EjectPage:
buffer = (char *)USB_MALLOC( 1 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
buffer[0] = FF_CHAR;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, 1, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_TEXT_START:
// No text initialization is required.
return USB_PRINTER_SUCCESS;
break;
//---------------------------------------------------------------------
case USB_PRINTER_TEXT:
case USB_PRINTER_TRANSPARENT:
// If the user's data is in ROM, we have to copy it to RAM first,
// so the USB Host routines can read it.
if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
{
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
}
if (transferFlags & USB_PRINTER_TRANSFER_COPY_DATA)
{
buffer = (char *)USB_MALLOC( size );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
{
uint32_t di;
#if defined( __C30__ ) || defined __XC16__
char __prog__ *ptr;
#elif defined( __PIC32MX__ )
const char *ptr;
#endif
ptr = ((USB_DATA_POINTER)data).pointerROM;
for (di=0; di<size; di++)
{
buffer[di] = *ptr++;
}
}
else
{
uint32_t di;
char *ptr;
ptr = ((USB_DATA_POINTER)data).pointerRAM;
for (di=0; di<size; di++)
{
buffer[di] = *ptr++;
}
}
}
else
{
buffer = ((USB_DATA_POINTER)data).pointerRAM;
}
return USBHostPrinterWrite( address, buffer, size, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_TEXT_STOP:
buffer = (char *)USB_MALLOC( 3 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
buffer[0] = ESC_CHAR;
buffer[1] = 'd';
buffer[2] = (uint8_t)size;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, 3, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_IMAGE_START:
#define VERTICAL_DENSITY ((USB_PRINTER_IMAGE_INFO *)(data.pointerRAM))->densityVertical
#define HORIZONTAL_DENSITY ((USB_PRINTER_IMAGE_INFO *)(data.pointerRAM))->densityHorizontal
// Check for legal density settings.
#if defined( USB_PRINTER_POS_24_DOT_IMAGE_SUPPORT ) && defined( USB_PRINTER_POS_36_DOT_IMAGE_SUPPORT )
if (!((VERTICAL_DENSITY == 8) || (VERTICAL_DENSITY == 24) || (VERTICAL_DENSITY == 36)))
#elif defined( USB_PRINTER_POS_24_DOT_IMAGE_SUPPORT ) && !defined( USB_PRINTER_POS_36_DOT_IMAGE_SUPPORT )
if (!((VERTICAL_DENSITY == 8) || (VERTICAL_DENSITY == 24)))
#else
if (!((VERTICAL_DENSITY == 8)))
#endif
{
return USB_PRINTER_BAD_PARAMETER;
}
if (!((HORIZONTAL_DENSITY == 1) || (HORIZONTAL_DENSITY == 2)))
{
return USB_PRINTER_BAD_PARAMETER;
}
// Set up dot density specification.
printerListESCPOS[printer].density = 0; // 8-dot image
printerListESCPOS[printer].imageDataWidth = 1;
#if defined( USB_PRINTER_POS_24_DOT_IMAGE_SUPPORT ) && !defined( USB_PRINTER_POS_36_DOT_IMAGE_SUPPORT )
if (VERTICAL_DENSITY == 24)
{
printerListESCPOS[printer].density = 32;
printerListESCPOS[printer].imageDataWidth = 3;
}
#elif defined( USB_PRINTER_POS_24_DOT_IMAGE_SUPPORT ) && defined( USB_PRINTER_POS_36_DOT_IMAGE_SUPPORT )
if (VERTICAL_DENSITY == 24)
{
printerListESCPOS[printer].density = 16;
printerListESCPOS[printer].imageDataWidth = 3;
}
if (VERTICAL_DENSITY == 36)
{
printerListESCPOS[printer].density = 32;
printerListESCPOS[printer].imageDataWidth = 5;
}
#endif
if (HORIZONTAL_DENSITY == 2)
{
printerListESCPOS[printer].density ++;
}
printerListESCPOS[printer].imageWidth = ((USB_PRINTER_IMAGE_INFO *)(data.pointerRAM))->width;
buffer = (char *)USB_MALLOC( 3 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
i = 0;
// Set line spacing to 8 dots, so there are no gaps between the image lines.
buffer[i++] = ESC_CHAR;
buffer[i++] = '3';
buffer[i++] = USB_PRINTER_POS_IMAGE_LINE_SPACING;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, i, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_IMAGE_DATA_HEADER:
buffer = (char *)USB_MALLOC( 6 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
i = 0;
buffer[i++] = LF_CHAR;
buffer[i++] = ESC_CHAR;
buffer[i++] = '*';
buffer[i++] = printerListESCPOS[printer].density;
buffer[i++] = printerListESCPOS[printer].imageWidth & 0xFF;
buffer[i++] = printerListESCPOS[printer].imageWidth >> 8;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, i, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_IMAGE_DATA:
// The polarity of POS raster graphics (0=white, 1=black) is
// backwards from other printer languages and the graphics library.
// To maintain compatibility, the values will be flipped for all
// copied data.
// For ESC/POS, the amount of data to transfer is the width of the
// image times the byte depth of the data, as specified by the
// vertical dot density.
size *= printerListESCPOS[printer].imageDataWidth;
// If the user's data is in ROM, we have to copy it to RAM first,
// so the USB Host routines can read it.
if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
{
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
}
if (transferFlags & USB_PRINTER_TRANSFER_COPY_DATA)
{
buffer = (char *)USB_MALLOC( size );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
{
#if defined( __C30__ ) || defined __XC16__
char __prog__ *ptr;
#elif defined( __PIC32MX__ )
const char *ptr;
#endif
uint32_t i;
ptr = ((USB_DATA_POINTER)data).pointerROM;
for (i=0; i<size; i++)
{
buffer[i] = ~(*ptr++);
}
}
else
{
char *ptr;
uint32_t i;
ptr = ((USB_DATA_POINTER)data).pointerRAM;
for (i=0; i<size; i++)
{
buffer[i] = ~(*ptr++);
}
}
}
else
{
buffer = ((USB_DATA_POINTER)data).pointerRAM;
}
return USBHostPrinterWrite( address, buffer, size, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_IMAGE_STOP:
// No termination required.
//return USB_PRINTER_SUCCESS;
buffer = (char *)USB_MALLOC( 3 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
i = 0;
// Set line spacing back to the default
buffer[i++] = ESC_CHAR;
buffer[i++] = '2';
// Feed after the last line.
buffer[i++] = LF_CHAR;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, i, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_POS_STANDARD_MODE:
printerListESCPOS[printer].printerFlags.inPageMode = 0;
return _PrintStaticCommand( printer, COMMAND_MODE_STANDARD, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_POS_FEED:
// Make sure the data pointer is NULL.
data.pointerRAM = NULL;
// Fall through the USB_PRINTER_POS_TEXT_LINE command processing.
//---------------------------------------------------------------------
case USB_PRINTER_POS_TEXT_LINE:
if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
{
return USB_PRINTER_BAD_PARAMETER;
}
{
uint16_t length;
char *ptr;
length = 0;
ptr = ((USB_DATA_POINTER)data).pointerRAM;
if (ptr != NULL)
{
length = strlen( ptr );
}
buffer = (char *)USB_MALLOC( length + 3 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
for (i=0; i<length; i++)
{
buffer[i] = *ptr++;
}
buffer[i++] = ESC_CHAR;
buffer[i++] = 'd';
buffer[i++] = (uint8_t)size;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, length + 3, transferFlags );
}
break;
//---------------------------------------------------------------------
#ifdef USB_PRINTER_POS_CUTTER_SUPPORT
case USB_PRINTER_POS_CUT:
case USB_PRINTER_POS_CUT_PARTIAL:
// Using Function B
buffer = (char *)USB_MALLOC( 4 );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
// Copy cut command.
buffer[0] = GS_CHAR;
buffer[1] = 'V';
buffer[2] = 65; // Full cut
// Replace partial cut if necessary.
if (command == USB_PRINTER_POS_CUT_PARTIAL)
{
buffer[2] = 66;
}
// Fill in feed amount. The default vertical motion unit varies
// between printers (often 1/360 inch). Not all printers can
// change this value.
buffer[3] = (char)size;
USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
return USBHostPrinterWrite( printerListESCPOS[printer].deviceAddress, buffer, 4, transferFlags );
break;
#endif
//---------------------------------------------------------------------
case USB_PRINTER_POS_JUSTIFICATION_CENTER:
return _PrintStaticCommand( printer, COMMAND_JUSTIFY_CENTER, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_POS_JUSTIFICATION_LEFT:
return _PrintStaticCommand( printer, COMMAND_JUSTIFY_LEFT, transferFlags );
break;
//---------------------------------------------------------------------
case USB_PRINTER_POS_JUSTIFICATION_RIGHT:
return _PrintStaticCommand( printer, COMMAND_JUSTIFY_RIGHT, transferFlags );
break;
//---------------------------------------------------------------------
#ifdef USB_PRINTER_POS_REVERSE_TEXT_SUPPORT
case USB_PRINTER_POS_FONT_REVERSE:
printerListESCPOS[printer].printerFlags.reversePrint = size & 0x01;
if (size == 0)
{
return _PrintStaticCommand( printer, COMMAND_FONT_REVERSE_OFF, transferFlags );
}
else
{
return _PrintStaticCommand( printer, COMMAND_FONT_REVERSE_ON, transferFlags );
}
break;
#endif
//---------------------------------------------------------------------
case USB_PRINTER_POS_FONT_UNDERLINE:
printerListESCPOS[printer].printerFlags.isUnderlined = size & 0x01;
return _PrintFontCommand( printer, transferFlags );
break;
//---------------------------------------------------------------------
#ifdef USB_PRINTER_POS_TWO_COLOR_SUPPORT
case USB_PRINTER_POS_COLOR_BLACK:
return _PrintStaticCommand( printer, COMMAND_COLOR_BLACK, transferFlags );
break;
#endif
//---------------------------------------------------------------------
#ifdef USB_PRINTER_POS_TWO_COLOR_SUPPORT
case USB_PRINTER_POS_COLOR_RED:
return _PrintStaticCommand( printer, COMMAND_COLOR_RED, transferFlags );
break;
#endif
//---------------------------------------------------------------------
#ifdef USB_PRINTER_POS_BARCODE_SUPPORT
case USB_PRINTER_POS_BARCODE:
{
#define BCD (uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.data
uint16_t j;
uint8_t dataLength; // The length of the bar code data, possibly adjusted for a checkdigit.
dataLength = ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.dataLength;
// Do any preprocessing required for the particular bar code type.
switch ((uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.type)
{
case USB_PRINTER_POS_BARCODE_UPC_A:
// Validate the data length.
if (dataLength != 11)
{
return USB_PRINTER_BAD_PARAMETER;
}
break;
case USB_PRINTER_POS_BARCODE_UPC_E:
// Validate the data length.
if (!((dataLength == 6) || (dataLength == 7) || (dataLength == 11)))
{
return USB_PRINTER_BAD_PARAMETER;
}
// If the length is not 6, then the first data byte must be '0'.
if ((dataLength != 6) && (BCD[0] != '0'))
{
return USB_PRINTER_BAD_PARAMETER;
}
break;
case USB_PRINTER_POS_BARCODE_EAN13:
// Validate the data length.
if (dataLength != 12)
{
return USB_PRINTER_BAD_PARAMETER;
}
break;
case USB_PRINTER_POS_BARCODE_EAN8:
// Validate the data length, and that the first byte is '0'.
if ((dataLength != 7) || (BCD[0] != '0'))
{
return USB_PRINTER_BAD_PARAMETER;
}
break;
case USB_PRINTER_POS_BARCODE_CODE39:
case USB_PRINTER_POS_BARCODE_CODABAR:
if ((uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.flags.bits.bPrintCheckDigit)
{
// Add one for the check digit that we will add.
dataLength ++;
}
break;
case USB_PRINTER_POS_BARCODE_ITF:
// Validate that the data length is an even number
if (dataLength & 0x01)
{
return USB_PRINTER_BAD_PARAMETER;
}
break;
#ifdef USE_PRINTER_POS_EXTENDED_BARCODE_FORMAT
case USB_PRINTER_POS_BARCODE_CODE93:
case USB_PRINTER_POS_BARCODE_CODE128:
// No special checks are required.
break;
case USB_PRINTER_POS_BARCODE_EAN128:
// NOT YET SUPPORTED
return USB_PRINTER_BAD_PARAMETER;
break;
#endif
default:
// Invalid bar code format.
return USB_PRINTER_BAD_PARAMETER;
break;
}
buffer = (char *)USB_MALLOC( 21 + dataLength );
if (buffer == NULL)
{
return USB_PRINTER_OUT_OF_MEMORY;
}
i = 0;
// Set barcode height.
buffer[i++] = GS_CHAR;
buffer[i++] = 'h';
buffer[i++] = (uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.height;
// Set readable characters position.
buffer[i++] = GS_CHAR;
buffer[i++] = 'H';
buffer[i++] = (uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.textPosition;
// Set readable characters font.
buffer[i++] = GS_CHAR;
buffer[i++] = 'f';
buffer[i++] = (uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.textFont;
// Print the bar code.
buffer[i++] = GS_CHAR;
buffer[i++] = 'k';
#ifdef USE_PRINTER_POS_EXTENDED_BARCODE_FORMAT
// Use format 2
buffer[i++] = barCodeFormats[(uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.type];
buffer[i++] = dataLength;
#else
// Use format 1
buffer[i++] = (uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.type;
#endif
// Put in the data as required for each particular bar code type.
switch ((uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.type)
{
case USB_PRINTER_POS_BARCODE_UPC_A:
case USB_PRINTER_POS_BARCODE_UPC_E:
case USB_PRINTER_POS_BARCODE_EAN13:
case USB_PRINTER_POS_BARCODE_EAN8:
// Copy the data for printing.
for (j=0; j<dataLength; j++)
{
buffer[i++] = BCD[j];
}
// UPC and EAN bar codes have a check digit, but we will let the
// printer calculate the check digit for us!
break;
case USB_PRINTER_POS_BARCODE_CODE39:
if ((uint8_t)((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBarCode.flags.bits.bPrintCheckDigit)
{
// These must all be ASCII, so copy them straight over.
// Our length already accounts for the check digit that
// we will add.
for (j=0; j<dataLength-1; j++)
{
buffer[i++] = BCD[j];
}
// Calculate the check digit. The printer will not automatically
// calculate and print the checkdigit for this format.
{
uint16_t sum = 0;
for (j=0; j<dataLength-1; j++)
{
sum += _BarcodeCharacterValueCode39( BCD[j] );
}
sum %= 43;
buffer[i++] = _BarcodeValueCharacterCode39( sum );
}
}
else
{
// These must all be ASCII, so copy them straight over.
for (j=0; j<dataLength; j++)
{