This program implements the negotiation phase and emulates a printer. It can be plugged on the parallel port of a PC. It\'s a test program

Dependencies:   mbed

Committer:
jpelletier
Date:
Sat May 07 23:08:51 2011 +0000
Revision:
0:8133df8bab0f
Alpha version (may not work perfectly)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jpelletier 0:8133df8bab0f 1 #include "mbed.h"
jpelletier 0:8133df8bab0f 2
jpelletier 0:8133df8bab0f 3
jpelletier 0:8133df8bab0f 4 #include <stdarg.h>
jpelletier 0:8133df8bab0f 5 #include <stdio.h>
jpelletier 0:8133df8bab0f 6 #include <stdlib.h>
jpelletier 0:8133df8bab0f 7 #include <string.h>
jpelletier 0:8133df8bab0f 8
jpelletier 0:8133df8bab0f 9 #define PAR_NEGOTIATE_EXTENSIBILITY_LINK 0x80
jpelletier 0:8133df8bab0f 10 #define PAR_NEGOTIATE_REQ_EPP_MODE 0x40
jpelletier 0:8133df8bab0f 11 #define PAR_NEGOTIATE_REQ_ECP_MODE 0x10
jpelletier 0:8133df8bab0f 12 #define PAR_NEGOTIATE_REQ_ECP_RLE_MODE 0x30
jpelletier 0:8133df8bab0f 13 #define PAR_NEGOTIATE_REQ_DEV_ID_NIBBLE_MODE 0x04
jpelletier 0:8133df8bab0f 14 #define PAR_NEGOTIATE_REQ_DEV_ID_BYTE_MODE 0x05
jpelletier 0:8133df8bab0f 15 #define PAR_NEGOTIATE_REQ_DEV_ID_ECP_MODE 0x14
jpelletier 0:8133df8bab0f 16 #define PAR_NEGOTIATE_REQ_DEV_ID_ECP_RLE_MODE 0x34
jpelletier 0:8133df8bab0f 17 #define PAR_NEGOTIATE_NIBBLE_MODE 0x00
jpelletier 0:8133df8bab0f 18 #define PAR_NEGOTIATE_BYTE_MODE 0x01
jpelletier 0:8133df8bab0f 19
jpelletier 0:8133df8bab0f 20 /*
jpelletier 0:8133df8bab0f 21 15 nError -> p9
jpelletier 0:8133df8bab0f 22 13 Select -> p10
jpelletier 0:8133df8bab0f 23 12 PE -> p11
jpelletier 0:8133df8bab0f 24 11 Busy -> p12
jpelletier 0:8133df8bab0f 25 10 nAck -> p13
jpelletier 0:8133df8bab0f 26
jpelletier 0:8133df8bab0f 27 1 nStrobe -> p14
jpelletier 0:8133df8bab0f 28 14 nAutoFeed -> p15
jpelletier 0:8133df8bab0f 29 16 nInit -> p16
jpelletier 0:8133df8bab0f 30 17 nSelectIn -> p17
jpelletier 0:8133df8bab0f 31 */
jpelletier 0:8133df8bab0f 32
jpelletier 0:8133df8bab0f 33 DigitalOut nError(p9);
jpelletier 0:8133df8bab0f 34 DigitalOut Select(p10);
jpelletier 0:8133df8bab0f 35 DigitalOut PaperOut(p11);
jpelletier 0:8133df8bab0f 36 DigitalOut Busy(p12);
jpelletier 0:8133df8bab0f 37 DigitalOut nAck(p13);
jpelletier 0:8133df8bab0f 38
jpelletier 0:8133df8bab0f 39 DigitalIn nStrobe(p14);
jpelletier 0:8133df8bab0f 40 DigitalIn nAutoFeed(p15);
jpelletier 0:8133df8bab0f 41 DigitalIn nInit(p16);
jpelletier 0:8133df8bab0f 42 DigitalIn nSelectIn(p17);
jpelletier 0:8133df8bab0f 43
jpelletier 0:8133df8bab0f 44 /*
jpelletier 0:8133df8bab0f 45 D0 p30 p0.4
jpelletier 0:8133df8bab0f 46 D1 p29 p0.5
jpelletier 0:8133df8bab0f 47 D2 p8 p0.6
jpelletier 0:8133df8bab0f 48 D3 p7 p0.7
jpelletier 0:8133df8bab0f 49 D4 p6 p0.8
jpelletier 0:8133df8bab0f 50 D5 p5 p0.9
jpelletier 0:8133df8bab0f 51 D6 p28 p0.10
jpelletier 0:8133df8bab0f 52 D7 p27 p0.11
jpelletier 0:8133df8bab0f 53 */
jpelletier 0:8133df8bab0f 54 BusInOut PtrData(p30,p29,p8,p7,p6,p5,p28,p27);
jpelletier 0:8133df8bab0f 55
jpelletier 0:8133df8bab0f 56 #define __DOUTBUFSIZE 256
jpelletier 0:8133df8bab0f 57 #define __DINBUFSIZE 256
jpelletier 0:8133df8bab0f 58 char __outstr[__DOUTBUFSIZE];
jpelletier 0:8133df8bab0f 59 char __instr[__DINBUFSIZE];
jpelletier 0:8133df8bab0f 60
jpelletier 0:8133df8bab0f 61 Serial pc(USBTX, USBRX); // tx, rx
jpelletier 0:8133df8bab0f 62 DigitalOut myled1(LED1);
jpelletier 0:8133df8bab0f 63 DigitalOut myled2(LED2);
jpelletier 0:8133df8bab0f 64 DigitalOut myled3(LED3);
jpelletier 0:8133df8bab0f 65 DigitalOut myled4(LED4);
jpelletier 0:8133df8bab0f 66
jpelletier 0:8133df8bab0f 67 //---------------------------------------------------------------------------------
jpelletier 0:8133df8bab0f 68 void printer_side_ecp_mode_write_data(char c)
jpelletier 0:8133df8bab0f 69 {
jpelletier 0:8133df8bab0f 70 /* Write data */
jpelletier 0:8133df8bab0f 71 Busy = 1;
jpelletier 0:8133df8bab0f 72 PtrData = c;
jpelletier 0:8133df8bab0f 73
jpelletier 0:8133df8bab0f 74 /* Wait HostAck = L (nAutoFd) */
jpelletier 0:8133df8bab0f 75 while (nAutoFeed) {}
jpelletier 0:8133df8bab0f 76
jpelletier 0:8133df8bab0f 77 /* Set PeriphClk = L (nAck) */
jpelletier 0:8133df8bab0f 78 nAck = 0;
jpelletier 0:8133df8bab0f 79
jpelletier 0:8133df8bab0f 80 /* Wait HostAck = H (nAutoFd) */
jpelletier 0:8133df8bab0f 81 while (!nAutoFeed) {}
jpelletier 0:8133df8bab0f 82
jpelletier 0:8133df8bab0f 83 /* Set PeriphClk = H (nAck) */
jpelletier 0:8133df8bab0f 84 nAck = 1;
jpelletier 0:8133df8bab0f 85 }
jpelletier 0:8133df8bab0f 86
jpelletier 0:8133df8bab0f 87 void printer_side_ecp_mode_write_cmd(char c)
jpelletier 0:8133df8bab0f 88 {
jpelletier 0:8133df8bab0f 89 /* Wait HostAck = L (nAutoFd) */
jpelletier 0:8133df8bab0f 90 while (nAutoFeed) {}
jpelletier 0:8133df8bab0f 91
jpelletier 0:8133df8bab0f 92 /* Write command */
jpelletier 0:8133df8bab0f 93 Busy = 0;
jpelletier 0:8133df8bab0f 94 PtrData = c;
jpelletier 0:8133df8bab0f 95
jpelletier 0:8133df8bab0f 96 /* Set PeriphClk = L (nAck) */
jpelletier 0:8133df8bab0f 97 nAck = 0;
jpelletier 0:8133df8bab0f 98
jpelletier 0:8133df8bab0f 99 /* Wait HostAck = H (nAutoFd) */
jpelletier 0:8133df8bab0f 100 while (!nAutoFeed) {}
jpelletier 0:8133df8bab0f 101
jpelletier 0:8133df8bab0f 102 /* Set PeriphClk = H (nAck) */
jpelletier 0:8133df8bab0f 103 nAck = 1;
jpelletier 0:8133df8bab0f 104 }
jpelletier 0:8133df8bab0f 105
jpelletier 0:8133df8bab0f 106 void printer_side_ecp_sendblock(char *str, int len)
jpelletier 0:8133df8bab0f 107 {
jpelletier 0:8133df8bab0f 108 PtrData.output();
jpelletier 0:8133df8bab0f 109
jpelletier 0:8133df8bab0f 110 while (len--)
jpelletier 0:8133df8bab0f 111 {
jpelletier 0:8133df8bab0f 112 printer_side_ecp_mode_write_data(*str);
jpelletier 0:8133df8bab0f 113 ++str;
jpelletier 0:8133df8bab0f 114 }
jpelletier 0:8133df8bab0f 115
jpelletier 0:8133df8bab0f 116 PtrData.input();
jpelletier 0:8133df8bab0f 117 }
jpelletier 0:8133df8bab0f 118
jpelletier 0:8133df8bab0f 119 void printer_side_ecp_printf(char *str, ...)
jpelletier 0:8133df8bab0f 120 {
jpelletier 0:8133df8bab0f 121 va_list args;
jpelletier 0:8133df8bab0f 122 int len;
jpelletier 0:8133df8bab0f 123
jpelletier 0:8133df8bab0f 124 va_start(args, str);
jpelletier 0:8133df8bab0f 125 len=vsnprintf(__outstr,__DOUTBUFSIZE,str,args);
jpelletier 0:8133df8bab0f 126 va_end(args);
jpelletier 0:8133df8bab0f 127
jpelletier 0:8133df8bab0f 128 printer_side_ecp_sendblock(__outstr,len);
jpelletier 0:8133df8bab0f 129 }
jpelletier 0:8133df8bab0f 130
jpelletier 0:8133df8bab0f 131 //---------------------------------------------------------------------------------
jpelletier 0:8133df8bab0f 132 void printer_side_ecprle_sendblock(char *str, int len)
jpelletier 0:8133df8bab0f 133 {
jpelletier 0:8133df8bab0f 134 int rle = 0;
jpelletier 0:8133df8bab0f 135 char c;
jpelletier 0:8133df8bab0f 136
jpelletier 0:8133df8bab0f 137 PtrData.output();
jpelletier 0:8133df8bab0f 138
jpelletier 0:8133df8bab0f 139 while (len--)
jpelletier 0:8133df8bab0f 140 {
jpelletier 0:8133df8bab0f 141 c = *str;
jpelletier 0:8133df8bab0f 142 while (*(++str) == c) {++rle;}
jpelletier 0:8133df8bab0f 143
jpelletier 0:8133df8bab0f 144 if (rle != 0)
jpelletier 0:8133df8bab0f 145 {
jpelletier 0:8133df8bab0f 146 printer_side_ecp_mode_write_cmd(rle);
jpelletier 0:8133df8bab0f 147 rle = 0;
jpelletier 0:8133df8bab0f 148 }
jpelletier 0:8133df8bab0f 149 printer_side_ecp_mode_write_data(c);
jpelletier 0:8133df8bab0f 150 }
jpelletier 0:8133df8bab0f 151
jpelletier 0:8133df8bab0f 152 PtrData.input();
jpelletier 0:8133df8bab0f 153 }
jpelletier 0:8133df8bab0f 154
jpelletier 0:8133df8bab0f 155 void printer_side_ecprle_printf(char *str, ...)
jpelletier 0:8133df8bab0f 156 {
jpelletier 0:8133df8bab0f 157 va_list args;
jpelletier 0:8133df8bab0f 158 int len;
jpelletier 0:8133df8bab0f 159
jpelletier 0:8133df8bab0f 160 va_start(args, str);
jpelletier 0:8133df8bab0f 161 len=vsnprintf(__outstr,__DOUTBUFSIZE,str,args);
jpelletier 0:8133df8bab0f 162 va_end(args);
jpelletier 0:8133df8bab0f 163
jpelletier 0:8133df8bab0f 164 printer_side_ecprle_sendblock(__outstr,len);
jpelletier 0:8133df8bab0f 165 }
jpelletier 0:8133df8bab0f 166
jpelletier 0:8133df8bab0f 167 //---------------------------------------------------------------------------------
jpelletier 0:8133df8bab0f 168 void printer_side_byte_mode_write(char c)
jpelletier 0:8133df8bab0f 169 {
jpelletier 0:8133df8bab0f 170 /* Wait HostBusy = L (nAutoFd) */
jpelletier 0:8133df8bab0f 171 while (nAutoFeed) {}
jpelletier 0:8133df8bab0f 172
jpelletier 0:8133df8bab0f 173 PtrData = c;
jpelletier 0:8133df8bab0f 174
jpelletier 0:8133df8bab0f 175 /* Set PtrClk = L (nAck) */
jpelletier 0:8133df8bab0f 176 nAck = 0;
jpelletier 0:8133df8bab0f 177
jpelletier 0:8133df8bab0f 178 /* Wait HostBusy = H (nAutoFd) */
jpelletier 0:8133df8bab0f 179 while (!nAutoFeed) {}
jpelletier 0:8133df8bab0f 180
jpelletier 0:8133df8bab0f 181 /* Set PtrClk = H (nAck) */
jpelletier 0:8133df8bab0f 182 nAck = 1;
jpelletier 0:8133df8bab0f 183
jpelletier 0:8133df8bab0f 184 /* Wait HostClk = L (nStrobe) */
jpelletier 0:8133df8bab0f 185 while (nStrobe) {}
jpelletier 0:8133df8bab0f 186
jpelletier 0:8133df8bab0f 187 /* Wait HostClk = H (nStrobe) */
jpelletier 0:8133df8bab0f 188 while (!nStrobe) {}
jpelletier 0:8133df8bab0f 189 }
jpelletier 0:8133df8bab0f 190
jpelletier 0:8133df8bab0f 191 void printer_side_byte_sendblock(char *str, int len)
jpelletier 0:8133df8bab0f 192 {
jpelletier 0:8133df8bab0f 193 PtrData.output();
jpelletier 0:8133df8bab0f 194
jpelletier 0:8133df8bab0f 195 while (len--)
jpelletier 0:8133df8bab0f 196 {
jpelletier 0:8133df8bab0f 197 printer_side_byte_mode_write(*str);
jpelletier 0:8133df8bab0f 198 ++str;
jpelletier 0:8133df8bab0f 199 }
jpelletier 0:8133df8bab0f 200
jpelletier 0:8133df8bab0f 201 PtrData.input();
jpelletier 0:8133df8bab0f 202 }
jpelletier 0:8133df8bab0f 203
jpelletier 0:8133df8bab0f 204 void printer_side_byte_printf(char *str, ...)
jpelletier 0:8133df8bab0f 205 {
jpelletier 0:8133df8bab0f 206 va_list args;
jpelletier 0:8133df8bab0f 207 int len;
jpelletier 0:8133df8bab0f 208
jpelletier 0:8133df8bab0f 209 va_start(args, str);
jpelletier 0:8133df8bab0f 210 len=vsnprintf(__outstr,__DOUTBUFSIZE,str,args);
jpelletier 0:8133df8bab0f 211 va_end(args);
jpelletier 0:8133df8bab0f 212
jpelletier 0:8133df8bab0f 213 printer_side_byte_sendblock(__outstr,len);
jpelletier 0:8133df8bab0f 214 }
jpelletier 0:8133df8bab0f 215
jpelletier 0:8133df8bab0f 216 //---------------------------------------------------------------------------------
jpelletier 0:8133df8bab0f 217 /*
jpelletier 0:8133df8bab0f 218 Busy, PE,Select,nError 3-0,7-4
jpelletier 0:8133df8bab0f 219 */
jpelletier 0:8133df8bab0f 220 void printer_side_write_nibble(char c)
jpelletier 0:8133df8bab0f 221 {
jpelletier 0:8133df8bab0f 222 /* Wait HostBusy = L (nAutoFd) */
jpelletier 0:8133df8bab0f 223 while (nAutoFeed) {}
jpelletier 0:8133df8bab0f 224
jpelletier 0:8133df8bab0f 225 nError = c & 0x01;
jpelletier 0:8133df8bab0f 226 Select = (c & 0x02) >> 1;
jpelletier 0:8133df8bab0f 227 PaperOut = (c & 0x04) >> 2;
jpelletier 0:8133df8bab0f 228 Busy = (c & 0x08) >> 3;
jpelletier 0:8133df8bab0f 229
jpelletier 0:8133df8bab0f 230 /* Set PtrClk = H (nAck) */
jpelletier 0:8133df8bab0f 231 nAck = 1;
jpelletier 0:8133df8bab0f 232
jpelletier 0:8133df8bab0f 233 /* Set PtrClk = L (nAck) */
jpelletier 0:8133df8bab0f 234 nAck = 0;
jpelletier 0:8133df8bab0f 235
jpelletier 0:8133df8bab0f 236 /* Wait HostBusy = H (nAutoFd) */
jpelletier 0:8133df8bab0f 237 while (!nAutoFeed) {}
jpelletier 0:8133df8bab0f 238
jpelletier 0:8133df8bab0f 239 /* Set PtrClk = H (nAck) */
jpelletier 0:8133df8bab0f 240 nAck = 1;
jpelletier 0:8133df8bab0f 241 }
jpelletier 0:8133df8bab0f 242
jpelletier 0:8133df8bab0f 243 void printer_side_nibble_mode_write(char c)
jpelletier 0:8133df8bab0f 244 {
jpelletier 0:8133df8bab0f 245 // data available
jpelletier 0:8133df8bab0f 246 nError = 0;
jpelletier 0:8133df8bab0f 247 printer_side_write_nibble(c); // Low
jpelletier 0:8133df8bab0f 248 printer_side_write_nibble(c >> 4); // High
jpelletier 0:8133df8bab0f 249
jpelletier 0:8133df8bab0f 250 nError = 0;
jpelletier 0:8133df8bab0f 251 }
jpelletier 0:8133df8bab0f 252
jpelletier 0:8133df8bab0f 253 void printer_side_nibble_sendblock(char *str, int len)
jpelletier 0:8133df8bab0f 254 {
jpelletier 0:8133df8bab0f 255 while (len--)
jpelletier 0:8133df8bab0f 256 {
jpelletier 0:8133df8bab0f 257 printer_side_nibble_mode_write(*str);
jpelletier 0:8133df8bab0f 258 ++str;
jpelletier 0:8133df8bab0f 259 }
jpelletier 0:8133df8bab0f 260 }
jpelletier 0:8133df8bab0f 261
jpelletier 0:8133df8bab0f 262 void printer_side_nibble_printf(char *str, ...)
jpelletier 0:8133df8bab0f 263 {
jpelletier 0:8133df8bab0f 264 va_list args;
jpelletier 0:8133df8bab0f 265 int len;
jpelletier 0:8133df8bab0f 266
jpelletier 0:8133df8bab0f 267 va_start(args, str);
jpelletier 0:8133df8bab0f 268 len=vsnprintf(__outstr,__DOUTBUFSIZE,str,args);
jpelletier 0:8133df8bab0f 269 va_end(args);
jpelletier 0:8133df8bab0f 270
jpelletier 0:8133df8bab0f 271 printer_side_nibble_sendblock(__outstr,len);
jpelletier 0:8133df8bab0f 272 }
jpelletier 0:8133df8bab0f 273
jpelletier 0:8133df8bab0f 274 //---------------------------------------------------------------------------------
jpelletier 0:8133df8bab0f 275 unsigned char printer_side_read_char(void)
jpelletier 0:8133df8bab0f 276 {
jpelletier 0:8133df8bab0f 277 unsigned char c;
jpelletier 0:8133df8bab0f 278
jpelletier 0:8133df8bab0f 279 /* When Strobe detected, set Busy */
jpelletier 0:8133df8bab0f 280 while (nStrobe) {}
jpelletier 0:8133df8bab0f 281
jpelletier 0:8133df8bab0f 282 Busy = 1;
jpelletier 0:8133df8bab0f 283
jpelletier 0:8133df8bab0f 284 /* Read data lines */
jpelletier 0:8133df8bab0f 285 c = PtrData;
jpelletier 0:8133df8bab0f 286
jpelletier 0:8133df8bab0f 287 /* Send nACK pulse */
jpelletier 0:8133df8bab0f 288 Busy = 0;
jpelletier 0:8133df8bab0f 289 nAck = 0;
jpelletier 0:8133df8bab0f 290 nAck = 1;
jpelletier 0:8133df8bab0f 291
jpelletier 0:8133df8bab0f 292 return c;
jpelletier 0:8133df8bab0f 293 }
jpelletier 0:8133df8bab0f 294
jpelletier 0:8133df8bab0f 295 unsigned char printer_side_negotiate(void)
jpelletier 0:8133df8bab0f 296 {
jpelletier 0:8133df8bab0f 297 unsigned char c;
jpelletier 0:8133df8bab0f 298
jpelletier 0:8133df8bab0f 299 /* Reply: Set nAck L, nERROR,PE, Select H */
jpelletier 0:8133df8bab0f 300 nAck = 0;
jpelletier 0:8133df8bab0f 301 nError = 1;
jpelletier 0:8133df8bab0f 302 PaperOut = 1;
jpelletier 0:8133df8bab0f 303 Select = 1;
jpelletier 0:8133df8bab0f 304
jpelletier 0:8133df8bab0f 305 /* Wait for nStrobe = L */
jpelletier 0:8133df8bab0f 306 while (nStrobe) {}
jpelletier 0:8133df8bab0f 307
jpelletier 0:8133df8bab0f 308 /* Read extensibility byte */
jpelletier 0:8133df8bab0f 309 c = PtrData;
jpelletier 0:8133df8bab0f 310
jpelletier 0:8133df8bab0f 311 /* Wait for nStrobe = H, nAUTOFEED = H */
jpelletier 0:8133df8bab0f 312 while (!(nStrobe & nAutoFeed)) {}
jpelletier 0:8133df8bab0f 313
jpelletier 0:8133df8bab0f 314 // pc.printf("Host requested mode: %02X\r\n",c & 0xff);
jpelletier 0:8133df8bab0f 315
jpelletier 0:8133df8bab0f 316 /* Reply: PE = L,
jpelletier 0:8133df8bab0f 317 nError = L if peripheral has reverse channel data available
jpelletier 0:8133df8bab0f 318
jpelletier 0:8133df8bab0f 319 if requested mode is
jpelletier 0:8133df8bab0f 320 Available, Select = H
jpelletier 0:8133df8bab0f 321 Not available, Select = L
jpelletier 0:8133df8bab0f 322 */
jpelletier 0:8133df8bab0f 323
jpelletier 0:8133df8bab0f 324 /* EPP not available */
jpelletier 0:8133df8bab0f 325 if (c == PAR_NEGOTIATE_REQ_EPP_MODE)
jpelletier 0:8133df8bab0f 326 {
jpelletier 0:8133df8bab0f 327 Select = 0;
jpelletier 0:8133df8bab0f 328 }
jpelletier 0:8133df8bab0f 329 else
jpelletier 0:8133df8bab0f 330 {
jpelletier 0:8133df8bab0f 331 Select = 1;
jpelletier 0:8133df8bab0f 332 }
jpelletier 0:8133df8bab0f 333
jpelletier 0:8133df8bab0f 334 nError = 0;
jpelletier 0:8133df8bab0f 335 PaperOut = 0;
jpelletier 0:8133df8bab0f 336 Busy = 0;
jpelletier 0:8133df8bab0f 337 nAck = 0;
jpelletier 0:8133df8bab0f 338
jpelletier 0:8133df8bab0f 339 wait_us(2);
jpelletier 0:8133df8bab0f 340
jpelletier 0:8133df8bab0f 341 /* Set nACK = H */
jpelletier 0:8133df8bab0f 342 nAck = 1;
jpelletier 0:8133df8bab0f 343
jpelletier 0:8133df8bab0f 344 return c;
jpelletier 0:8133df8bab0f 345 }
jpelletier 0:8133df8bab0f 346
jpelletier 0:8133df8bab0f 347 void compatibility_read(void)
jpelletier 0:8133df8bab0f 348 {
jpelletier 0:8133df8bab0f 349 unsigned char c;
jpelletier 0:8133df8bab0f 350 int i = 0;
jpelletier 0:8133df8bab0f 351
jpelletier 0:8133df8bab0f 352 while(nInit)
jpelletier 0:8133df8bab0f 353 {
jpelletier 0:8133df8bab0f 354 c = printer_side_read_char();
jpelletier 0:8133df8bab0f 355
jpelletier 0:8133df8bab0f 356 /* Set Busy active so that we can print the received value */
jpelletier 0:8133df8bab0f 357 Busy = 1;
jpelletier 0:8133df8bab0f 358
jpelletier 0:8133df8bab0f 359 pc.printf("%02X ",c & 0xff);
jpelletier 0:8133df8bab0f 360 ++i;
jpelletier 0:8133df8bab0f 361 if (i == 10)
jpelletier 0:8133df8bab0f 362 {
jpelletier 0:8133df8bab0f 363 i = 0;
jpelletier 0:8133df8bab0f 364 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 365 }
jpelletier 0:8133df8bab0f 366
jpelletier 0:8133df8bab0f 367 /* Set Busy inactive so that we can receive the following bytes */
jpelletier 0:8133df8bab0f 368 Busy = 0;
jpelletier 0:8133df8bab0f 369 }
jpelletier 0:8133df8bab0f 370 }
jpelletier 0:8133df8bab0f 371
jpelletier 0:8133df8bab0f 372 //===========================================================================
jpelletier 0:8133df8bab0f 373 int main(void)
jpelletier 0:8133df8bab0f 374 {
jpelletier 0:8133df8bab0f 375 unsigned char c;
jpelletier 0:8133df8bab0f 376 char data;
jpelletier 0:8133df8bab0f 377 int i = 0;
jpelletier 0:8133df8bab0f 378 int rle = 0;
jpelletier 0:8133df8bab0f 379
jpelletier 0:8133df8bab0f 380 pc.printf("Printer emulator on mbed\r\n");
jpelletier 0:8133df8bab0f 381
jpelletier 0:8133df8bab0f 382 // set the outputs to the host computer
jpelletier 0:8133df8bab0f 383 PtrData.input();
jpelletier 0:8133df8bab0f 384
jpelletier 0:8133df8bab0f 385 state_init:
jpelletier 0:8133df8bab0f 386 myled1 = 0;
jpelletier 0:8133df8bab0f 387 myled2 = 0;
jpelletier 0:8133df8bab0f 388 myled3 = 0;
jpelletier 0:8133df8bab0f 389 myled4 = 0;
jpelletier 0:8133df8bab0f 390
jpelletier 0:8133df8bab0f 391 while (!nInit) {}
jpelletier 0:8133df8bab0f 392
jpelletier 0:8133df8bab0f 393 Busy = 0;
jpelletier 0:8133df8bab0f 394 nAck = 1;
jpelletier 0:8133df8bab0f 395 nError = 1;
jpelletier 0:8133df8bab0f 396 PaperOut = 0;
jpelletier 0:8133df8bab0f 397 Select = 0;
jpelletier 0:8133df8bab0f 398
jpelletier 0:8133df8bab0f 399 if (!nStrobe)
jpelletier 0:8133df8bab0f 400 {
jpelletier 0:8133df8bab0f 401 /* Read data from PC compatibility mode */
jpelletier 0:8133df8bab0f 402 Busy = 1;
jpelletier 0:8133df8bab0f 403
jpelletier 0:8133df8bab0f 404 /* Read data lines */
jpelletier 0:8133df8bab0f 405 pc.printf("%02X ",PtrData & 0xff);
jpelletier 0:8133df8bab0f 406 ++i;
jpelletier 0:8133df8bab0f 407 if (i == 16)
jpelletier 0:8133df8bab0f 408 {
jpelletier 0:8133df8bab0f 409 i = 0;
jpelletier 0:8133df8bab0f 410 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 411 }
jpelletier 0:8133df8bab0f 412
jpelletier 0:8133df8bab0f 413 /* Wait for nSTROBE = H */
jpelletier 0:8133df8bab0f 414 while (!nStrobe) {}
jpelletier 0:8133df8bab0f 415
jpelletier 0:8133df8bab0f 416 /* Send nACK pulse */
jpelletier 0:8133df8bab0f 417 Busy = 0;
jpelletier 0:8133df8bab0f 418 nAck = 0;
jpelletier 0:8133df8bab0f 419 nAck = 1;
jpelletier 0:8133df8bab0f 420 goto state_init;
jpelletier 0:8133df8bab0f 421 }
jpelletier 0:8133df8bab0f 422
jpelletier 0:8133df8bab0f 423 else if (!(nSelectIn & !nAutoFeed))
jpelletier 0:8133df8bab0f 424 {
jpelletier 0:8133df8bab0f 425 goto state_init;
jpelletier 0:8133df8bab0f 426 }
jpelletier 0:8133df8bab0f 427
jpelletier 0:8133df8bab0f 428 /* Negotiation phase */
jpelletier 0:8133df8bab0f 429 /* PC: nSelectIn = H, nAUTOFEED = L */
jpelletier 0:8133df8bab0f 430 c = printer_side_negotiate();
jpelletier 0:8133df8bab0f 431
jpelletier 0:8133df8bab0f 432 switch(c)
jpelletier 0:8133df8bab0f 433 {
jpelletier 0:8133df8bab0f 434 case PAR_NEGOTIATE_REQ_EPP_MODE: // Not available
jpelletier 0:8133df8bab0f 435 goto state_init;
jpelletier 0:8133df8bab0f 436
jpelletier 0:8133df8bab0f 437 case PAR_NEGOTIATE_REQ_DEV_ID_ECP_MODE:
jpelletier 0:8133df8bab0f 438 case PAR_NEGOTIATE_REQ_ECP_MODE:
jpelletier 0:8133df8bab0f 439 state_ecp_mode:
jpelletier 0:8133df8bab0f 440 // PARPORT_CMD_ECP_INIT1
jpelletier 0:8133df8bab0f 441 // PARPORT_CMD_ECP_INIT2
jpelletier 0:8133df8bab0f 442 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 443
jpelletier 0:8133df8bab0f 444 // PARPORT_CMD_ECP_READ
jpelletier 0:8133df8bab0f 445 if (nStrobe)
jpelletier 0:8133df8bab0f 446 {
jpelletier 0:8133df8bab0f 447 // data available
jpelletier 0:8133df8bab0f 448 nError = 0;
jpelletier 0:8133df8bab0f 449
jpelletier 0:8133df8bab0f 450 /* Acknowledge the reverse transfer request */
jpelletier 0:8133df8bab0f 451 PaperOut = 0;
jpelletier 0:8133df8bab0f 452
jpelletier 0:8133df8bab0f 453 if (c == PAR_NEGOTIATE_REQ_DEV_ID_ECP_MODE)
jpelletier 0:8133df8bab0f 454 printer_side_ecp_printf("%cSoftware printer emulator",26);
jpelletier 0:8133df8bab0f 455 else
jpelletier 0:8133df8bab0f 456 printer_side_ecp_printf("Hello world from printer emulator in ecp mode\n");
jpelletier 0:8133df8bab0f 457
jpelletier 0:8133df8bab0f 458 // End of data
jpelletier 0:8133df8bab0f 459 nError = 1;
jpelletier 0:8133df8bab0f 460
jpelletier 0:8133df8bab0f 461 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 462 goto state_init;
jpelletier 0:8133df8bab0f 463 }
jpelletier 0:8133df8bab0f 464
jpelletier 0:8133df8bab0f 465 // PARPORT_CMD_ECP_WR_CMD
jpelletier 0:8133df8bab0f 466 // PARPORT_CMD_ECP_WR_DATA
jpelletier 0:8133df8bab0f 467 if (nInit)
jpelletier 0:8133df8bab0f 468 {
jpelletier 0:8133df8bab0f 469 /* Acknowledge the forward transfer request */
jpelletier 0:8133df8bab0f 470 PaperOut = 1;
jpelletier 0:8133df8bab0f 471
jpelletier 0:8133df8bab0f 472 /* Read data from PC ecp mode */
jpelletier 0:8133df8bab0f 473 Busy = 1;
jpelletier 0:8133df8bab0f 474
jpelletier 0:8133df8bab0f 475 /* Read data lines */
jpelletier 0:8133df8bab0f 476 pc.printf("%02X ",PtrData & 0xff);
jpelletier 0:8133df8bab0f 477 ++i;
jpelletier 0:8133df8bab0f 478 if (i == 16)
jpelletier 0:8133df8bab0f 479 {
jpelletier 0:8133df8bab0f 480 i = 0;
jpelletier 0:8133df8bab0f 481 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 482 }
jpelletier 0:8133df8bab0f 483
jpelletier 0:8133df8bab0f 484 Busy = 0;
jpelletier 0:8133df8bab0f 485 }
jpelletier 0:8133df8bab0f 486
jpelletier 0:8133df8bab0f 487 goto state_ecp_mode;
jpelletier 0:8133df8bab0f 488
jpelletier 0:8133df8bab0f 489 case PAR_NEGOTIATE_REQ_DEV_ID_ECP_RLE_MODE:
jpelletier 0:8133df8bab0f 490 case PAR_NEGOTIATE_REQ_ECP_RLE_MODE:
jpelletier 0:8133df8bab0f 491 rle = 0;
jpelletier 0:8133df8bab0f 492 state_ecp_rle_mode:
jpelletier 0:8133df8bab0f 493 // PARPORT_CMD_ECP_INIT1
jpelletier 0:8133df8bab0f 494 // PARPORT_CMD_ECP_INIT2
jpelletier 0:8133df8bab0f 495 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 496
jpelletier 0:8133df8bab0f 497 // PARPORT_CMD_ECP_READ
jpelletier 0:8133df8bab0f 498 if (nStrobe)
jpelletier 0:8133df8bab0f 499 {
jpelletier 0:8133df8bab0f 500 // data available
jpelletier 0:8133df8bab0f 501 nError = 0;
jpelletier 0:8133df8bab0f 502
jpelletier 0:8133df8bab0f 503 /* Acknowledge the reverse transfer request */
jpelletier 0:8133df8bab0f 504 PaperOut = 0;
jpelletier 0:8133df8bab0f 505
jpelletier 0:8133df8bab0f 506 if (c == PAR_NEGOTIATE_REQ_DEV_ID_ECP_RLE_MODE)
jpelletier 0:8133df8bab0f 507 printer_side_ecprle_printf("%cSoftware printer emulator",26);
jpelletier 0:8133df8bab0f 508 else
jpelletier 0:8133df8bab0f 509 printer_side_ecprle_printf("Hello world from printer emulator in ecp rle mode\n");
jpelletier 0:8133df8bab0f 510
jpelletier 0:8133df8bab0f 511 // End of data
jpelletier 0:8133df8bab0f 512 nError = 1;
jpelletier 0:8133df8bab0f 513
jpelletier 0:8133df8bab0f 514 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 515 goto state_init;
jpelletier 0:8133df8bab0f 516 }
jpelletier 0:8133df8bab0f 517
jpelletier 0:8133df8bab0f 518 // PARPORT_CMD_ECP_WR_CMD
jpelletier 0:8133df8bab0f 519 // PARPORT_CMD_ECP_WR_DATA
jpelletier 0:8133df8bab0f 520 if (nInit)
jpelletier 0:8133df8bab0f 521 {
jpelletier 0:8133df8bab0f 522 // PARPORT_CMD_ECP_WR_DATA
jpelletier 0:8133df8bab0f 523 if (nAutoFeed)
jpelletier 0:8133df8bab0f 524 {
jpelletier 0:8133df8bab0f 525 /* Acknowledge the forward transfer request */
jpelletier 0:8133df8bab0f 526 PaperOut = 1;
jpelletier 0:8133df8bab0f 527
jpelletier 0:8133df8bab0f 528 /* Read data from PC ecp mode */
jpelletier 0:8133df8bab0f 529 Busy = 1;
jpelletier 0:8133df8bab0f 530
jpelletier 0:8133df8bab0f 531 /* Read data lines */
jpelletier 0:8133df8bab0f 532 data = PtrData;
jpelletier 0:8133df8bab0f 533
jpelletier 0:8133df8bab0f 534 /* if previous byte was an RLE value, replicate the current byte */
jpelletier 0:8133df8bab0f 535 if (rle != 0)
jpelletier 0:8133df8bab0f 536 {
jpelletier 0:8133df8bab0f 537 pc.printf("(%02X *) %02X ",rle & 0xff,data & 0xff);
jpelletier 0:8133df8bab0f 538 rle = 0;
jpelletier 0:8133df8bab0f 539 ++i;
jpelletier 0:8133df8bab0f 540 if (i == 16)
jpelletier 0:8133df8bab0f 541 {
jpelletier 0:8133df8bab0f 542 i = 0;
jpelletier 0:8133df8bab0f 543 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 544 }
jpelletier 0:8133df8bab0f 545 }
jpelletier 0:8133df8bab0f 546 else
jpelletier 0:8133df8bab0f 547 {
jpelletier 0:8133df8bab0f 548 pc.printf("%02X ",data & 0xff);
jpelletier 0:8133df8bab0f 549 ++i;
jpelletier 0:8133df8bab0f 550 if (i == 16)
jpelletier 0:8133df8bab0f 551 {
jpelletier 0:8133df8bab0f 552 i = 0;
jpelletier 0:8133df8bab0f 553 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 554 }
jpelletier 0:8133df8bab0f 555 }
jpelletier 0:8133df8bab0f 556
jpelletier 0:8133df8bab0f 557 Busy = 0;
jpelletier 0:8133df8bab0f 558 }
jpelletier 0:8133df8bab0f 559 else
jpelletier 0:8133df8bab0f 560 {
jpelletier 0:8133df8bab0f 561 /* Acknowledge the forward transfer request */
jpelletier 0:8133df8bab0f 562 PaperOut = 1;
jpelletier 0:8133df8bab0f 563
jpelletier 0:8133df8bab0f 564 /* Read data from PC ecp mode */
jpelletier 0:8133df8bab0f 565 Busy = 1;
jpelletier 0:8133df8bab0f 566
jpelletier 0:8133df8bab0f 567 /* Read data lines */
jpelletier 0:8133df8bab0f 568 data = PtrData;
jpelletier 0:8133df8bab0f 569
jpelletier 0:8133df8bab0f 570 /* RLE */
jpelletier 0:8133df8bab0f 571 if ((data & 0x80) == 0)
jpelletier 0:8133df8bab0f 572 /* RLE command: next byte to be replicated 1 to 127 times (2-128 bytes) */
jpelletier 0:8133df8bab0f 573 rle = data & 0x7f;
jpelletier 0:8133df8bab0f 574 else
jpelletier 0:8133df8bab0f 575 {
jpelletier 0:8133df8bab0f 576 /* Address */
jpelletier 0:8133df8bab0f 577 pc.printf("[%02X]",data & 0xff);
jpelletier 0:8133df8bab0f 578 ++i;
jpelletier 0:8133df8bab0f 579 if (i == 16)
jpelletier 0:8133df8bab0f 580 {
jpelletier 0:8133df8bab0f 581 i = 0;
jpelletier 0:8133df8bab0f 582 pc.printf("\r\n");
jpelletier 0:8133df8bab0f 583 }
jpelletier 0:8133df8bab0f 584 }
jpelletier 0:8133df8bab0f 585 Busy = 0;
jpelletier 0:8133df8bab0f 586 }
jpelletier 0:8133df8bab0f 587 }
jpelletier 0:8133df8bab0f 588
jpelletier 0:8133df8bab0f 589 goto state_ecp_rle_mode;
jpelletier 0:8133df8bab0f 590
jpelletier 0:8133df8bab0f 591 case PAR_NEGOTIATE_REQ_DEV_ID_NIBBLE_MODE:
jpelletier 0:8133df8bab0f 592 if (!nInit) goto state_init;
jpelletier 0:8133df8bab0f 593 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 594
jpelletier 0:8133df8bab0f 595 printer_side_nibble_printf("%cSoftware printer emulator",26);
jpelletier 0:8133df8bab0f 596
jpelletier 0:8133df8bab0f 597 // End of nibble data
jpelletier 0:8133df8bab0f 598 nError = 1;
jpelletier 0:8133df8bab0f 599
jpelletier 0:8133df8bab0f 600 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 601 goto state_init;
jpelletier 0:8133df8bab0f 602
jpelletier 0:8133df8bab0f 603 case PAR_NEGOTIATE_REQ_DEV_ID_BYTE_MODE:
jpelletier 0:8133df8bab0f 604 if (!nInit) goto state_init;
jpelletier 0:8133df8bab0f 605 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 606
jpelletier 0:8133df8bab0f 607 printer_side_byte_printf("%cSoftware printer emulator",26);
jpelletier 0:8133df8bab0f 608
jpelletier 0:8133df8bab0f 609 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 610 goto state_init;
jpelletier 0:8133df8bab0f 611
jpelletier 0:8133df8bab0f 612 case PAR_NEGOTIATE_NIBBLE_MODE:
jpelletier 0:8133df8bab0f 613 if (!nInit) goto state_init;
jpelletier 0:8133df8bab0f 614 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 615
jpelletier 0:8133df8bab0f 616 printer_side_nibble_printf("Hello world from printer emulator in nibble mode\n");
jpelletier 0:8133df8bab0f 617
jpelletier 0:8133df8bab0f 618 // End of nibble data
jpelletier 0:8133df8bab0f 619 nError = 1;
jpelletier 0:8133df8bab0f 620
jpelletier 0:8133df8bab0f 621 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 622 goto state_init;
jpelletier 0:8133df8bab0f 623
jpelletier 0:8133df8bab0f 624 case PAR_NEGOTIATE_BYTE_MODE:
jpelletier 0:8133df8bab0f 625 if (!nInit) goto state_init;
jpelletier 0:8133df8bab0f 626 if (!nSelectIn) goto state_init;
jpelletier 0:8133df8bab0f 627
jpelletier 0:8133df8bab0f 628 printer_side_byte_printf("Hello world from printer emulator in byte mode\n");
jpelletier 0:8133df8bab0f 629
jpelletier 0:8133df8bab0f 630 while (nSelectIn) {}
jpelletier 0:8133df8bab0f 631 goto state_init;
jpelletier 0:8133df8bab0f 632
jpelletier 0:8133df8bab0f 633 default:
jpelletier 0:8133df8bab0f 634 pc.printf("Mode %02X not supported\n",c & 0xff);
jpelletier 0:8133df8bab0f 635 goto state_init;
jpelletier 0:8133df8bab0f 636 }
jpelletier 0:8133df8bab0f 637 }