SX Thermal
Printer Controller
;From: andrew.mcmeikan at mitswa.com.au
;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 $13.bt ;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 $13.bt ;so next outsr clears it
endm
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
RETI
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
;pullups
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
recount:
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
shiftbits:
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
shiftbitsagain:
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
RET
ORG $2000
DATA 00
DATA 00
DATA 00
DATA 00
ORG $2007
DATA 0x19 ;fuse settings
ORG $2100
;data 00
;data 00
;data 00
END
file: /Techref/scenix/lib/io/dev/thprn_sx.htm, 10KB, , updated: 2004/12/29 12:33, local time: 2024/11/16 06:37,
|
| ©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? <A HREF="http://linistepper.com/techref/scenix/lib/io/dev/thprn_sx.htm"> SX Thermal Printer Controller </A> |
Did you find what you needed?
|