please dont rip this site

SX Thermal Printer Controller

;From: andrew.mcmeikan at

                ;be carefull when assembling
                ;there is a lookup table that MUST NOT cross a
                ;256 byte boundry ---- CHECK IT

                ;thermal printer controler
innerloop = 0ff
lilloop = 01
bigloop =0ff

strobe          macro   bt
	SETB	$	;bit for strobe
	CLRB	0b.7	;dont want interupts
	CALL	outsr	;clock it out
	CALL	lildly	;let it burn in
	SETB	0b.7	;re-enable interupts
	CLRB	$	;so next outsr clears it

	ORG	$0000

	JMP	main

	ORG	$0004
                ;entry occurs in here when host pulls strobe signal low
                ;to indicate data that requires printing
                ;useing this int routine occupies two levels of stack
                ;one for the return address and one for outsr's return
                ;centronics pinouts
                ; pin 1 strobe is connected to  RB0
                ; pin 2 data1   "       "       RA1
                ; pin 3 data2   "       "       RA2
                ; pin 4 data3   "       "       RA3
                ; pin 5 data4   "       "       RA4
                ; pin 6 data5   "       "       RB1
                ; pin 7 data6   "       "       RB2
                ; pin 8 data7   "       "       RB3
                ; pin 9 data8   "       "       RB4
                ; pin10 ack     "       "       Cap from BSY this dips low
                ;                                       when want next byte
                ; pin11 busy   is connected to  RA0  High= offline
                ; pin12 Paper out is connected to photocell High=no paper
                ;pins 19 to 30 are signal grounds GND
                ; pin31 INT    is connected to RESET (via diode)
                ;                       and is used to initialize printer

	SETB	RA.0	;say we are busy

                ;read both ports to get byte of data
	MOV	W, >>RA	;read port a shifting data down one
	AND	W, #0f	;only keep bottom bits
	MOV	$16, W	;keep incomming data here
	MOV	W, >>RB	;read port b shifting down one
	AND	W, #0f	;wipe out extraneous bits
	MOV	$17, W	;waste another register
	MOV	W, <>$17	;get 'b' data lower into upper W
	OR	$16, W	;or top bits into data
                ;bit pattern from host now in 0x16

	INC	0e	;increment our count of bytes

                ;clock data into thermal head
	MOV	W, #08	;for 8 bits
	MOV	$17, W	;better keep count of it
clkhd:	RL	$16	;rotate it thru carry
	SETB	$12.4	;set data high
	SC		;check the carry flag
	CLRB	$12.4	;clear data if required
	CALL	outsr
	SETB	$12.5	;clock that bit in
	CALL	outsr
	CLRB	$12.5	;drop clock again
	CALL	outsr
	DECSZ	$17	;have we finished loop yet ?
	JMP	clkhd	;guess not
                ;no point doing the extra shift as we are just
                ;throwing the data away once it is in the head

                ;if byte count=max then lets latch and let the main routine
                ;                                         print it
	MOV	W, #$c0	;try 192           ;216 max bytes per line 1728 bits
	MOV	W, 0e-w	;check max against our byte count
	SZ		;the same? result of zero?
	JMP	continue	;no its ok, head not full yet

                ;need to latch thermal head
                ; We do not not lower busy here
                ;as main routine will do so once it has reset
                ;the counter.

	SETB	$12.6	;latch bit for thermal head
	CALL	outsr	;send- no one else better be using it
	CLRB	$12.6	;put back
	CALL	outsr	;send that to

	JMP	exint	;leave int handler

continue:       ;tell host we are no longer busy, get next byte
	CLRB	RA.0	;bring BSY low
                ;and fall thru to exit :)
exint:                                  ;now restore to before interupt

main            ;thermal printer control program 192 dpi 9 inch 1728 pixels
                ;need to set up direction bits for ports
                ;and set initial pin levels

	MOV	W, #$C0	
	MOV	!OPTION, W	;set options RTW and RTI on so OptionX can be used

	mov	M, #$0E
	mov	!RA,#$FF
	mov	!RB,#$FF

		;porta as input except RA.0
	MOV	RA, #$ff 	;set all pins high on port a
	mov	M, #$0F
	MOV	W, #$FE		;RA0 as output

		;portb interrupt on neg edge is the default
	MOV	RB, #01f	;make bits 6,7 &5 low
	mov	M, #$0F
	MOV	!RB, #01f	;port b 5,6,7 as output

	MOV	W, #$08	;specify which phase to start on
	MOV	$15, W	;store it somewhere safe
	CLR	$0E	;zero byte count for head
	MOV	W, #$00	;phases off clk,lat,data, strb off
	MOV	$12, W	;data for shift reg 1
	MOV	W, #00	;all strobes off (low)
	MOV	$13, W	;data for shift reg 2
	CALL	outsr	;set all pins high except for stepper
	MOV	W, #$90	;enable RB0 and GIE interupt bits
	MOV	$0B, W	;interupts now turned on!
	CLRB	RA.0	;say we are not busy

p1=8;9 ;1
p2=4;8 ;3         ;ok here are definitions of how the shift registers are wired
p3=2;0c;2         ; ok on 0x12    bit0    stepper phase A
p4=1;4 ;6         ;               bit1    "       "     B
p5=8;6 ;4         ;               bit2    "       "     C
p6=4;2 ;0c        ;               bit3    "       "     D
p7=2;3 ;8         ;               bit4    Data for thermal head
p8=1;1 ;9         ;               bit5    Clock for thermal Head
                  ;               bit6    Latch for thermal head
                  ;               bit7    strobe 1 for thermal head;

                  ;       0x13    bit0 to bit7 rest of strobes for head

mloop:          ;this is the loopy bit of main
                ;we sit in here till we get a full head
                ;then we reset the counter, send an ack to the host
                ;print the line out and advance the paper, then we sit until
                ;the head is full again :)

		;first check if the head is full
	MOV	W, #$C0	;try 192            ;216 max bytes per line 1728 bits
	MOV	W, $0E-w	;check max against our byte count
	SZ		;the same? result of zero?
	JMP	mloop	;no not yet keep waiting
	CLR	$0E	;Ok we've spotted the head full

                ;need to strobe head drivers
	SETB	$12.7	;strb1
	CLRB	$0B.7	;turn off interupts
	CALL	outsr	;Fire!
	CALL	lildly	;let it burn!
	SETB	$0B.7	;re-enable interupts
	CLRB	$12.7	;ok thats done

                strobe 0
                strobe 1
                strobe 2
                strobe 3
                strobe 4
                strobe 5
                strobe 6
                strobe 7

	CLRB	$0B.7	;turn off interupts
	CALL	outsr	;yay! all strobes Fired!
	CLRB	RA.0	;ok we aren't busy any more
	SETB	$0B.7	;re-enable interupts

	CALL	papadv	;move paper on to next line
	JMP	mloop	;lets go back and see if another
                                        ;line is ready yet

phlook:         ;this routine looks up the value for a particular phase
                ;important that this lookup resides within a 256 byte block
                ;as PCL is directly modified.  if called with value grater
                ;than 8 ,will cause who knows what kind of crash!
	ADD	02, W	;ok now its going to jump :)
	NOP	;err dont expect zero ?!?!
	RETW	#p8	;return with phase 8
	RETW	#p7	;coz we are counting down
	RETW	#p6	;remember... see next routine!
	RETW	#p5
	RETW	#p4
	RETW	#p3
	RETW	#p2
	RETW	#p1
	SLEEP	;coz its all gone wrong if it
                                        ;gets here or past!
                                        ;check the listing to be sure
                                        ;it fits between page boundries!

papadv:         ;this routine is to activate a paper advance one step
                ;it will use register #15 to keep track of which
                ;point in the phase cycle it is
	MOV	W, #0f0	;prep mask
	CLRB	$0b.7	;diable interupts
	AND	$12, W	;nock off bottom bits
	MOV	W, $15	;grab our phase number into W
	CALL	phlook
	OR	$12, W	;new pattern now set
	SETB	$0b.7	;ints re-enabled
	DEC	$15	;get next phase number
	SNZ		;did we hit zero?
	JMP	recount	;yep need to reload the counter
	CLRB	$0b.7	;turn off interupts coz of (outsr)
	CALL	outsr	;jump to out put new phase
	SETB	$0b.7	;turn on interupts again
	RET	;and go back
	MOV	W, #08	;we hit zero reset it back to 8
	MOV	$15, W	;use it next time round
	CLRB	$0b.7	;clear interupt enable
	CALL	outsr	;I know its just below us
	SETB	$0b.7	;but tis only way to keep
	RET	;the interupts rightly enabled

outsr:          ;this routine takes bytes at 0x12 and 0x13
                ;and clocks them out onto the shift registers
                ;shift registers accessed on port b bits 5,6 & 7
                ;bit 6 as clock - clocks data on POSITIVE edge
                ;bit 7 as data  - non inverted
                ;bit 5 as strobe - latches data on NEGATIVE edge
                ; we are sending lsb first ie bit# 1 on shift register
                ; output pin #8
                ; sending byte at address 0x12 first then 0x13
                ; this puts 0x12 on the last shift register in line
                ;uses reg # 14 to keep count of bits

                ;since this code is NON-RE-ENTERENT, do NOT call it
                ;while interupts are enabled, coz the int handler
                ;calls this routine to access the thermal head.

	MOV	W, #08	;for 8 bits
	MOV	$14, W	;better keep count of it
	RR	$12	;rotate it thru carry
	SETB	6.7	;set data high
	SC		;check the carry flag
	CLRB	6.7	;clear data if required
	SETB	6.6	;clock that bit in
	CLRB	6.6	;drop clock again
	DECSZ	$14	;have we finished loop yet ?
	JMP	shiftbits	;guess not
	RR	$12	;preserve the data, shift the carry
                        ;now we have finished one byte lets do the other
	MOV	W, #08	;for 8 bits
	MOV	$14, W	;better keep count of it
	RR	$13	;rotate it thru carry
	SETB	6.7	;set data high
	SC		;check the carry flag
	CLRB	6.7	;clear data if required
	SETB	6.6	;clock that bit in
	CLRB	6.6	;drop clock again
	DECSZ	$14	;have we finished loop yet ?
	JMP	shiftbitsagain	;guess not
	RR	$13	;preserve the data, shift the carry
                        ;now we have really finished clocking bits
	SETB	6.5	;bring up the strobe line
	CLRB	6.5	;and LATCH it
	RET	;back to where ever.

lildly	MOV	W, #lilloop
	MOV	$11, W
	JMP	reload
bigdly	MOV	W, #bigloop
	MOV	$11, W
reload	MOV	W, #innerloop
	MOV	$10, W
inloop	NOP
	DECSZ	$10
	JMP	inloop
	DECSZ	$11
	JMP	reload

	ORG	$2000
                DATA    00
                DATA    00
                DATA    00
                DATA    00

	ORG	$2007
                DATA    0x19            ;fuse settings

	ORG	$2100
                ;data    00
                ;data    00
                ;data    00


file: /Techref/scenix/lib/io/dev/thprn_sx.htm, 10KB, , updated: 2004/12/29 13:33, local time: 2024/5/18 19:38,

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF=""> SX Thermal Printer Controller </A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?


Welcome to!


Welcome to!