Subversion Repositories svn.mios

Rev

Rev 146 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
130 tk 1
; $Id: aout_74hc595.inc 285 2008-04-23 20:31:07Z tk $
2
;
3
; AOUT driver for 74HC595 based DAC (-> MBHP_AOUT_LC module)
4
;
5
; See aout.inc for description of the available functions
6
;
7
; ==========================================================================
8
;
9
;  Copyright 1998-2008 Thorsten Klose (tk@midibox.org)
10
;  Licensed for personal non-commercial use only.
11
;  All other rights reserved.
12
;
13
; ==========================================================================
14
;
285 tk 15
; Special Option for AOUT_LC module: select either 12/4 bit (0), or 8/8 bit (1),
16
; or 12/12/8 (2) configuration
130 tk 17
; this has to be done for each module seperately
285 tk 18
;
19
; Note: the 12/12/8 bit selection (2) combines 4 shift registers. The first two SRs
20
; are working like option 0 (first channel: 12bit, second channel: upper 4bit)
21
; The third SR outputs the lower bits of second channel, and the fourth SR the
22
; 8bit value of third channel. The fourth channel is ignored
23
; (same for channel 4-7... channel 8 ignored)
24
; For this "combined" option, it is recommented, to set both modes (M1,M2 and/or M3,M4)
25
; to value 2 for future compatibilty
130 tk 26
#ifndef AOUT_LC_RESOLUTION_OPTION_M1
27
#define AOUT_LC_RESOLUTION_OPTION_M1 0
28
#endif
29
#ifndef AOUT_LC_RESOLUTION_OPTION_M2
30
#define AOUT_LC_RESOLUTION_OPTION_M2 0
31
#endif
32
#ifndef AOUT_LC_RESOLUTION_OPTION_M3
33
#define AOUT_LC_RESOLUTION_OPTION_M3 0
34
#endif
35
#ifndef AOUT_LC_RESOLUTION_OPTION_M4
36
#define AOUT_LC_RESOLUTION_OPTION_M4 0
37
#endif
38
 
39
;; --------------------------------------------------------------------------
40
;;  Hardware specific initialisation (see aout.inc for details)
41
;; --------------------------------------------------------------------------
42
AOUT_InitHW
43
	;; CS line used as RCLK by AOUT_LC module - should be at low level by default
44
	bcf	AOUT_LAT_CS, AOUT_PIN_CS
45
 
46
	;; enable pin drivers
47
	bcf	AOUT_TRIS_CS, AOUT_PIN_CS
48
	bcf	AOUT_TRIS_DIN, AOUT_PIN_DIN
49
	bcf	AOUT_TRIS_SCLK, AOUT_PIN_SCLK
50
 
51
	return
52
 
53
 
54
;; --------------------------------------------------------------------------
55
;;  Sets the digital pins (see aout.inc for details)
56
;; --------------------------------------------------------------------------
146 tk 57
_AOUT_DigitalPinsSet		; (for C)
130 tk 58
AOUT_DigitalPinsSet
59
	;; not supported by AOUT_LC module
60
	return
61
 
62
 
63
;; --------------------------------------------------------------------------
64
;;  Update function (see aout.inc for details)
65
;; --------------------------------------------------------------------------
146 tk 66
_AOUT_Update			; (for C)
130 tk 67
AOUT_Update
68
	;; skip if no update requested
69
	SET_BSR	AOUT_UPDATE_REQ
70
	movf	AOUT_UPDATE_REQ, W, BANKED
71
	bz	AOUT_Update_End
72
 
73
        bcf	AOUT_LAT_SCLK, AOUT_PIN_SCLK	; ensure that clock starts at low level
74
 
75
	;; update all channels
76
	SET_BSR	AOUT_INVERTED
77
 
285 tk 78
 
130 tk 79
	;; 4th AOUT_LC module
285 tk 80
#if AOUT_LC_RESOLUTION_OPTION_M4 == 2
81
	lfsr	FSR1, AOUT_VALUES + 3*4-2	; pointer to values in FSR1
82
	swapf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
83
	rrf	WREG, W
84
#else
130 tk 85
	lfsr	FSR1, AOUT_VALUES + 3*4		; pointer to values in FSR1
86
	swapf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
87
	rrf	WREG, W
88
	rrf	WREG, W
285 tk 89
#endif
130 tk 90
	movwf	MIOS_PARAMETER3
285 tk 91
#if AOUT_LC_RESOLUTION_OPTION_M4 == 0
130 tk 92
	rcall	AOUT_Update_Hlp_12_4
285 tk 93
#endif
94
#if AOUT_LC_RESOLUTION_OPTION_M4 == 1
130 tk 95
	rcall	AOUT_Update_Hlp_8_8
96
#endif
285 tk 97
#if AOUT_LC_RESOLUTION_OPTION_M4 == 2
98
	rcall	AOUT_Update_Hlp_12_12_8
99
#endif
130 tk 100
 
101
	;; 3rd AOUT_LC module
102
	lfsr	FSR1, AOUT_VALUES + 2*4		; pointer to values in FSR1
103
	swapf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
104
	movwf	MIOS_PARAMETER3
285 tk 105
#if AOUT_LC_RESOLUTION_OPTION_M3 == 1
106
	rcall	AOUT_Update_Hlp_8_8		; used for 8/8 resolution
130 tk 107
#else
285 tk 108
	rcall	AOUT_Update_Hlp_12_4		; used for 12/4 and 12/12/8 resolution
130 tk 109
#endif
110
 
285 tk 111
 
130 tk 112
	;; 2nd AOUT_LC module
285 tk 113
#if AOUT_LC_RESOLUTION_OPTION_M2 == 2
114
	lfsr	FSR1, AOUT_VALUES + 1*4-2	; pointer to values in FSR1
115
	rrf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
116
#else
130 tk 117
	lfsr	FSR1, AOUT_VALUES + 1*4		; pointer to values in FSR1
118
	rrf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
119
	rrf	WREG, W
285 tk 120
#endif
130 tk 121
	movwf	MIOS_PARAMETER3
285 tk 122
#if AOUT_LC_RESOLUTION_OPTION_M2 == 0
130 tk 123
	rcall	AOUT_Update_Hlp_12_4
285 tk 124
#endif
125
#if AOUT_LC_RESOLUTION_OPTION_M2 == 1
130 tk 126
	rcall	AOUT_Update_Hlp_8_8
127
#endif
285 tk 128
#if AOUT_LC_RESOLUTION_OPTION_M2 == 2
129
	rcall	AOUT_Update_Hlp_12_12_8
130
#endif
130 tk 131
 
132
	;; 1st AOUT_LC module
133
	lfsr	FSR1, AOUT_VALUES + 0*4		; pointer to values in FSR1
134
	movf	AOUT_INVERTED, W, BANKED	; inversion flags in MIOS_PARAMETER3[1:0]
135
	movwf	MIOS_PARAMETER3
285 tk 136
#if AOUT_LC_RESOLUTION_OPTION_M1 == 1
137
	rcall	AOUT_Update_Hlp_8_8		; used for 8/8 resolution
130 tk 138
#else
285 tk 139
	rcall	AOUT_Update_Hlp_12_4		; used for 12/4 and 12/12/8 resolution
130 tk 140
#endif
141
 
285 tk 142
 
130 tk 143
	;; CS line used as RCLK by AOUT_LC module
144
	bsf	AOUT_LAT_CS, AOUT_PIN_CS	; trigger RCLK to update chain
145
	nop
146
	bcf	AOUT_LAT_CS, AOUT_PIN_CS
147
 
148
AOUT_Update_End
149
	;; clear update flags
150
	SET_BSR	AOUT_UPDATE_REQ
151
	clrf	AOUT_UPDATE_REQ, BANKED
152
 
153
	return
154
 
155
;; help function to update a single AOUT_LC module
156
AOUT_Update_Hlp_12_4
285 tk 157
#if AOUT_LC_RESOLUTION_OPTION_M1 != 1 || AOUT_LC_RESOLUTION_OPTION_M2 != 1 || AOUT_LC_RESOLUTION_OPTION_M3 != 1 || AOUT_LC_RESOLUTION_OPTION_M4 != 1
130 tk 158
	;; map 2 * 16 bit to 12/4 bit
159
	movlw	1				; first channel: 12bit
160
	movf	PLUSW1, W			; high-byte -> MIOS_PARAMETER1
161
	btfsc	MIOS_PARAMETER3, 0		; inversion?
162
	xorlw	0xff
163
	movwf	MIOS_PARAMETER1
164
	movf	INDF1, W			; [7:4] of low-byte -> MIOS_PARAMETER2[7:4]
165
	andlw	0xf0
166
	btfsc	MIOS_PARAMETER3, 0		; inversion?
167
	xorlw	0xf0
168
	movwf	MIOS_PARAMETER2
169
 
170
	movlw	3				; second channel: 4bit
171
	swapf	PLUSW1, W			; [7:4] of high-byte -> MIOS_PARAMETER2[3:0]
172
	andlw	0x0f
173
	btfsc	MIOS_PARAMETER3, 1		; inversion?
174
	xorlw	0x0f
175
	iorwf	MIOS_PARAMETER2, F
176
	rgoto	AOUT_LoadWord
285 tk 177
#else
178
	return					; neither 12/4, nor 12/12/4 option used - save memory
179
#endif
130 tk 180
 
285 tk 181
 
182
 
130 tk 183
AOUT_Update_Hlp_8_8
285 tk 184
#if AOUT_LC_RESOLUTION_OPTION_M1 == 1 || AOUT_LC_RESOLUTION_OPTION_M2 == 1 || AOUT_LC_RESOLUTION_OPTION_M3 == 1 || AOUT_LC_RESOLUTION_OPTION_M4 == 1
130 tk 185
	;; map 2 * 16 bit to 8/8 bit
186
	movlw	1				; first channel: 8bit
187
	movf	PLUSW1, W			; high-byte -> MIOS_PARAMETER1
188
	btfsc	MIOS_PARAMETER3, 0		; inversion?
189
	xorlw	0xff
190
	movwf	MIOS_PARAMETER1
191
 
192
	movlw	3				; second channel: 8bit
193
	movf	PLUSW1, W			; high-byte -> MIOS_PARAMETER2
132 tk 194
	btfsc	MIOS_PARAMETER3, 1		; inversion?
130 tk 195
	xorlw	0xff
196
	movwf	MIOS_PARAMETER2
197
	rgoto	AOUT_LoadWord
285 tk 198
#else
199
	return					; 8/8 option not used - save memory
200
#endif
130 tk 201
 
202
 
285 tk 203
 
204
AOUT_Update_Hlp_12_12_8
205
#if AOUT_LC_RESOLUTION_OPTION_M1 == 2 || AOUT_LC_RESOLUTION_OPTION_M2 == 2 || AOUT_LC_RESOLUTION_OPTION_M3 == 2 || AOUT_LC_RESOLUTION_OPTION_M4 == 2
206
	;; first channel, and upper bits of second channel already uploaded via 12_4 function
207
	;; now we have to upload the lower bits of the second channel + 8 bits of the third channel
208
	;; the fourth channel is ignored
209
	movlw	1				; second: lower 8bit
210
	swapf	PLUSW1, W			; [3:0] of high-byte -> MIOS_PARAMETER1[7:4]
211
	btfsc	MIOS_PARAMETER3, 0		; inversion?
212
	xorlw	0xf0
213
	andlw	0xf0
214
	movwf	MIOS_PARAMETER1
215
	swapf	INDF1, W			; [7:4] of low-byte -> MIOS_PARAMETER1[3:0]
216
	andlw	0x0f
217
	btfsc	MIOS_PARAMETER3, 0		; inversion?
218
	xorlw	0x0f
219
	iorwf	MIOS_PARAMETER1, F
130 tk 220
 
285 tk 221
	movlw	3				; third channel: 8bit
222
	movf	PLUSW1, W			; high-byte -> MIOS_PARAMETER2
223
	btfsc	MIOS_PARAMETER3, 1		; inversion?
224
	xorlw	0xff
225
	movwf	MIOS_PARAMETER2
226
	rgoto	AOUT_LoadWord
227
#else
228
	return					; 12/12/8 option not used - save memory
229
#endif
230
 
231
 
130 tk 232
;; --------------------------------------------------------------------------
133 tk 233
;;  Internal function to load a 16bit value into two 74HC595
130 tk 234
;;  IN: word in MIOS_PARAMETER[12]
235
;;  USES: MIOS_PARAMETER3 as temporary register
236
;; --------------------------------------------------------------------------
237
AOUT_LoadWord
238
	;; NOTE: you will notice that the instructions are sometimes arranged
239
	;; in a special order to ensure proper output signals - for example:
240
	;; between a rising and a falling SCLK edge there is at least one
241
	;; other instruction to ensure that the high pulse of the SCLK
242
	;; is longer than 100 nS
243
 
244
	movlw	16				; init loop counter
245
	movwf	MIOS_PARAMETER3
246
AOUT_LoadWord_Loop
247
	bcf	AOUT_LAT_DIN, AOUT_PIN_DIN	; set DIN depending on current MSB
248
	btfsc	MIOS_PARAMETER2, 7
249
	bsf	AOUT_LAT_DIN, AOUT_PIN_DIN
250
	rlf	MIOS_PARAMETER1, F		; start to shift the 16-bit value
251
	bsf	AOUT_LAT_SCLK, AOUT_PIN_SCLK	; rising clock edge
252
	rlf	MIOS_PARAMETER2, F		; second step for the 16-bit shift
253
	bcf	AOUT_LAT_SCLK, AOUT_PIN_SCLK	; falling clock edge
254
	decfsz	MIOS_PARAMETER3, F		; loop 16 times
255
	rgoto	AOUT_LoadWord_Loop
256
 
257
	return