Subversion Repositories group.electronics

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
126 pfowler 1
/*
2
 * lmd.c
3
 *
4
 *  Created on: 30/11/2013
5
 *      Author: pfowler
6
 */
7
 
8
#include <avr/io.h>
9
#include <stdlib.h>
10
#include <avr/pgmspace.h>
11
#include <util/delay.h>
12
#include <math.h>
13
 
14
#include "avrutil.h"
15
#include "lmd.h"
16
 
17
#define LMD_NOOP		0x00
18
#define	LMD_DIGIT0		0x01
19
#define	LMD_DIGIT1		0x02
20
#define	LMD_DIGIT2		0x03
21
#define	LMD_DIGIT3		0x04
22
#define	LMD_DIGIT4		0x05
23
#define	LMD_DIGIT5		0x06
24
#define	LMD_DIGIT6		0x07
25
#define	LMD_DIGIT7		0x08
26
#define LMD_DECODE_MODE	0x09
27
#define LMD_INTENSITY	0x0a
28
#define	LMD_SCAN_LIMIT	0x0b
29
#define	LMD_SHUTDOWN	0x0c
30
#define	LMD_DISPLAY_TEST 0x0f
31
 
32
 
33
void lmd_intensity(uint8_t max, uint8_t i) {
34
	lmd_writeReg(max, LMD_INTENSITY, i);
35
}
36
 
37
void lmd_scanlimit(uint8_t max, uint8_t l) {
38
	lmd_writeReg(max, LMD_SCAN_LIMIT, l);
39
}
40
 
41
void lmd_shutdown(uint8_t max, uint8_t s) {
42
	lmd_writeReg(max, LMD_SHUTDOWN, s);
43
}
44
 
45
void lmd_decodemode(uint8_t max, uint8_t d) {
46
	lmd_writeReg(max, LMD_DECODE_MODE, d);
47
}
48
 
49
 
50
 
51
void lmd_init(uint8_t pinx_addr,
52
		uint8_t clk_pin, uint8_t load_pin, uint8_t data_pin,
53
		uint8_t numMax) {
54
	lmd.pin = pinx_addr;
55
	lmd.ddr = pinx_addr + 1;
56
	lmd.port = pinx_addr + 2;
57
	lmd.clk = clk_pin;
58
	lmd.load = load_pin;
59
	lmd.data = data_pin;
60
	lmd.numMax = numMax;
61
 
62
	lmd.dps = malloc(lmd.numMax * sizeof(uint8_t));
63
 
64
 
65
	sbi(lmd.ddr, lmd.clk);
66
	sbi(lmd.ddr, lmd.load);
67
	sbi(lmd.ddr, lmd.data);
68
 
69
	_delay_us(100);
70
												// Defaults
71
	lmd_writeRegAll(LMD_INTENSITY, 0x01);			// Lowest intensity
72
	lmd_writeRegAll(LMD_SCAN_LIMIT, 0x07);			// Use all leds
73
	lmd_writeRegAll(LMD_SHUTDOWN, 0x01);			// Shutdown
74
	lmd_writeRegAll(LMD_DECODE_MODE, 0x00);		// No decoding
75
 
76
	_delay_us(100);
77
 
78
	lmd_clearAll();
79
}
80
 
81
void lmd_clearAll(void) {
82
	uint8_t c;
83
	for (c=1; c<=8; c++) {
84
		lmd_writeRegAll(c, 0x00);
85
	}
86
}
87
 
88
void lmd_dp(uint8_t max, uint8_t digit) {
89
	lmd.dps[max] = digit;
90
}
91
 
92
void lmd_print_u32(uint8_t max, uint32_t value) {
93
	const uint8_t DIGIT_COUNT = 8;
94
 
95
	uint8_t i;
96
	for (i=1; i<=DIGIT_COUNT; i++) {
97
		uint32_t power = (uint32_t)pow(10, i);
98
		if (i != 1) power++;
99
		uint8_t val = ((value % power) / (power/10)) ;
100
 
101
		if (rbi(lmd.dps[max], i-1))
102
			lmd_writeReg(max, i, val | 0xf0 );
103
		else
104
			lmd_writeReg(max, i, val);
105
	}
106
}
107
 
108
void lmd_print_u16(uint8_t max, uint16_t value) {
109
	const uint8_t DIGIT_COUNT = 5;
110
 
111
	uint8_t i;
112
	for (i=1; i<=DIGIT_COUNT; i++) {
113
		uint32_t power = (uint32_t)pow(10, i);
114
		if (i != 1) power++;
115
		uint8_t val = ((value % power) / (power/10)) ;
116
 
117
		if (rbi(lmd.dps[max], i-1))
118
			lmd_writeReg(max, i, val | 0xf0 );
119
		else
120
			lmd_writeReg(max, i, val);
121
	}
122
 
123
}
124
 
125
void lmd_print_u8(uint8_t max, uint8_t value) {
126
	const uint8_t DIGIT_COUNT = 3
127
			;
128
	uint8_t i;
129
	for (i=1; i<=DIGIT_COUNT; i++) {
130
		uint32_t power = (uint32_t)pow(10, i);
131
		if (i != 1) power++;
132
		uint8_t val = ((value % power) / (power/10)) ;
133
 
134
		if (rbi(lmd.dps[max], i-1))
135
			lmd_writeReg(max, i, val | 0xf0 );
136
		else
137
			lmd_writeReg(max, i, val);
138
	}
139
}
140
 
141
void lmd_writeReg(uint8_t max, uint8_t reg, uint8_t val) {
142
	uint8_t c;
143
	cbi(_SFR_IO8(lmd.port), lmd.load);
144
	for (c=lmd.numMax; c< max; c--) {
145
		lmd_writeByte(0x00);
146
		lmd_writeByte(0x00);
147
	}
148
 
149
	lmd_writeByte(reg);
150
	lmd_writeByte(val);
151
 
152
	for (c=max-1; c<= 1; c--) {
153
		lmd_writeByte(0x00);
154
		lmd_writeByte(0x00);
155
	}
156
	sbi(_SFR_IO8(lmd.port), lmd.load);
157
}
158
 
159
void lmd_writeRegAll(uint8_t reg, uint8_t val) {
160
	uint8_t c;
161
	cbi(_SFR_IO8(lmd.port), lmd.load);
162
	for (c=1; c<=lmd.numMax; c++) {
163
		lmd_writeByte(reg);
164
		lmd_writeByte(val);
165
	}
166
	sbi(_SFR_IO8(lmd.port), lmd.load);
167
}
168
 
169
void lmd_writeByte(uint8_t dataout) {
170
	uint8_t mask;
171
	uint8_t i = 8;
172
	for (i=8; i>0; i--) {
173
		mask = 0x01 << (i - 1);
174
		cbi(_SFR_IO8(lmd.port), lmd.clk);
175
		if (dataout & mask)		// Send 1 bit at a time
176
			sbi(_SFR_IO8(lmd.port), lmd.data);
177
		else
178
			cbi(_SFR_IO8(lmd.port), lmd.data);
179
		sbi(_SFR_IO8(lmd.port), lmd.clk);
180
	}
181
 
182
}
183
 
184
void lmd_test(void) {
185
	lmd_writeRegAll(LMD_DECODE_MODE,0x00);
186
	lmd_writeRegAll(8,0b01001110);
187
	lmd_writeRegAll(7,0b01111110);
188
	lmd_writeRegAll(6,0b01111110);
189
	lmd_writeRegAll(5,0b00001110);
190
	lmd_writeRegAll(4,0b01110111);
191
	lmd_writeRegAll(3,0b01011011);
192
	lmd_writeRegAll(2,0b01011011);
193
	lmd_writeRegAll(1,0x80);
194
}
195