├── .gitignore
├── README.md
├── gps_i2c
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── gps_i2c.c
├── i2c
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── i2c.c
└── i2c.h
├── i2c_master_test
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── i2c_master_test.c
├── i2c_slave_test
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── i2c_slave_test.c
├── lcd
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── lcd.c
└── lcd.h
├── lcd_i2c_digital_clock
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── lcd_i2c_digital_clock.c
├── lcd_test
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── lcd_test.c
├── led_analog_clock
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── Doxyfile
├── led_analog_clock.c
├── led_analog_clock_v1.c
├── led_analog_clock_v1.h
├── led_analog_clock_v2.c
├── led_analog_clock_v2.h
├── led_analog_watch_v1.c
├── led_analog_watch_v1.h
├── led_mapping.c
└── led_mapping.h
├── led_charlieplex
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── Doxyfile
├── led_charlieplex.c
└── led_charlieplex.h
├── led_sequencer
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── led_sequencer.c
└── led_sequencer.h
├── nmea
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── nmea.c
└── nmea.h
├── rtc
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── rtc.c
├── rtc.h
├── rtc_ds1307.c
├── rtc_ds1307.h
└── rtc_types.h
├── rtc_test
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
└── rtc_test.c
├── uart
├── .cproject
├── .project
├── .settings
│ └── de.innot.avreclipse.core.prefs
├── README
├── TODO
├── uart.c
├── uart.h
├── uart_description.c
├── uart_description.h
└── uart_quirks.h
└── uart_test
├── .cproject
├── .project
├── .settings
└── de.innot.avreclipse.core.prefs
└── uart_test.c
/.gitignore:
--------------------------------------------------------------------------------
1 | .metadata
2 | Debug
3 | Release
4 | Release_*
5 | RemoteSystemsTempFiles
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jeremy Cole's AVR Projects #
2 |
3 | Many smaller projects written by Jeremy Cole on Atmel AVR MCUs:
4 |
5 | * [uart](https://github.com/jeremycole/avr/tree/master/uart) -- A UART (serial) library based on Peter Fleury's uartlibrary. Also see [uart_test](https://github.com/jeremycole/avr/tree/master/uart_test).
6 | * [i2c](https://github.com/jeremycole/avr/tree/master/i2c) -- An I2C (aka TWI) library initially based on Peter Fleury's i2cmaster. Now includes slave mode support using callback functions. Also see [i2c_master_test](https://github.com/jeremycole/avr/tree/master/i2c_master_test) and [i2c_slave_test](https://github.com/jeremycole/avr/tree/master/i2c_slave_test).
7 | * [rtc](https://github.com/jeremycole/avr/tree/master/rtc) -- A custom real-time clock (RTC) library currently supporting the Maxim's DS1307 I2C-connected RTC chip. The rtc library requires the i2c library above. Also see [rtc_test](https://github.com/jeremycole/avr/tree/master/rtc_test).
8 | * [lcd](https://github.com/jeremycole/avr/tree/master/lcd) -- An LCD library supporting both 8-bit and 4-bit parallel modes of the HD44780U LCD controller. Also see [lcd_test](https://github.com/jeremycole/avr/tree/master/lcd_test).
9 | * [led_charlieplex](https://github.com/jeremycole/avr/tree/master/led_charlieplex) -- A custom library for generically describing the structure of and controlling a charlieplexed LED matrix.
10 | * [led_sequencer](https://github.com/jeremycole/avr/tree/master/led_sequencer) -- A custom library for time-sequencing LED animations, supporting the led_charlieplex library for describing the LED matrix to play animations on.
11 | * [nmea](https://github.com/jeremycole/avr/tree/master/nmea) -- An NMEA sentence parser for interoperation with GPS devices. Currently only supports `$GPRMC` sentences.
12 |
13 | Larger specific projects:
14 |
15 | * [led_analog_clock](https://github.com/jeremycole/avr/tree/master/led_analog_clock) -- The complete set of code using the uart (for debugging and setting the time), i2c, rtc, led_charlieplex, and led_sequencer libraries. Can connect to the lcd_i2c_digital_clock via I2C interface.
16 | * [lcd_i2c_digital_clock](https://github.com/jeremycole/avr/tree/master/lcd_i2c_digital_clock) -- An LCD-based digital clock module that attaches to led_analog_clock via I2C interface and displays the time in digital form.
17 | * [gps_i2c](https://github.com/jeremycole/avr/tree/master/gps_i2c) -- A translator from UART to I2C to allow a GPS to be attached to the led_analog_clock project to provide an accurate time sync source.
--------------------------------------------------------------------------------
/gps_i2c/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | gps_i2c
4 |
5 |
6 | i2c
7 | nmea
8 | rtc
9 | uart
10 |
11 |
12 |
13 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
14 | clean,full,incremental,
15 |
16 |
17 |
18 |
19 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
20 | full,incremental,
21 |
22 |
23 |
24 |
25 |
26 | org.eclipse.cdt.core.cnature
27 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
28 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
29 | de.innot.avreclipse.core.avrnature
30 |
31 |
32 |
--------------------------------------------------------------------------------
/gps_i2c/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega1284p
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/MCUType=atmega1284p
11 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/UseExtendedRAMforHeap=true
13 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/BitBangDelay=
14 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Bitclock=
15 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/EEPROMFile=
16 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/EEPROMFromConfig=true
17 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/FlashFile=
18 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/FlashFromConfig=true
19 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Fuses/ByteValues=194\:209\:253
20 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Fuses/FileName=
21 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Fuses/MCUid=atmega1284p
22 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Fuses/UseFile=false
23 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/Fuses/Write=true
24 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/NoChipErase=false
25 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/NoSigCheck=false
26 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/NoVerify=false
27 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/NoWrite=false
28 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/OtherOptions=
29 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/ProgrammerID=programmerconfig.1
30 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/UseCounter=false
31 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/WriteEEPROM=false
32 | avrtarget/de.innot.avreclipse.configuration.app.release.881431360.1697256572/avrdude/WriteFlash=true
33 | avrtarget/perConfig=true
34 | eclipse.preferences.version=1
35 |
--------------------------------------------------------------------------------
/i2c/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | i2c
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 |
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | make
31 |
32 |
33 | org.eclipse.cdt.make.core.buildLocation
34 | ${workspace_loc:/i2c/Release}
35 |
36 |
37 | org.eclipse.cdt.make.core.cleanBuildTarget
38 | clean
39 |
40 |
41 | org.eclipse.cdt.make.core.contents
42 | org.eclipse.cdt.make.core.activeConfigSettings
43 |
44 |
45 | org.eclipse.cdt.make.core.enableAutoBuild
46 | false
47 |
48 |
49 | org.eclipse.cdt.make.core.enableCleanBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.enableFullBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.fullBuildTarget
58 | all
59 |
60 |
61 | org.eclipse.cdt.make.core.stopOnError
62 | true
63 |
64 |
65 | org.eclipse.cdt.make.core.useDefaultBuildCmd
66 | true
67 |
68 |
69 |
70 |
71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
72 |
73 |
74 |
75 |
76 |
77 | org.eclipse.cdt.core.cnature
78 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
79 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
80 | de.innot.avreclipse.core.avrnature
81 |
82 |
83 |
--------------------------------------------------------------------------------
/i2c/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=10
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/NoChipErase=false
14 | avrtarget/avrdude/NoSigCheck=false
15 | avrtarget/avrdude/NoVerify=false
16 | avrtarget/avrdude/NoWrite=false
17 | avrtarget/avrdude/OtherOptions=
18 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
19 | avrtarget/avrdude/UseCounter=false
20 | avrtarget/avrdude/WriteEEPROM=false
21 | avrtarget/avrdude/WriteFlash=true
22 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/ClockFrequency=8000000
23 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/ExtRAMSize=0
24 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/ExtendedRAM=false
25 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/MCUType=atmega1284p
26 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/UseEEPROM=false
27 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050.931460294/UseExtendedRAMforHeap=true
28 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/ClockFrequency=8000000
29 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/ExtRAMSize=0
30 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/ExtendedRAM=false
31 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/MCUType=atmega644
32 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/UseEEPROM=false
33 | avrtarget/de.innot.avreclipse.configuration.lib.release.6991877.1692053050/UseExtendedRAMforHeap=true
34 | avrtarget/perConfig=true
35 | eclipse.preferences.version=1
36 |
--------------------------------------------------------------------------------
/i2c/i2c.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 | Copyright (c) 2006, Peter Fleury
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 |
19 | */
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "i2c.h"
27 |
28 | /* I2C clock in Hz */
29 | #ifndef I2C_SCL_CLOCK
30 | #define I2C_SCL_CLOCK 100000L
31 | #endif
32 |
33 | #define I2C_WAIT_CLEAR(v, b) while(!((v) & _BV((b))))
34 | #define I2C_WAIT_SET(v, b) while((v) & _BV((b)))
35 |
36 | #define I2C_ENABLE_ISR() TWCR |= _BV(TWIE)
37 | #define I2C_DISABLE_ISR() TWCR &= ~_BV(TWIE)
38 |
39 | volatile i2c_t i2c_global;
40 |
41 | ISR(TWI_vect)
42 | {
43 | uint8_t status;
44 | i2c_mode_t last_mode;
45 |
46 | last_mode = i2c_global.mode;
47 | status = TW_STATUS;
48 |
49 | /*
50 | * Receiving any of these statuses changes the current I2C mode regardless
51 | * of its current state.
52 | */
53 | switch(status)
54 | {
55 | case TW_ST_SLA_ACK:
56 | case TW_ST_ARB_LOST_SLA_ACK:
57 | i2c_global.mode = I2C_MODE_ST;
58 | break;
59 | case TW_SR_SLA_ACK:
60 | case TW_SR_ARB_LOST_SLA_ACK:
61 | case TW_SR_GCALL_ACK:
62 | case TW_SR_ARB_LOST_GCALL_ACK:
63 | i2c_global.mode = I2C_MODE_SR;
64 | break;
65 | case TW_SR_STOP:
66 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
67 | i2c_global.mode = I2C_MODE_IDLE;
68 | break;
69 | case TW_NO_INFO:
70 | case TW_BUS_ERROR:
71 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
72 | i2c_global.mode = I2C_MODE_IDLE;
73 | break;
74 | }
75 |
76 | switch(i2c_global.mode)
77 | {
78 | case I2C_MODE_MT:
79 | case I2C_MODE_MR:
80 | break;
81 |
82 | case I2C_MODE_ST:
83 | if(i2c_global.st_callback)
84 | {
85 | (*i2c_global.st_callback)(status, last_mode, i2c_global.mode);
86 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
87 | }
88 | break;
89 | case I2C_MODE_SR:
90 | if(i2c_global.sr_callback)
91 | {
92 | if(0 == (*i2c_global.sr_callback)(status, last_mode, i2c_global.mode))
93 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
94 | }
95 | break;
96 |
97 | case I2C_MODE_IDLE:
98 | if(last_mode == I2C_MODE_SR)
99 | {
100 | if(i2c_global.stop_callback)
101 | {
102 | (*i2c_global.stop_callback)(status, last_mode, i2c_global.mode);
103 | }
104 | }
105 | break;
106 | case I2C_MODE_UNKNOWN:
107 | default:
108 | break;
109 | }
110 | }
111 |
112 | /*
113 | * Initialization of the I2C bus interface. Need to be called only once.
114 | */
115 | void i2c_init(void)
116 | {
117 | TWBR = ((F_CPU/I2C_SCL_CLOCK)-16)/2;
118 | i2c_global.mode = I2C_MODE_IDLE;
119 | i2c_global.st_callback = NULL;
120 | i2c_global.sr_callback = NULL;
121 | I2C_ENABLE_ISR();
122 | }
123 |
124 | uint8_t i2c_slave_init(uint8_t address, uint8_t address_mask, uint8_t gcall)
125 | {
126 | TWAR = address | (gcall & 0x01);
127 | TWAMR = address_mask;
128 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
129 |
130 | return TWAR;
131 | }
132 |
133 | /*
134 | * Issues a start condition and sends address and transfer direction.
135 | *
136 | * Return: 0 device accessible
137 | * 1 failed to access device
138 | */
139 | uint8_t i2c_start(uint8_t address, uint8_t mode)
140 | {
141 | uint8_t twst;
142 |
143 | i2c_global.mode = (mode == I2C_WRITE)?I2C_MODE_MT:I2C_MODE_MR;
144 |
145 | /* Send START condition */
146 | TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTA);
147 |
148 | /* Wait until transmission completed */
149 | I2C_WAIT_CLEAR(TWCR, TWINT);
150 |
151 | /* Check value of TWI Status Register. */
152 | twst = TW_STATUS;
153 | if ( (twst != TW_START) && (twst != TW_REP_START)) return twst;
154 |
155 | /* Send device address */
156 | TWDR = address | mode;
157 | TWCR = _BV(TWINT) | _BV(TWEN);
158 |
159 | /* Wait until transmission completed and ACK/NACK has been received */
160 | I2C_WAIT_CLEAR(TWCR, TWINT);
161 |
162 | /* Check value of TWI Status Register. */
163 | twst = TW_STATUS;
164 | if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return twst;
165 |
166 | return 0;
167 | }
168 |
169 |
170 | /*
171 | * Issues a repeated start condition and sends address and transfer direction.
172 | *
173 | * Input: Address and transfer direction of I2C device.
174 | *
175 | * Return: 0 device accessible
176 | * 1 failed to access device
177 | */
178 | uint8_t i2c_rep_start(uint8_t address, uint8_t mode)
179 | {
180 | return i2c_start(address, mode);
181 | }
182 |
183 |
184 | /*
185 | * Terminates the data transfer and releases the I2C bus.
186 | */
187 | void i2c_stop(void)
188 | {
189 | /* Send STOP condition. */
190 | TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
191 |
192 | /* Wait until STOP condition is executed and bus released. */
193 | I2C_WAIT_SET(TWCR, TWSTO);
194 |
195 | i2c_global.mode = I2C_MODE_IDLE;
196 | I2C_ENABLE_ISR();
197 | }
198 |
199 |
200 | /*
201 | * Send one byte to I2C device.
202 | *
203 | * Input: byte to be transfered
204 | *
205 | * Return: 0 write successful
206 | * 1 write failed
207 | */
208 | uint8_t i2c_write(uint8_t data)
209 | {
210 | uint8_t twst;
211 |
212 | /* Send data to the previously addressed device */
213 | TWDR = data;
214 | TWCR = _BV(TWINT) | _BV(TWEN);
215 |
216 | /* Wait until transmission completed */
217 | I2C_WAIT_CLEAR(TWCR, TWINT);
218 |
219 | /* Check value of TWI Status Register. */
220 | twst = TW_STATUS;
221 | if(twst != TW_MT_DATA_ACK)
222 | return twst;
223 |
224 | return 0;
225 | }
226 |
227 |
228 | /*
229 | * Send a string of bytes to I2C device.
230 | *
231 | * Input: byte to be transfered
232 | *
233 | * Return: 0 write successful
234 | * 1 write failed
235 | */
236 | uint8_t i2c_write_array(uint8_t *data, uint8_t count)
237 | {
238 | while(count--)
239 | {
240 | if(i2c_write(*data++) != 0) return count;
241 | }
242 |
243 | return 0;
244 | }
245 |
246 |
247 | /*
248 | * Read one byte from the I2C device, request more data from device.
249 | *
250 | * Return: byte read from I2C device
251 | */
252 | uint8_t i2c_read_ack(void)
253 | {
254 | TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
255 | I2C_WAIT_CLEAR(TWCR, TWINT);
256 |
257 | return TWDR;
258 | }
259 |
260 |
261 | /*
262 | * Read one byte from the I2C device, read is followed by a STOP condition
263 | *
264 | * Return: byte read from I2C device
265 | */
266 | uint8_t i2c_read_nak(void)
267 | {
268 | TWCR = _BV(TWINT) | _BV(TWEN);
269 | I2C_WAIT_CLEAR(TWCR, TWINT);
270 |
271 | return TWDR;
272 | }
273 |
274 |
275 | /*
276 | * Read multiple bytes from the I2C device, read may be followed by a STOP
277 | * condition if nak_last is true.
278 | *
279 | * Return: zero
280 | */
281 | uint8_t i2c_read_many(uint8_t *buffer, uint8_t count, uint8_t nak_last)
282 | {
283 | while(count--)
284 | {
285 | *buffer++ = i2c_read(!(nak_last && (count==0)));
286 | }
287 |
288 | return 0;
289 | }
290 |
--------------------------------------------------------------------------------
/i2c/i2c.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 | Copyright (c) 2006, Peter Fleury
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 |
19 | */
20 |
21 | #ifndef I2C_H
22 | #define I2C_H
23 |
24 | #include
25 |
26 | /**@{*/
27 |
28 | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
29 | #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
30 | #endif
31 |
32 | #include
33 |
34 | /** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
35 | #define I2C_READ 1
36 |
37 | /** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
38 | #define I2C_WRITE 0
39 |
40 | /** Only the specific address will be responded to (rather than a range) */
41 | #define I2C_ADDRESS_MASK_SINGLE 0
42 |
43 | /** Disable responses on the general call address. */
44 | #define I2C_GCALL_DISABLED 0
45 |
46 | /** Enable responses on the general call address. */
47 | #define I2C_GCALL_ENABLED 1
48 |
49 | typedef enum _i2c_mode_t
50 | {
51 | I2C_MODE_UNKNOWN = 0,
52 | I2C_MODE_IDLE,
53 | I2C_MODE_MT,
54 | I2C_MODE_MR,
55 | I2C_MODE_ST,
56 | I2C_MODE_SR
57 | } i2c_mode_t;
58 |
59 | typedef uint8_t (i2c_callback_t)(uint8_t status, i2c_mode_t last_mode, i2c_mode_t current_mode);
60 |
61 | typedef struct _i2c_t
62 | {
63 | i2c_mode_t mode;
64 | i2c_callback_t *st_callback;
65 | i2c_callback_t *sr_callback;
66 | i2c_callback_t *stop_callback;
67 | } i2c_t;
68 |
69 | extern volatile i2c_t i2c_global;
70 |
71 | /**
72 | @brief initialize the I2C master interace. Need to be called only once
73 | @param void
74 | @return none
75 | */
76 | extern void i2c_init(void);
77 |
78 | extern uint8_t i2c_slave_init(uint8_t address, uint8_t address_mask, uint8_t gcall);
79 |
80 | /**
81 | @brief Terminates the data transfer and releases the I2C bus
82 | @param void
83 | @return none
84 | */
85 | extern void i2c_stop(void);
86 |
87 |
88 | /**
89 | @brief Issues a start condition and sends address and transfer direction
90 |
91 | @param addr address and transfer direction of I2C device
92 | @retval 0 device accessible
93 | @retval 1 failed to access device
94 | */
95 | extern uint8_t i2c_start(uint8_t address, uint8_t mode);
96 |
97 |
98 | /**
99 | @brief Issues a repeated start condition and sends address and transfer direction
100 |
101 | @param addr address and transfer direction of I2C device
102 | @retval 0 device accessible
103 | @retval 1 failed to access device
104 | */
105 | extern uint8_t i2c_rep_start(uint8_t address, uint8_t mode);
106 |
107 |
108 | /**
109 | @brief Issues a start condition and sends address and transfer direction
110 |
111 | If device is busy, use ack polling to wait until device ready
112 | @param addr address and transfer direction of I2C device
113 | @return none
114 | */
115 | extern void i2c_start_wait(uint8_t address, uint8_t mode);
116 |
117 |
118 | /**
119 | @brief Send one byte to I2C device
120 | @param data byte to be transfered
121 | @retval 0 write successful
122 | @retval 1 write failed
123 | */
124 | extern uint8_t i2c_write(uint8_t data);
125 |
126 | extern uint8_t i2c_write_array(uint8_t *data, uint8_t count);
127 |
128 | /**
129 | @brief read one byte from the I2C device, request more data from device
130 | @return byte read from I2C device
131 | */
132 | extern uint8_t i2c_read_ack(void);
133 |
134 | /**
135 | @brief read one byte from the I2C device, read is followed by a stop condition
136 | @return byte read from I2C device
137 | */
138 | extern uint8_t i2c_read_nak(void);
139 |
140 | /**
141 | @brief read one byte from the I2C device
142 |
143 | Implemented as a macro, which calls either i2c_read_ack or i2c_read_nak
144 |
145 | @param ack 1 send ack, request more data from device
146 | 0 send nak, read is followed by a stop condition
147 | @return byte read from I2C device
148 | */
149 | extern uint8_t i2c_read(uint8_t ack);
150 | #define i2c_read(ack) ((ack) ? i2c_read_ack() : i2c_read_nak())
151 |
152 | extern uint8_t i2c_read_many(uint8_t *buffer, uint8_t count, uint8_t nak_last);
153 |
154 | /**@}*/
155 | #endif
156 |
--------------------------------------------------------------------------------
/i2c_master_test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | i2c_master_test
4 |
5 |
6 | i2c
7 | uart
8 |
9 |
10 |
11 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
12 | clean,full,incremental,
13 |
14 |
15 | ?name?
16 |
17 |
18 |
19 | org.eclipse.cdt.make.core.append_environment
20 | true
21 |
22 |
23 | org.eclipse.cdt.make.core.autoBuildTarget
24 | all
25 |
26 |
27 | org.eclipse.cdt.make.core.buildArguments
28 |
29 |
30 |
31 | org.eclipse.cdt.make.core.buildCommand
32 | make
33 |
34 |
35 | org.eclipse.cdt.make.core.buildLocation
36 | ${workspace_loc:/i2c_master_test/Release}
37 |
38 |
39 | org.eclipse.cdt.make.core.cleanBuildTarget
40 | clean
41 |
42 |
43 | org.eclipse.cdt.make.core.contents
44 | org.eclipse.cdt.make.core.activeConfigSettings
45 |
46 |
47 | org.eclipse.cdt.make.core.enableAutoBuild
48 | false
49 |
50 |
51 | org.eclipse.cdt.make.core.enableCleanBuild
52 | true
53 |
54 |
55 | org.eclipse.cdt.make.core.enableFullBuild
56 | true
57 |
58 |
59 | org.eclipse.cdt.make.core.fullBuildTarget
60 | all
61 |
62 |
63 | org.eclipse.cdt.make.core.stopOnError
64 | true
65 |
66 |
67 | org.eclipse.cdt.make.core.useDefaultBuildCmd
68 | true
69 |
70 |
71 |
72 |
73 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
74 |
75 |
76 |
77 |
78 |
79 | org.eclipse.cdt.core.cnature
80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
82 | de.innot.avreclipse.core.avrnature
83 |
84 |
85 |
--------------------------------------------------------------------------------
/i2c_master_test/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | #Sun Aug 15 19:00:16 PDT 2010
2 | avrtarget/ClockFrequency=8000000
3 | avrtarget/ExtRAMSize=0
4 | avrtarget/ExtendedRAM=false
5 | avrtarget/MCUType=atmega644p
6 | avrtarget/UseEEPROM=false
7 | avrtarget/UseExtendedRAMforHeap=true
8 | avrtarget/avrdude/BitBangDelay=
9 | avrtarget/avrdude/Bitclock=
10 | avrtarget/avrdude/EEPROMFile=
11 | avrtarget/avrdude/EEPROMFromConfig=true
12 | avrtarget/avrdude/FlashFile=
13 | avrtarget/avrdude/FlashFromConfig=true
14 | avrtarget/avrdude/NoChipErase=false
15 | avrtarget/avrdude/NoSigCheck=false
16 | avrtarget/avrdude/NoVerify=false
17 | avrtarget/avrdude/NoWrite=false
18 | avrtarget/avrdude/OtherOptions=
19 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
20 | avrtarget/avrdude/UseCounter=false
21 | avrtarget/avrdude/WriteEEPROM=false
22 | avrtarget/avrdude/WriteFlash=true
23 | avrtarget/perConfig=false
24 | eclipse.preferences.version=1
25 |
--------------------------------------------------------------------------------
/i2c_master_test/i2c_master_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | int main(void)
33 | {
34 | uart_t *u0;
35 | uint8_t x = 0;
36 |
37 | _delay_ms(1000);
38 |
39 | u0 = uart_init("0", 0);
40 | uart_init_stdout(u0);
41 |
42 | i2c_init();
43 |
44 | DDRC = _BV(PC0) | _BV(PC1);
45 | PORTC = _BV(PC0) | _BV(PC1);
46 |
47 | sei();
48 |
49 | printf("\n\nBooted up!\n");
50 |
51 | while(1)
52 | {
53 | printf("I2C Mode: %i\n", i2c_global.mode);
54 | if(0 == i2c_start(0x70, I2C_WRITE))
55 | {
56 | i2c_write(x++);
57 | i2c_write(x++);
58 | i2c_write(x++);
59 | }
60 | i2c_stop();
61 |
62 | _delay_ms(1000);
63 | }
64 |
65 | return(0);
66 | }
67 |
--------------------------------------------------------------------------------
/i2c_slave_test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | i2c_slave_test
4 |
5 |
6 | i2c
7 | uart
8 |
9 |
10 |
11 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
12 | clean,full,incremental,
13 |
14 |
15 | ?name?
16 |
17 |
18 |
19 | org.eclipse.cdt.make.core.append_environment
20 | true
21 |
22 |
23 | org.eclipse.cdt.make.core.autoBuildTarget
24 | all
25 |
26 |
27 | org.eclipse.cdt.make.core.buildArguments
28 |
29 |
30 |
31 | org.eclipse.cdt.make.core.buildCommand
32 | make
33 |
34 |
35 | org.eclipse.cdt.make.core.buildLocation
36 | ${workspace_loc:/i2c_slave_test/Release}
37 |
38 |
39 | org.eclipse.cdt.make.core.cleanBuildTarget
40 | clean
41 |
42 |
43 | org.eclipse.cdt.make.core.contents
44 | org.eclipse.cdt.make.core.activeConfigSettings
45 |
46 |
47 | org.eclipse.cdt.make.core.enableAutoBuild
48 | false
49 |
50 |
51 | org.eclipse.cdt.make.core.enableCleanBuild
52 | true
53 |
54 |
55 | org.eclipse.cdt.make.core.enableFullBuild
56 | true
57 |
58 |
59 | org.eclipse.cdt.make.core.fullBuildTarget
60 | all
61 |
62 |
63 | org.eclipse.cdt.make.core.stopOnError
64 | true
65 |
66 |
67 | org.eclipse.cdt.make.core.useDefaultBuildCmd
68 | true
69 |
70 |
71 |
72 |
73 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
74 |
75 |
76 |
77 |
78 |
79 | org.eclipse.cdt.core.cnature
80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
82 | de.innot.avreclipse.core.avrnature
83 |
84 |
85 |
--------------------------------------------------------------------------------
/i2c_slave_test/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | #Sun Aug 15 19:04:40 PDT 2010
2 | avrtarget/ClockFrequency=8000000
3 | avrtarget/ExtRAMSize=0
4 | avrtarget/ExtendedRAM=false
5 | avrtarget/MCUType=atmega644
6 | avrtarget/UseEEPROM=false
7 | avrtarget/UseExtendedRAMforHeap=true
8 | avrtarget/avrdude/BitBangDelay=
9 | avrtarget/avrdude/Bitclock=
10 | avrtarget/avrdude/EEPROMFile=
11 | avrtarget/avrdude/EEPROMFromConfig=true
12 | avrtarget/avrdude/FlashFile=
13 | avrtarget/avrdude/FlashFromConfig=true
14 | avrtarget/avrdude/NoChipErase=false
15 | avrtarget/avrdude/NoSigCheck=false
16 | avrtarget/avrdude/NoVerify=false
17 | avrtarget/avrdude/NoWrite=false
18 | avrtarget/avrdude/OtherOptions=
19 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
20 | avrtarget/avrdude/UseCounter=false
21 | avrtarget/avrdude/WriteEEPROM=false
22 | avrtarget/avrdude/WriteFlash=true
23 | avrtarget/perConfig=false
24 | eclipse.preferences.version=1
25 |
--------------------------------------------------------------------------------
/i2c_slave_test/i2c_slave_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | uint8_t i2c_data[16];
33 | uint8_t data_offset;
34 |
35 | uint8_t handle_sr(uint8_t status, i2c_mode_t last_mode, i2c_mode_t current_mode)
36 | {
37 | if(last_mode != current_mode)
38 | {
39 | data_offset=0;
40 | memset(i2c_data, 0, 16);
41 | }
42 |
43 | if(status == TW_SR_DATA_ACK || status == TW_SR_DATA_NACK)
44 | i2c_data[data_offset++] = TWDR;
45 |
46 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
47 | return 0;
48 | }
49 |
50 | int main(void)
51 | {
52 | uart_t *u0;
53 |
54 | _delay_ms(1000);
55 |
56 | u0 = uart_init("0", 0);
57 | uart_init_stdout(u0);
58 |
59 | i2c_init();
60 | i2c_slave_init(0x70, 0, 0);
61 | i2c_global.sr_callback = handle_sr;
62 |
63 | sei();
64 |
65 | printf("\n\nBooted up!\n");
66 |
67 | while(1)
68 | {
69 | printf("I2C Mode: %i, Data: %i, %i, %i\n", i2c_global.mode,
70 | i2c_data[0], i2c_data[1], i2c_data[2]);
71 |
72 | _delay_ms(1000);
73 | }
74 |
75 | return(0);
76 | }
77 |
--------------------------------------------------------------------------------
/lcd/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | lcd
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 |
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | make
31 |
32 |
33 | org.eclipse.cdt.make.core.buildLocation
34 | ${workspace_loc:/lcd/Debug}
35 |
36 |
37 | org.eclipse.cdt.make.core.cleanBuildTarget
38 | clean
39 |
40 |
41 | org.eclipse.cdt.make.core.contents
42 | org.eclipse.cdt.make.core.activeConfigSettings
43 |
44 |
45 | org.eclipse.cdt.make.core.enableAutoBuild
46 | false
47 |
48 |
49 | org.eclipse.cdt.make.core.enableCleanBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.enableFullBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.fullBuildTarget
58 | all
59 |
60 |
61 | org.eclipse.cdt.make.core.stopOnError
62 | true
63 |
64 |
65 | org.eclipse.cdt.make.core.useDefaultBuildCmd
66 | true
67 |
68 |
69 |
70 |
71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
72 |
73 |
74 |
75 |
76 |
77 | org.eclipse.cdt.core.cnature
78 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
79 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
80 | de.innot.avreclipse.core.avrnature
81 |
82 |
83 |
--------------------------------------------------------------------------------
/lcd/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/MCUType=atmega1284p
11 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214.727203139/UseExtendedRAMforHeap=true
13 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/ClockFrequency=8000000
14 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/ExtRAMSize=0
15 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/ExtendedRAM=false
16 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/MCUType=atmega644
17 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/UseEEPROM=false
18 | avrtarget/de.innot.avreclipse.configuration.lib.release.1970224268.527364214/UseExtendedRAMforHeap=true
19 | avrtarget/perConfig=true
20 | eclipse.preferences.version=1
21 |
--------------------------------------------------------------------------------
/lcd/lcd.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "lcd.h"
27 |
28 | void lcd_init(lcd_t *lcd)
29 | {
30 | *lcd->rs.ddr |= _BV(lcd->rs.bv);
31 | *lcd->rw.ddr |= _BV(lcd->rw.bv);
32 | *lcd->e.ddr |= _BV(lcd->e.bv);
33 |
34 | _delay_ms(20);
35 | lcd_parameters(lcd, lcd->interface);
36 |
37 | _delay_ms(6);
38 | lcd_parameters(lcd, lcd->interface);
39 |
40 | _delay_us(150);
41 | lcd_parameters(lcd, lcd->interface);
42 |
43 | lcd_parameters(lcd, lcd->interface | LCD_LINES_2 | LCD_FONT_5X8);
44 | lcd_entry_mode(lcd, LCD_CURSOR_INCREMENT | LCD_DISPLAY_SHIFT_OFF);
45 | lcd_clear(lcd);
46 | lcd_display_mode(lcd, LCD_DISPLAY_ON);
47 | }
48 |
49 | uint8_t _lcd_read_data(lcd_t *lcd)
50 | {
51 | uint8_t data = 0;
52 |
53 | *lcd->e.port |= _BV(lcd->e.bv);
54 | _delay_us(0.1);
55 | switch(lcd->interface)
56 | {
57 | case LCD_INTERFACE_8BIT:
58 | data = *lcd->data.pin;
59 | break;
60 | case LCD_INTERFACE_4BIT:
61 | data = ((*lcd->data.pin & (0x0f << lcd->data.bv)) >> lcd->data.bv) << 4;
62 | _delay_us(0.3);
63 | *lcd->e.port &= ~_BV(lcd->e.bv);
64 | _delay_us(0.3);
65 | *lcd->e.port |= _BV(lcd->e.bv);
66 | _delay_us(0.3);
67 | data |= ((*lcd->data.pin & (0x0f << lcd->data.bv)) >> lcd->data.bv);
68 | break;
69 | }
70 | _delay_us(0.3);
71 | *lcd->e.port &= ~_BV(lcd->e.bv);
72 | _delay_us(0.3);
73 |
74 | switch(lcd->interface)
75 | {
76 | case LCD_INTERFACE_8BIT:
77 | *lcd->data.port = 0x00;
78 | *lcd->data.ddr = 0x00;
79 | break;
80 | case LCD_INTERFACE_4BIT:
81 | *lcd->data.port &= ~(0x0f << lcd->data.bv);
82 | *lcd->data.ddr &= ~(0x0f << lcd->data.bv);
83 | break;
84 | }
85 |
86 | return data;
87 | }
88 |
89 | void _lcd_write_data(lcd_t *lcd, uint8_t data)
90 | {
91 | *lcd->e.port |= _BV(lcd->e.bv);
92 | _delay_us(0.1);
93 | switch(lcd->interface)
94 | {
95 | case LCD_INTERFACE_8BIT:
96 | *lcd->data.ddr = 0xff;
97 | *lcd->data.port = data;
98 | break;
99 | case LCD_INTERFACE_4BIT:
100 | *lcd->data.ddr |= 0x0f << lcd->data.bv;
101 | *lcd->data.port |= ((data & 0xf0) >> 4) << lcd->data.bv;
102 | _delay_us(0.3);
103 | *lcd->e.port &= ~_BV(lcd->e.bv);
104 | *lcd->data.port &= ~(0x0f << lcd->data.bv);
105 | _delay_us(0.3);
106 | *lcd->e.port |= _BV(lcd->e.bv);
107 | _delay_us(0.3);
108 | *lcd->data.port |= (data & 0x0f) << lcd->data.bv;
109 | break;
110 | }
111 | _delay_us(0.3);
112 | *lcd->e.port &= ~_BV(lcd->e.bv);
113 | _delay_us(0.3);
114 |
115 | switch(lcd->interface)
116 | {
117 | case LCD_INTERFACE_8BIT:
118 | *lcd->data.port = 0x00;
119 | *lcd->data.ddr = 0x00;
120 | break;
121 | case LCD_INTERFACE_4BIT:
122 | *lcd->data.port &= ~(0x0f << lcd->data.bv);
123 | *lcd->data.ddr &= ~(0x0f << lcd->data.bv);
124 | break;
125 | }
126 | }
127 |
128 | uint8_t lcd_read_sr(lcd_t *lcd)
129 | {
130 | int status;
131 |
132 | *lcd->rw.port |= _BV(lcd->rw.bv);
133 | *lcd->rs.port &= ~_BV(lcd->rs.bv);
134 | _delay_us(0.1);
135 | status = _lcd_read_data(lcd);
136 | *lcd->rs.port &= ~_BV(lcd->rs.bv);
137 | *lcd->rw.port &= ~_BV(lcd->rw.bv);
138 | _delay_us(0.2);
139 |
140 | return status;
141 | }
142 |
143 | void lcd_write_ir(lcd_t *lcd, uint8_t instruction)
144 | {
145 | while ((lcd_read_sr(lcd) & LCD_BUSY) != 0) {};
146 |
147 | *lcd->rs.port &= ~_BV(lcd->rs.bv);
148 | *lcd->rw.port &= ~_BV(lcd->rw.bv);
149 | _delay_us(0.1);
150 | _lcd_write_data(lcd, instruction);
151 | _delay_us(0.2);
152 | }
153 |
154 | void lcd_write_dr(lcd_t *lcd, uint8_t data)
155 | {
156 | while ((lcd_read_sr(lcd) & LCD_BUSY) != 0) {};
157 |
158 | *lcd->rw.port &= ~_BV(lcd->rw.bv);
159 | *lcd->rs.port |= _BV(lcd->rs.bv);
160 | _delay_us(0.1);
161 | _lcd_write_data(lcd, data);
162 | *lcd->rs.port &= ~_BV(lcd->rs.bv);
163 | *lcd->rw.port &= ~_BV(lcd->rw.bv);
164 | _delay_us(0.2);
165 | }
166 |
167 | void lcd_display_mode(lcd_t *lcd, uint8_t mode)
168 | {
169 | lcd_write_ir(lcd, LCD_IR_MODE_DISPLAY | mode);
170 | }
171 |
172 | void lcd_parameters(lcd_t *lcd, uint8_t parameters)
173 | {
174 | lcd_write_ir(lcd, LCD_IR_MODE_PARAMETERS | parameters);
175 | }
176 |
177 | void lcd_entry_mode(lcd_t *lcd, uint8_t mode)
178 | {
179 | lcd_write_ir(lcd, LCD_IR_MODE_ENTRY | mode);
180 | }
181 |
182 | void lcd_move_cursor(lcd_t *lcd, uint8_t line, uint8_t col)
183 | {
184 | lcd_write_ir(lcd, LCD_IR_MODE_DDRAM_ADDR | ((LCD_LINE_DDRAM_WIDTH * line) + col) );
185 | }
186 |
187 | void lcd_cg_define(lcd_t *lcd, uint8_t character, uint8_t data[8])
188 | {
189 | uint8_t pos;
190 | lcd_write_ir(lcd, LCD_IR_MODE_CGRAM_ADDR | (character * 8));
191 | for(pos=0; pos < 8; pos++)
192 | {
193 | lcd_write_dr(lcd, data[pos]);
194 | }
195 | }
196 |
197 | void lcd_clear(lcd_t *lcd)
198 | {
199 | lcd_write_ir(lcd, LCD_IR_CLEAR);
200 | }
201 |
202 | void lcd_return_home(lcd_t *lcd)
203 | {
204 | lcd_write_ir(lcd, LCD_IR_RETURN_HOME);
205 | }
206 |
207 | void lcd_write_char(lcd_t *lcd, char c)
208 | {
209 | lcd_write_dr(lcd, c);
210 | }
211 |
212 | void lcd_write_string(lcd_t *lcd, char *s, int n)
213 | {
214 | for (; n>0; n--, s++)
215 | {
216 | lcd_write_dr(lcd, *s);
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/lcd/lcd.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef LCD_H
21 | #define LCD_H
22 |
23 | #include
24 |
25 | #define LCD_IR_CLEAR (0x01)
26 | #define LCD_IR_RETURN_HOME (0x02)
27 |
28 | #define LCD_IR_MODE_ENTRY (0x04)
29 | #define LCD_CURSOR_DECREMENT (0x00)
30 | #define LCD_CURSOR_INCREMENT (0x02)
31 | #define LCD_DISPLAY_SHIFT_OFF (0x00)
32 | #define LCD_DISPLAY_SHIFT_ON (0x01)
33 |
34 | #define LCD_IR_MODE_DISPLAY (0x08)
35 | #define LCD_DISPLAY_ON (0x04)
36 | #define LCD_CURSOR_ON (0x02)
37 | #define LCD_CURSOR_BLINK (0x01)
38 |
39 | #define LCD_IR_MODE_PARAMETERS (0x20)
40 | #define LCD_INTERFACE_4BIT (0x00)
41 | #define LCD_INTERFACE_8BIT (0x10)
42 | #define LCD_LINES_1 (0x00)
43 | #define LCD_LINES_2 (0x08)
44 | #define LCD_FONT_5X8 (0x00)
45 | #define LCD_FONT_5X11 (0x04)
46 |
47 | #define LCD_IR_MODE_CGRAM_ADDR (0x40)
48 | #define LCD_IR_MODE_DDRAM_ADDR (0x80)
49 |
50 | #define LCD_BUSY (0x80)
51 |
52 | #define LCD_LINE_DDRAM_WIDTH (0x40)
53 |
54 | typedef struct _lcd_port_t
55 | {
56 | volatile uint8_t *pin;
57 | volatile uint8_t *port;
58 | volatile uint8_t *ddr;
59 | uint8_t bv;
60 | } lcd_port_t;
61 |
62 | typedef struct _lcd_t
63 | {
64 | uint8_t interface;
65 | lcd_port_t data;
66 | lcd_port_t rs;
67 | lcd_port_t rw;
68 | lcd_port_t e;
69 | } lcd_t;
70 |
71 | typedef uint8_t lcd_cg_t[8];
72 |
73 | void lcd_init(lcd_t *lcd);
74 | uint8_t lcd_read_sr(lcd_t *lcd);
75 | void lcd_write_ir(lcd_t *lcd, uint8_t instruction);
76 | void lcd_write_dr(lcd_t *lcd, uint8_t data);
77 | void lcd_display_mode(lcd_t *lcd, uint8_t mode);
78 | void lcd_parameters(lcd_t *lcd, uint8_t parameters);
79 | void lcd_entry_mode(lcd_t *lcd, uint8_t mode);
80 | void lcd_move_cursor(lcd_t *lcd, uint8_t line, uint8_t col);
81 | void lcd_cg_define(lcd_t *lcd, uint8_t character, uint8_t data[8]);
82 | void lcd_clear(lcd_t *lcd);
83 | void lcd_return_home(lcd_t *lcd);
84 | void lcd_write_char(lcd_t *lcd, char c);
85 | void lcd_write_string(lcd_t *lcd, char *s, int n);
86 |
87 | #endif /* LCD_H */
88 |
--------------------------------------------------------------------------------
/lcd_i2c_digital_clock/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | lcd_i2c_digital_clock
4 |
5 |
6 | i2c
7 | lcd
8 | rtc
9 | uart
10 |
11 |
12 |
13 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
14 | clean,full,incremental,
15 |
16 |
17 | ?name?
18 |
19 |
20 |
21 | org.eclipse.cdt.make.core.append_environment
22 | true
23 |
24 |
25 | org.eclipse.cdt.make.core.autoBuildTarget
26 | all
27 |
28 |
29 | org.eclipse.cdt.make.core.buildArguments
30 |
31 |
32 |
33 | org.eclipse.cdt.make.core.buildCommand
34 | make
35 |
36 |
37 | org.eclipse.cdt.make.core.buildLocation
38 | ${workspace_loc:/lcd_test/Release}
39 |
40 |
41 | org.eclipse.cdt.make.core.cleanBuildTarget
42 | clean
43 |
44 |
45 | org.eclipse.cdt.make.core.contents
46 | org.eclipse.cdt.make.core.activeConfigSettings
47 |
48 |
49 | org.eclipse.cdt.make.core.enableAutoBuild
50 | false
51 |
52 |
53 | org.eclipse.cdt.make.core.enableCleanBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.enableFullBuild
58 | true
59 |
60 |
61 | org.eclipse.cdt.make.core.fullBuildTarget
62 | all
63 |
64 |
65 | org.eclipse.cdt.make.core.stopOnError
66 | true
67 |
68 |
69 | org.eclipse.cdt.make.core.useDefaultBuildCmd
70 | true
71 |
72 |
73 |
74 |
75 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
76 |
77 |
78 |
79 |
80 |
81 | org.eclipse.cdt.core.cnature
82 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
83 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
84 | de.innot.avreclipse.core.avrnature
85 |
86 |
87 |
--------------------------------------------------------------------------------
/lcd_i2c_digital_clock/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=10
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/Fuses/ByteValues=194\:217\:255
14 | avrtarget/avrdude/Fuses/FileName=
15 | avrtarget/avrdude/Fuses/MCUid=atmega644
16 | avrtarget/avrdude/Fuses/UseFile=false
17 | avrtarget/avrdude/Fuses/Write=true
18 | avrtarget/avrdude/NoChipErase=false
19 | avrtarget/avrdude/NoSigCheck=false
20 | avrtarget/avrdude/NoVerify=false
21 | avrtarget/avrdude/NoWrite=false
22 | avrtarget/avrdude/OtherOptions=
23 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
24 | avrtarget/avrdude/UseCounter=false
25 | avrtarget/avrdude/WriteEEPROM=false
26 | avrtarget/avrdude/WriteFlash=true
27 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/ClockFrequency=8000000
28 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/ExtRAMSize=0
29 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/ExtendedRAM=false
30 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/MCUType=atmega1284p
31 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/UseEEPROM=false
32 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/UseExtendedRAMforHeap=true
33 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/BitBangDelay=
34 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Bitclock=
35 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/EEPROMFile=
36 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/EEPROMFromConfig=true
37 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/FlashFile=
38 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/FlashFromConfig=true
39 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Fuses/ByteValues=194\:209\:252
40 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Fuses/FileName=
41 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Fuses/MCUid=atmega1284p
42 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Fuses/UseFile=false
43 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/Fuses/Write=true
44 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/NoChipErase=false
45 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/NoSigCheck=false
46 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/NoVerify=false
47 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/NoWrite=false
48 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/OtherOptions=
49 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/ProgrammerID=programmerconfig.1
50 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/UseCounter=false
51 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/WriteEEPROM=false
52 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634.709383679/avrdude/WriteFlash=true
53 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/ClockFrequency=8000000
54 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/ExtRAMSize=0
55 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/ExtendedRAM=false
56 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/MCUType=atmega644
57 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/UseEEPROM=false
58 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/UseExtendedRAMforHeap=true
59 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/BitBangDelay=
60 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Bitclock=
61 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/EEPROMFile=
62 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/EEPROMFromConfig=true
63 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/FlashFile=
64 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/FlashFromConfig=true
65 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Fuses/ByteValues=194\:209\:252
66 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Fuses/FileName=
67 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Fuses/MCUid=atmega644
68 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Fuses/UseFile=false
69 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/Fuses/Write=true
70 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/NoChipErase=false
71 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/NoSigCheck=false
72 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/NoVerify=false
73 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/NoWrite=false
74 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/OtherOptions=
75 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/ProgrammerID=programmerconfig.1
76 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/UseCounter=false
77 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/WriteEEPROM=false
78 | avrtarget/de.innot.avreclipse.configuration.app.release.789230477.1525111634/avrdude/WriteFlash=true
79 | avrtarget/perConfig=true
80 | eclipse.preferences.version=1
81 |
--------------------------------------------------------------------------------
/lcd_i2c_digital_clock/lcd_i2c_digital_clock.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | /*
21 |
22 | LCD I2C Digital Clock
23 | =====================
24 |
25 | An LCD digital clock controlled by I2C, using LCD Backpack, initially
26 | designed to be connected to LED Analog Clock. This code expects an
27 | rtc_datetime_24h_t to be transmitted after an I2C START. For example,
28 | from the I2C master-side, the following code will pass a (locally
29 | created) rtc_datetime_24h_t structure to the LCD I2C Digital Clock for
30 | display:
31 |
32 | void write_remote_lcd(rtc_datetime_24h_t *dt)
33 | {
34 | if(0 == i2c_start(0x70, I2C_WRITE))
35 | {
36 | i2c_write_array((uint8_t *)dt, 8);
37 | }
38 | i2c_stop();
39 | }
40 |
41 | In the future, a more robust protocol supporting many more features could
42 | be implemented by collecting a byte "register" before accepting more data.
43 |
44 | */
45 |
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 |
55 | #define I2C_SCL_CLOCK 400000L
56 | #include
57 | #include
58 | #include
59 | #include
60 |
61 | #define LCD_CON_OCR OCR0A
62 | #define LCD_BKL_OCR OCR0B
63 |
64 | lcd_t lcd = {
65 | .interface = LCD_INTERFACE_8BIT,
66 | .data = {&PINA, &PORTA, &DDRA, PA0},
67 | .rs = {&PINB, &PORTB, &DDRB, PB1},
68 | .rw = {&PINB, &PORTB, &DDRB, PB2},
69 | .e = {&PINB, &PORTB, &DDRB, PB0}
70 | };
71 |
72 | #define MAX_DATA_AGE_CS 150
73 |
74 | struct {
75 | rtc_datetime_24h_t current_dt;
76 | uint8_t gps_signal_strength;
77 | } data;
78 | uint8_t *data_p;
79 | uint8_t data_age = MAX_DATA_AGE_CS;
80 |
81 | #define CG_GPS_ICON 0
82 | lcd_cg_t cg_gps_icon = {
83 | 0b00000000,
84 | 0b00000000,
85 | 0b00000000,
86 | 0b00000110,
87 | 0b00001000,
88 | 0b00001011,
89 | 0b00001001,
90 | 0b00000110,
91 | };
92 |
93 | #define CG_GPS_SIGNAL 1
94 | #define CG_GPS_SIGNAL_SIZE 9
95 | lcd_cg_t cg_gps_signal[9] = {
96 | { // 0, "X" drawing
97 | 0b00000000,
98 | 0b00000000,
99 | 0b00000000,
100 | 0b00010001,
101 | 0b00001010,
102 | 0b00000100,
103 | 0b00001010,
104 | 0b00010001,
105 | },
106 | { // 1
107 | 0b00000000,
108 | 0b00000000,
109 | 0b00000000,
110 | 0b00000000,
111 | 0b00000000,
112 | 0b00000000,
113 | 0b00000000,
114 | 0b00000001,
115 | },
116 | { // 2
117 | 0b00000000,
118 | 0b00000000,
119 | 0b00000000,
120 | 0b00000000,
121 | 0b00000000,
122 | 0b00000000,
123 | 0b00000001,
124 | 0b00000011,
125 | },
126 | { // 3
127 | 0b00000000,
128 | 0b00000000,
129 | 0b00000000,
130 | 0b00000000,
131 | 0b00000000,
132 | 0b00000001,
133 | 0b00000011,
134 | 0b00000111,
135 | },
136 | { // 4
137 | 0b00000000,
138 | 0b00000000,
139 | 0b00000000,
140 | 0b00000000,
141 | 0b00000001,
142 | 0b00000011,
143 | 0b00000111,
144 | 0b00001111,
145 | },
146 | { // 5
147 | 0b00000000,
148 | 0b00000000,
149 | 0b00000000,
150 | 0b00000001,
151 | 0b00000011,
152 | 0b00000111,
153 | 0b00001111,
154 | 0b00011111,
155 | },
156 | { // 6
157 | 0b00000000,
158 | 0b00000000,
159 | 0b00000001,
160 | 0b00000011,
161 | 0b00000111,
162 | 0b00001111,
163 | 0b00011111,
164 | 0b00011111,
165 | },
166 | { // 7
167 | 0b00000000,
168 | 0b00000001,
169 | 0b00000011,
170 | 0b00000111,
171 | 0b00001111,
172 | 0b00011111,
173 | 0b00011111,
174 | 0b00011111,
175 | },
176 | { // 8
177 | 0b00000001,
178 | 0b00000011,
179 | 0b00000111,
180 | 0b00001111,
181 | 0b00011111,
182 | 0b00011111,
183 | 0b00011111,
184 | 0b00011111,
185 | },
186 | };
187 |
188 | uint8_t handle_i2c_slave_rx(uint8_t status, i2c_mode_t last_mode, i2c_mode_t current_mode)
189 | {
190 | if(last_mode != current_mode)
191 | {
192 | data_p = (uint8_t *)&data;
193 | }
194 |
195 | if(status == TW_SR_DATA_ACK || status == TW_SR_DATA_NACK)
196 | *data_p++ = TWDR;
197 |
198 | data_age = 0;
199 |
200 | return 0;
201 | }
202 |
203 | int main(void)
204 | {
205 | uart_t *u0;
206 | char s[32];
207 |
208 | _delay_ms(1000);
209 |
210 | u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU));
211 | uart_init_stdout(u0);
212 |
213 | i2c_init();
214 | i2c_slave_init(0x70, I2C_ADDRESS_MASK_SINGLE, I2C_GCALL_DISABLED);
215 | i2c_global.sr_callback = handle_i2c_slave_rx;
216 |
217 | DDRB |= _BV(PB3) | _BV(PB4);
218 |
219 | /*
220 | COM0A1 = Clear OC0A on compare match
221 | COM0B1 = Clear OC0B on compare match
222 | WGM01|WGM00 = Fast PWM
223 | */
224 | TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
225 | /* CS01 = Prescale by /8 */
226 | TCCR0B = _BV(CS01);
227 |
228 | LCD_CON_OCR = 90;
229 | LCD_BKL_OCR = 255;
230 |
231 | sei();
232 |
233 | printf("\n\nBooted up!\n");
234 |
235 | lcd_init(&lcd);
236 |
237 | lcd_cg_define(&lcd, CG_GPS_ICON, cg_gps_icon);
238 | lcd_cg_define(&lcd, CG_GPS_SIGNAL, cg_gps_signal[0]);
239 |
240 | while(1)
241 | {
242 | if(data_age == 0)
243 | {
244 | // Re-define the CG_GPS_SIGNAL character to a depiction of the current
245 | // signal strength (an "X" for no signal, or a number of bars).
246 | lcd_cg_define(&lcd, CG_GPS_SIGNAL,
247 | cg_gps_signal[data.gps_signal_strength]);
248 |
249 | sprintf(s, "%-10s%-4s%2i",
250 | rtc_dow_names[data.current_dt.day_of_week],
251 | rtc_month_abbreviations[data.current_dt.month],
252 | data.current_dt.date);
253 | lcd_move_cursor(&lcd, 0, 0);
254 | lcd_write_string(&lcd, s, strlen(s));
255 |
256 | sprintf(s, " %02i:%02i:%02i ",
257 | data.current_dt.hour,
258 | data.current_dt.minute,
259 | data.current_dt.second);
260 | lcd_move_cursor(&lcd, 1, 0);
261 | lcd_write_string(&lcd, s, strlen(s));
262 |
263 | // Draw the "G" icon.
264 | lcd_move_cursor(&lcd, 1, 14);
265 | lcd_write_char(&lcd, CG_GPS_ICON);
266 |
267 | // Draw the previously defined signal strength icon.
268 | lcd_move_cursor(&lcd, 1, 15);
269 | lcd_write_char(&lcd, CG_GPS_SIGNAL);
270 |
271 | // Between 9pm and 6am, dim the display, otherwise maximum brightness.
272 | if(data.current_dt.hour >= 6 && data.current_dt.hour < 21)
273 | LCD_BKL_OCR = 255;
274 | else
275 | LCD_BKL_OCR = 64;
276 |
277 | } else if(data_age == MAX_DATA_AGE_CS) {
278 | // The last data we've received is too old to display. It's better to
279 | // display an error than an incorrect time.
280 | LCD_BKL_OCR = 255;
281 | lcd_clear(&lcd);
282 | lcd_move_cursor(&lcd, 0, 0);
283 | lcd_write_string(&lcd, "Waiting for", 11);
284 | lcd_move_cursor(&lcd, 1, 5);
285 | lcd_write_string(&lcd, "valid data!", 11);
286 | }
287 |
288 | if(data_age <= MAX_DATA_AGE_CS) {
289 | data_age++;
290 | }
291 |
292 | _delay_ms(10);
293 | }
294 |
295 | return(0);
296 | }
297 |
--------------------------------------------------------------------------------
/lcd_test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | lcd_test
4 |
5 |
6 | lcd
7 | uart
8 |
9 |
10 |
11 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
12 | clean,full,incremental,
13 |
14 |
15 | ?name?
16 |
17 |
18 |
19 | org.eclipse.cdt.make.core.append_environment
20 | true
21 |
22 |
23 | org.eclipse.cdt.make.core.autoBuildTarget
24 | all
25 |
26 |
27 | org.eclipse.cdt.make.core.buildArguments
28 |
29 |
30 |
31 | org.eclipse.cdt.make.core.buildCommand
32 | make
33 |
34 |
35 | org.eclipse.cdt.make.core.buildLocation
36 | ${workspace_loc:/lcd_test/Release}
37 |
38 |
39 | org.eclipse.cdt.make.core.cleanBuildTarget
40 | clean
41 |
42 |
43 | org.eclipse.cdt.make.core.contents
44 | org.eclipse.cdt.make.core.activeConfigSettings
45 |
46 |
47 | org.eclipse.cdt.make.core.enableAutoBuild
48 | false
49 |
50 |
51 | org.eclipse.cdt.make.core.enableCleanBuild
52 | true
53 |
54 |
55 | org.eclipse.cdt.make.core.enableFullBuild
56 | true
57 |
58 |
59 | org.eclipse.cdt.make.core.fullBuildTarget
60 | all
61 |
62 |
63 | org.eclipse.cdt.make.core.stopOnError
64 | true
65 |
66 |
67 | org.eclipse.cdt.make.core.useDefaultBuildCmd
68 | true
69 |
70 |
71 |
72 |
73 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
74 |
75 |
76 |
77 |
78 |
79 | org.eclipse.cdt.core.cnature
80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
82 | de.innot.avreclipse.core.avrnature
83 |
84 |
85 |
--------------------------------------------------------------------------------
/lcd_test/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | #Sun Oct 24 16:34:58 PDT 2010
2 | avrtarget/ClockFrequency=8000000
3 | avrtarget/ExtRAMSize=0
4 | avrtarget/ExtendedRAM=false
5 | avrtarget/MCUType=atmega644
6 | avrtarget/UseEEPROM=false
7 | avrtarget/UseExtendedRAMforHeap=true
8 | avrtarget/avrdude/BitBangDelay=
9 | avrtarget/avrdude/Bitclock=10
10 | avrtarget/avrdude/EEPROMFile=
11 | avrtarget/avrdude/EEPROMFromConfig=true
12 | avrtarget/avrdude/FlashFile=
13 | avrtarget/avrdude/FlashFromConfig=true
14 | avrtarget/avrdude/Fuses/ByteValues=194\:217\:255
15 | avrtarget/avrdude/Fuses/FileName=
16 | avrtarget/avrdude/Fuses/MCUid=atmega644
17 | avrtarget/avrdude/Fuses/UseFile=false
18 | avrtarget/avrdude/Fuses/Write=true
19 | avrtarget/avrdude/NoChipErase=false
20 | avrtarget/avrdude/NoSigCheck=false
21 | avrtarget/avrdude/NoVerify=false
22 | avrtarget/avrdude/NoWrite=false
23 | avrtarget/avrdude/OtherOptions=
24 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
25 | avrtarget/avrdude/UseCounter=false
26 | avrtarget/avrdude/WriteEEPROM=false
27 | avrtarget/avrdude/WriteFlash=true
28 | avrtarget/perConfig=false
29 | eclipse.preferences.version=1
30 |
--------------------------------------------------------------------------------
/lcd_test/lcd_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | #define LCD_CON_OCR OCR0A
33 | #define LCD_BKL_OCR OCR0B
34 |
35 | lcd_t lcd = {
36 | .interface = LCD_INTERFACE_8BIT,
37 | .data = {&PINA, &PORTA, &DDRA, PA0},
38 | .rs = {&PINB, &PORTB, &DDRB, PB1},
39 | .rw = {&PINB, &PORTB, &DDRB, PB2},
40 | .e = {&PINB, &PORTB, &DDRB, PB0}
41 | };
42 |
43 | int main(void)
44 | {
45 | uart_t *u0;
46 | char s[32];
47 | uint16_t x = 0;
48 |
49 | _delay_ms(1000);
50 |
51 | u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU));
52 | uart_init_stdout(u0);
53 |
54 | DDRB |= _BV(PB3) | _BV(PB4);
55 |
56 | /*
57 | COM0A1 = Clear OC0A on compare match
58 | COM0B1 = Clear OC0B on compare match
59 | WGM01|WGM00 = Fast PWM
60 | */
61 | TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
62 | /* CS01 = Prescale by /8 */
63 | TCCR0B = _BV(CS01);
64 |
65 | LCD_CON_OCR = 90;
66 | LCD_BKL_OCR = 255;
67 |
68 | sei();
69 |
70 | printf("\n\nBooted up!\n");
71 |
72 | lcd_init(&lcd);
73 |
74 | while(1)
75 | {
76 | if(0 == (x%26))
77 | lcd_clear(&lcd);
78 |
79 | sprintf(s, "%-11s%5i", "Test String", x);
80 | lcd_move_cursor(&lcd, 0, 0);
81 | lcd_write_string(&lcd, s, strlen(s));
82 |
83 | lcd_move_cursor(&lcd, 1, x%16);
84 | lcd_write_char(&lcd, x%26+'a');
85 |
86 | _delay_ms(200);
87 | x++;
88 | }
89 |
90 | return(0);
91 | }
92 |
--------------------------------------------------------------------------------
/led_analog_clock/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | led_analog_clock
4 |
5 |
6 | i2c
7 | led_charlieplex
8 | led_sequencer
9 | rtc
10 | uart
11 |
12 |
13 |
14 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
15 | clean,full,incremental,
16 |
17 |
18 | ?name?
19 |
20 |
21 |
22 | org.eclipse.cdt.make.core.append_environment
23 | true
24 |
25 |
26 | org.eclipse.cdt.make.core.autoBuildTarget
27 | all
28 |
29 |
30 | org.eclipse.cdt.make.core.buildArguments
31 |
32 |
33 |
34 | org.eclipse.cdt.make.core.buildCommand
35 | make
36 |
37 |
38 | org.eclipse.cdt.make.core.buildLocation
39 | ${workspace_loc:/led_analog_clock_v1/Release}
40 |
41 |
42 | org.eclipse.cdt.make.core.cleanBuildTarget
43 | clean
44 |
45 |
46 | org.eclipse.cdt.make.core.contents
47 | org.eclipse.cdt.make.core.activeConfigSettings
48 |
49 |
50 | org.eclipse.cdt.make.core.enableAutoBuild
51 | false
52 |
53 |
54 | org.eclipse.cdt.make.core.enableCleanBuild
55 | true
56 |
57 |
58 | org.eclipse.cdt.make.core.enableFullBuild
59 | true
60 |
61 |
62 | org.eclipse.cdt.make.core.fullBuildTarget
63 | all
64 |
65 |
66 | org.eclipse.cdt.make.core.stopOnError
67 | true
68 |
69 |
70 | org.eclipse.cdt.make.core.useDefaultBuildCmd
71 | true
72 |
73 |
74 |
75 |
76 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
77 |
78 |
79 |
80 |
81 |
82 | org.eclipse.cdt.core.cnature
83 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
84 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
85 | de.innot.avreclipse.core.avrnature
86 |
87 |
88 |
--------------------------------------------------------------------------------
/led_analog_clock/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/Fuses/ByteValues=194\:209\:252
14 | avrtarget/avrdude/Fuses/FileName=
15 | avrtarget/avrdude/Fuses/MCUid=atmega644
16 | avrtarget/avrdude/Fuses/UseFile=false
17 | avrtarget/avrdude/Fuses/Write=true
18 | avrtarget/avrdude/NoChipErase=false
19 | avrtarget/avrdude/NoSigCheck=false
20 | avrtarget/avrdude/NoVerify=false
21 | avrtarget/avrdude/NoWrite=false
22 | avrtarget/avrdude/OtherOptions=
23 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
24 | avrtarget/avrdude/UseCounter=false
25 | avrtarget/avrdude/WriteEEPROM=false
26 | avrtarget/avrdude/WriteFlash=true
27 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/ClockFrequency=8000000
28 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/ExtRAMSize=0
29 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/ExtendedRAM=false
30 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/MCUType=atmega644
31 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/UseEEPROM=false
32 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/UseExtendedRAMforHeap=true
33 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/BitBangDelay=
34 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/Bitclock=
35 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/EEPROMFile=
36 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/EEPROMFromConfig=true
37 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/FlashFile=
38 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/FlashFromConfig=true
39 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/NoChipErase=false
40 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/NoSigCheck=false
41 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/NoVerify=false
42 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/NoWrite=false
43 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/OtherOptions=
44 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/ProgrammerID=programmerconfig.1
45 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/UseCounter=false
46 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/WriteEEPROM=false
47 | avrtarget/de.innot.avreclipse.configuration.app.release.2119175456.1762794471/avrdude/WriteFlash=true
48 | avrtarget/perConfig=true
49 | eclipse.preferences.version=1
50 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_clock_v1.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 |
23 | #include
24 |
25 | #include "led_analog_clock_v1.h"
26 |
27 | led_charlieplex_port_t led_analog_clock_v1_ports[] = {
28 | /* 0 */ { &PINA, &DDRA, &PORTA, 0xff },
29 | /* 1 */ { &PINC, &DDRC, &PORTC, 0xff },
30 | { NULL, NULL, NULL, 0 },
31 | };
32 |
33 | led_charlieplex_led_t led_analog_clock_v1_leds[] = {
34 | { "AA1", 0, 0, 1, 0 },
35 | { "AB1", 0, 0, 1, 1 },
36 | { "AC1", 0, 0, 1, 2 },
37 | { "AD1", 0, 0, 1, 3 },
38 | { "AE1", 0, 0, 1, 4 },
39 | { "AF1", 0, 0, 1, 5 },
40 | { "AG1", 0, 0, 1, 6 },
41 | { "AH1", 0, 0, 1, 7 },
42 |
43 | { "AA2", 1, 0, 0, 0 },
44 | { "AB2", 1, 1, 0, 0 },
45 | { "AC2", 1, 2, 0, 0 },
46 | { "AD2", 1, 3, 0, 0 },
47 | { "AE2", 1, 4, 0, 0 },
48 | { "AF2", 1, 5, 0, 0 },
49 | { "AG2", 1, 6, 0, 0 },
50 | { "AH2", 1, 7, 0, 0 },
51 |
52 | { "BA1", 0, 1, 1, 0 },
53 | { "BB1", 0, 1, 1, 1 },
54 | { "BC1", 0, 1, 1, 2 },
55 | { "BD1", 0, 1, 1, 3 },
56 | { "BE1", 0, 1, 1, 4 },
57 | { "BF1", 0, 1, 1, 5 },
58 | { "BG1", 0, 1, 1, 6 },
59 | { "BH1", 0, 1, 1, 7 },
60 |
61 | { "BA2", 1, 0, 0, 1 },
62 | { "BB2", 1, 1, 0, 1 },
63 | { "BC2", 1, 2, 0, 1 },
64 | { "BD2", 1, 3, 0, 1 },
65 | { "BE2", 1, 4, 0, 1 },
66 | { "BF2", 1, 5, 0, 1 },
67 | { "BG2", 1, 6, 0, 1 },
68 | { "BH2", 1, 7, 0, 1 },
69 |
70 | { "CA1", 0, 2, 1, 0 },
71 | { "CB1", 0, 2, 1, 1 },
72 | { "CC1", 0, 2, 1, 2 },
73 | { "CD1", 0, 2, 1, 3 },
74 | { "CE1", 0, 2, 1, 4 },
75 | { "CF1", 0, 2, 1, 5 },
76 | { "CG1", 0, 2, 1, 6 },
77 | { "CH1", 0, 2, 1, 7 },
78 |
79 | { "CA2", 1, 0, 0, 2 },
80 | { "CB2", 1, 1, 0, 2 },
81 | { "CC2", 1, 2, 0, 2 },
82 | { "CD2", 1, 3, 0, 2 },
83 | { "CE2", 1, 4, 0, 2 },
84 | { "CF2", 1, 5, 0, 2 },
85 | { "CG2", 1, 6, 0, 2 },
86 | { "CH2", 1, 7, 0, 2 },
87 |
88 | { "DA1", 0, 3, 1, 0 },
89 | { "DB1", 0, 3, 1, 1 },
90 | { "DC1", 0, 3, 1, 2 },
91 | { "DD1", 0, 3, 1, 3 },
92 | { "DE1", 0, 3, 1, 4 },
93 | { "DF1", 0, 3, 1, 5 },
94 | { "DG1", 0, 3, 1, 6 },
95 | { "DH1", 0, 3, 1, 7 },
96 |
97 | { "DA2", 1, 0, 0, 3 },
98 | { "DB2", 1, 1, 0, 3 },
99 | { "DC2", 1, 2, 0, 3 },
100 | { "DD2", 1, 3, 0, 3 },
101 | { "DE2", 1, 4, 0, 3 },
102 | { "DF2", 1, 5, 0, 3 },
103 | { "DG2", 1, 6, 0, 3 },
104 | { "DH2", 1, 7, 0, 3 },
105 |
106 | { "EA1", 0, 4, 1, 0 },
107 | { "EB1", 0, 4, 1, 1 },
108 | { "EC1", 0, 4, 1, 2 },
109 | { "ED1", 0, 4, 1, 3 },
110 | { "EE1", 0, 4, 1, 4 },
111 | { "EF1", 0, 4, 1, 5 },
112 | { "EG1", 0, 4, 1, 6 },
113 | { "EH1", 0, 4, 1, 7 },
114 |
115 | { "EA2", 1, 0, 0, 4 },
116 | { "EB2", 1, 1, 0, 4 },
117 | { "EC2", 1, 2, 0, 4 },
118 | { "ED2", 1, 3, 0, 4 },
119 | { "EE2", 1, 4, 0, 4 },
120 | { "EF2", 1, 5, 0, 4 },
121 | { "EG2", 1, 6, 0, 4 },
122 | { "EH2", 1, 7, 0, 4 },
123 |
124 | { "FA1", 0, 5, 1, 0 },
125 | { "FB1", 0, 5, 1, 1 },
126 | { "FC1", 0, 5, 1, 2 },
127 | { "FD1", 0, 5, 1, 3 },
128 | { "FE1", 0, 5, 1, 4 },
129 | { "FF1", 0, 5, 1, 5 },
130 | { "FG1", 0, 5, 1, 6 },
131 | { "FH1", 0, 5, 1, 7 },
132 |
133 | { "FA2", 1, 0, 0, 5 },
134 | { "FB2", 1, 1, 0, 5 },
135 | { "FC2", 1, 2, 0, 5 },
136 | { "FD2", 1, 3, 0, 5 },
137 | { "FE2", 1, 4, 0, 5 },
138 | { "FF2", 1, 5, 0, 5 },
139 | { "FG2", 1, 6, 0, 5 },
140 | { "FH2", 1, 7, 0, 5 },
141 |
142 | { "GA1", 0, 6, 1, 0 },
143 | { "GB1", 0, 6, 1, 1 },
144 | { "GC1", 0, 6, 1, 2 },
145 | { "GD1", 0, 6, 1, 3 },
146 | { "GE1", 0, 6, 1, 4 },
147 | { "GF1", 0, 6, 1, 5 },
148 | { "GG1", 0, 6, 1, 6 },
149 | { "GH1", 0, 6, 1, 7 },
150 |
151 | { "GA2", 1, 0, 0, 6 },
152 | { "GB2", 1, 1, 0, 6 },
153 | { "GC2", 1, 2, 0, 6 },
154 | { "GD2", 1, 3, 0, 6 },
155 | { "GE2", 1, 4, 0, 6 },
156 | { "GF2", 1, 5, 0, 6 },
157 | { "GG2", 1, 6, 0, 6 },
158 | { "GH2", 1, 7, 0, 6 },
159 |
160 | { "HA1", 0, 7, 1, 0 },
161 | { "HB1", 0, 7, 1, 1 },
162 | { "HC1", 0, 7, 1, 2 },
163 | { "HD1", 0, 7, 1, 3 },
164 | { "HE1", 0, 7, 1, 4 },
165 | { "HF1", 0, 7, 1, 5 },
166 | { "HG1", 0, 7, 1, 6 },
167 | { "HH1", 0, 7, 1, 7 },
168 |
169 | { "HA2", 1, 0, 0, 7 },
170 | { "HB2", 1, 1, 0, 7 },
171 | { "HC2", 1, 2, 0, 7 },
172 | { "HD2", 1, 3, 0, 7 },
173 | { "HE2", 1, 4, 0, 7 },
174 | { "HF2", 1, 5, 0, 7 },
175 | { "HG2", 1, 6, 0, 7 },
176 | { "HH2", 1, 7, 0, 7 },
177 |
178 | { NULL, 0, 0, 0, 0 }
179 | };
180 |
181 | led_charlieplex_t led_analog_clock_v1 = {
182 | 0,
183 | led_analog_clock_v1_ports,
184 | led_analog_clock_v1_leds
185 | };
186 |
187 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_clock_v1.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef LED_ANALOG_CLOCK_V1_H
21 | #define LED_ANALOG_CLOCK_V1_H
22 |
23 | #include
24 |
25 | led_charlieplex_t led_analog_clock_v1;
26 |
27 | #endif /* LED_ANALOG_CLOCK_V1_H */
28 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_clock_v2.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 |
23 | #include
24 |
25 | #include "led_analog_clock_v2.h"
26 |
27 | led_charlieplex_port_t led_analog_clock_v2_ports[] = {
28 | /* 0 */ { &PINA, &DDRA, &PORTA, 0xff },
29 | /* 1 */ { &PINB, &DDRB, &PORTB, (_BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3)) },
30 | /* 2 */ { &PIND, &DDRD, &PORTD, (_BV(PD4) | _BV(PD5) | _BV(PD6) | _BV(PD7)) },
31 | { NULL, NULL, NULL, 0 },
32 | };
33 |
34 | led_charlieplex_led_t led_analog_clock_v2_leds[] = {
35 | { "AA1", 0, 0, 2, 4 },
36 | { "AB1", 0, 0, 2, 5 },
37 | { "AC1", 0, 0, 2, 6 },
38 | { "AD1", 0, 0, 2, 7 },
39 | { "AE1", 0, 0, 1, 0 },
40 | { "AF1", 0, 0, 1, 1 },
41 | { "AG1", 0, 0, 1, 2 },
42 | { "AH1", 0, 0, 1, 3 },
43 |
44 | { "AA2", 2, 4, 0, 0 },
45 | { "AB2", 2, 5, 0, 0 },
46 | { "AC2", 2, 6, 0, 0 },
47 | { "AD2", 2, 7, 0, 0 },
48 | { "AE2", 1, 0, 0, 0 },
49 | { "AF2", 1, 1, 0, 0 },
50 | { "AG2", 1, 2, 0, 0 },
51 | { "AH2", 1, 3, 0, 0 },
52 |
53 | { "BA1", 0, 1, 2, 4 },
54 | { "BB1", 0, 1, 2, 5 },
55 | { "BC1", 0, 1, 2, 6 },
56 | { "BD1", 0, 1, 2, 7 },
57 | { "BE1", 0, 1, 1, 0 },
58 | { "BF1", 0, 1, 1, 1 },
59 | { "BG1", 0, 1, 1, 2 },
60 | { "BH1", 0, 1, 1, 3 },
61 |
62 | { "BA2", 2, 4, 0, 1 },
63 | { "BB2", 2, 5, 0, 1 },
64 | { "BC2", 2, 6, 0, 1 },
65 | { "BD2", 2, 7, 0, 1 },
66 | { "BE2", 1, 0, 0, 1 },
67 | { "BF2", 1, 1, 0, 1 },
68 | { "BG2", 1, 2, 0, 1 },
69 | { "BH2", 1, 3, 0, 1 },
70 |
71 | { "CA1", 0, 2, 2, 4 },
72 | { "CB1", 0, 2, 2, 5 },
73 | { "CC1", 0, 2, 2, 6 },
74 | { "CD1", 0, 2, 2, 7 },
75 | { "CE1", 0, 2, 1, 0 },
76 | { "CF1", 0, 2, 1, 1 },
77 | { "CG1", 0, 2, 1, 2 },
78 | { "CH1", 0, 2, 1, 3 },
79 |
80 | { "CA2", 2, 4, 0, 2 },
81 | { "CB2", 2, 5, 0, 2 },
82 | { "CC2", 2, 6, 0, 2 },
83 | { "CD2", 2, 7, 0, 2 },
84 | { "CE2", 1, 0, 0, 2 },
85 | { "CF2", 1, 1, 0, 2 },
86 | { "CG2", 1, 2, 0, 2 },
87 | { "CH2", 1, 3, 0, 2 },
88 |
89 | { "DA1", 0, 3, 2, 4 },
90 | { "DB1", 0, 3, 2, 5 },
91 | { "DC1", 0, 3, 2, 6 },
92 | { "DD1", 0, 3, 2, 7 },
93 | { "DE1", 0, 3, 1, 0 },
94 | { "DF1", 0, 3, 1, 1 },
95 | { "DG1", 0, 3, 1, 2 },
96 | { "DH1", 0, 3, 1, 3 },
97 |
98 | { "DA2", 2, 4, 0, 3 },
99 | { "DB2", 2, 5, 0, 3 },
100 | { "DC2", 2, 6, 0, 3 },
101 | { "DD2", 2, 7, 0, 3 },
102 | { "DE2", 1, 0, 0, 3 },
103 | { "DF2", 1, 1, 0, 3 },
104 | { "DG2", 1, 2, 0, 3 },
105 | { "DH2", 1, 3, 0, 3 },
106 |
107 | { "EA1", 0, 4, 2, 4 },
108 | { "EB1", 0, 4, 2, 5 },
109 | { "EC1", 0, 4, 2, 6 },
110 | { "ED1", 0, 4, 2, 7 },
111 | { "EE1", 0, 4, 1, 0 },
112 | { "EF1", 0, 4, 1, 1 },
113 | { "EG1", 0, 4, 1, 2 },
114 | { "EH1", 0, 4, 1, 3 },
115 |
116 | { "EA2", 2, 4, 0, 4 },
117 | { "EB2", 2, 5, 0, 4 },
118 | { "EC2", 2, 6, 0, 4 },
119 | { "ED2", 2, 7, 0, 4 },
120 | { "EE2", 1, 0, 0, 4 },
121 | { "EF2", 1, 1, 0, 4 },
122 | { "EG2", 1, 2, 0, 4 },
123 | { "EH2", 1, 3, 0, 4 },
124 |
125 | { "FA1", 0, 5, 2, 4 },
126 | { "FB1", 0, 5, 2, 5 },
127 | { "FC1", 0, 5, 2, 6 },
128 | { "FD1", 0, 5, 2, 7 },
129 | { "FE1", 0, 5, 1, 0 },
130 | { "FF1", 0, 5, 1, 1 },
131 | { "FG1", 0, 5, 1, 2 },
132 | { "FH1", 0, 5, 1, 3 },
133 |
134 | { "FA2", 2, 4, 0, 5 },
135 | { "FB2", 2, 5, 0, 5 },
136 | { "FC2", 2, 6, 0, 5 },
137 | { "FD2", 2, 7, 0, 5 },
138 | { "FE2", 1, 0, 0, 5 },
139 | { "FF2", 1, 1, 0, 5 },
140 | { "FG2", 1, 2, 0, 5 },
141 | { "FH2", 1, 3, 0, 5 },
142 |
143 | { "GA1", 0, 6, 2, 4 },
144 | { "GB1", 0, 6, 2, 5 },
145 | { "GC1", 0, 6, 2, 6 },
146 | { "GD1", 0, 6, 2, 7 },
147 | { "GE1", 0, 6, 1, 0 },
148 | { "GF1", 0, 6, 1, 1 },
149 | { "GG1", 0, 6, 1, 2 },
150 | { "GH1", 0, 6, 1, 3 },
151 |
152 | { "GA2", 2, 4, 0, 6 },
153 | { "GB2", 2, 5, 0, 6 },
154 | { "GC2", 2, 6, 0, 6 },
155 | { "GD2", 2, 7, 0, 6 },
156 | { "GE2", 1, 0, 0, 6 },
157 | { "GF2", 1, 1, 0, 6 },
158 | { "GG2", 1, 2, 0, 6 },
159 | { "GH2", 1, 3, 0, 6 },
160 |
161 | { "HA1", 0, 7, 2, 4 },
162 | { "HB1", 0, 7, 2, 5 },
163 | { "HC1", 0, 7, 2, 6 },
164 | { "HD1", 0, 7, 2, 7 },
165 | { "HE1", 0, 7, 1, 0 },
166 | { "HF1", 0, 7, 1, 1 },
167 | { "HG1", 0, 7, 1, 2 },
168 | { "HH1", 0, 7, 1, 3 },
169 |
170 | { "HA2", 2, 4, 0, 7 },
171 | { "HB2", 2, 5, 0, 7 },
172 | { "HC2", 2, 6, 0, 7 },
173 | { "HD2", 2, 7, 0, 7 },
174 | { "HE2", 1, 0, 0, 7 },
175 | { "HF2", 1, 1, 0, 7 },
176 | { "HG2", 1, 2, 0, 7 },
177 | { "HH2", 1, 3, 0, 7 },
178 |
179 | { NULL, 0, 0, 0, 0 }
180 | };
181 |
182 | led_charlieplex_t led_analog_clock_v2 = {
183 | 0,
184 | led_analog_clock_v2_ports,
185 | led_analog_clock_v2_leds
186 | };
187 |
188 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_clock_v2.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef LED_ANALOG_CLOCK_V2_H
21 | #define LED_ANALOG_CLOCK_V2_H
22 |
23 | #include
24 |
25 | led_charlieplex_t led_analog_clock_v2;
26 |
27 | #endif /* LED_ANALOG_CLOCK_V2_H */
28 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_watch_v1.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 |
23 | #include
24 |
25 | #include "led_analog_watch_v1.h"
26 |
27 | led_charlieplex_port_t led_analog_watch_v1_ports[] = {
28 | /* 0 */ { &PINA, &DDRA, &PORTA, 0xff },
29 | /* 1 */ { &PINB, &DDRB, &PORTB, (_BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3)) },
30 | /* 2 */ { &PIND, &DDRD, &PORTD, (_BV(PD4) | _BV(PD5) | _BV(PD6) | _BV(PD7)) },
31 | { NULL, NULL, NULL, 0 },
32 | };
33 |
34 | led_charlieplex_led_t led_analog_watch_v1_leds[] = {
35 | { "AA1", 0, 0, 2, 4 },
36 | { "AB1", 0, 0, 2, 5 },
37 | { "AC1", 0, 0, 2, 6 },
38 | { "AD1", 0, 0, 2, 7 },
39 | { "AE1", 0, 0, 1, 0 },
40 | { "AF1", 0, 0, 1, 1 },
41 | { "AG1", 0, 0, 1, 2 },
42 | { "AH1", 0, 0, 1, 3 },
43 |
44 | { "AA2", 2, 4, 0, 0 },
45 | { "AB2", 2, 5, 0, 0 },
46 | { "AC2", 2, 6, 0, 0 },
47 | { "AD2", 2, 7, 0, 0 },
48 | { "AE2", 1, 0, 0, 0 },
49 | { "AF2", 1, 1, 0, 0 },
50 | { "AG2", 1, 2, 0, 0 },
51 | { "AH2", 1, 3, 0, 0 },
52 |
53 | { "BA1", 0, 1, 2, 4 },
54 | { "BB1", 0, 1, 2, 5 },
55 | { "BC1", 0, 1, 2, 6 },
56 | { "BD1", 0, 1, 2, 7 },
57 | { "BE1", 0, 1, 1, 0 },
58 | { "BF1", 0, 1, 1, 1 },
59 | { "BG1", 0, 1, 1, 2 },
60 | { "BH1", 0, 1, 1, 3 },
61 |
62 | { "BA2", 2, 4, 0, 1 },
63 | { "BB2", 2, 5, 0, 1 },
64 | { "BC2", 2, 6, 0, 1 },
65 | { "BD2", 2, 7, 0, 1 },
66 | { "BE2", 1, 0, 0, 1 },
67 | { "BF2", 1, 1, 0, 1 },
68 | { "BG2", 1, 2, 0, 1 },
69 | { "BH2", 1, 3, 0, 1 },
70 |
71 | { "CA1", 0, 2, 2, 4 },
72 | { "CB1", 0, 2, 2, 5 },
73 | { "CC1", 0, 2, 2, 6 },
74 | { "CD1", 0, 2, 2, 7 },
75 | { "CE1", 0, 2, 1, 0 },
76 | { "CF1", 0, 2, 1, 1 },
77 | { "CG1", 0, 2, 1, 2 },
78 | { "CH1", 0, 2, 1, 3 },
79 |
80 | { "CA2", 2, 4, 0, 2 },
81 | { "CB2", 2, 5, 0, 2 },
82 | { "CC2", 2, 6, 0, 2 },
83 | { "CD2", 2, 7, 0, 2 },
84 | { "CE2", 1, 0, 0, 2 },
85 | { "CF2", 1, 1, 0, 2 },
86 | { "CG2", 1, 2, 0, 2 },
87 | { "CH2", 1, 3, 0, 2 },
88 |
89 | { "DA1", 0, 3, 2, 4 },
90 | { "DB1", 0, 3, 2, 5 },
91 | { "DC1", 0, 3, 2, 6 },
92 | { "DD1", 0, 3, 2, 7 },
93 | { "DE1", 0, 3, 1, 0 },
94 | { "DF1", 0, 3, 1, 1 },
95 | { "DG1", 0, 3, 1, 2 },
96 | { "DH1", 0, 3, 1, 3 },
97 |
98 | { "DA2", 2, 4, 0, 3 },
99 | { "DB2", 2, 5, 0, 3 },
100 | { "DC2", 2, 6, 0, 3 },
101 | { "DD2", 2, 7, 0, 3 },
102 | { "DE2", 1, 0, 0, 3 },
103 | { "DF2", 1, 1, 0, 3 },
104 | { "DG2", 1, 2, 0, 3 },
105 | { "DH2", 1, 3, 0, 3 },
106 |
107 | { "EA1", 0, 4, 2, 4 },
108 | { "EB1", 0, 4, 2, 5 },
109 | { "EC1", 0, 4, 2, 6 },
110 | { "ED1", 0, 4, 2, 7 },
111 | { "EE1", 0, 4, 1, 0 },
112 | { "EF1", 0, 4, 1, 1 },
113 | { "EG1", 0, 4, 1, 2 },
114 | { "EH1", 0, 4, 1, 3 },
115 |
116 | { "EA2", 2, 4, 0, 4 },
117 | { "EB2", 2, 5, 0, 4 },
118 | { "EC2", 2, 6, 0, 4 },
119 | { "ED2", 2, 7, 0, 4 },
120 | { "EE2", 1, 0, 0, 4 },
121 | { "EF2", 1, 1, 0, 4 },
122 | { "EG2", 1, 2, 0, 4 },
123 | { "EH2", 1, 3, 0, 4 },
124 |
125 | { "FA1", 0, 5, 2, 4 },
126 | { "FB1", 0, 5, 2, 5 },
127 | { "FC1", 0, 5, 2, 6 },
128 | { "FD1", 0, 5, 2, 7 },
129 | { "FE1", 0, 5, 1, 0 },
130 | { "FF1", 0, 5, 1, 1 },
131 | { "FG1", 0, 5, 1, 2 },
132 | { "FH1", 0, 5, 1, 3 },
133 |
134 | { "FA2", 2, 4, 0, 5 },
135 | { "FB2", 2, 5, 0, 5 },
136 | { "FC2", 2, 6, 0, 5 },
137 | { "FD2", 2, 7, 0, 5 },
138 | { "FE2", 1, 0, 0, 5 },
139 | { "FF2", 1, 1, 0, 5 },
140 | { "FG2", 1, 2, 0, 5 },
141 | { "FH2", 1, 3, 0, 5 },
142 |
143 | { "GA1", 0, 6, 2, 4 },
144 | { "GB1", 0, 6, 2, 5 },
145 | { "GC1", 0, 6, 2, 6 },
146 | { "GD1", 0, 6, 2, 7 },
147 | { "GE1", 0, 6, 1, 0 },
148 | { "GF1", 0, 6, 1, 1 },
149 | { "GG1", 0, 6, 1, 2 },
150 | { "GH1", 0, 6, 1, 3 },
151 |
152 | { "GA2", 2, 4, 0, 6 },
153 | { "GB2", 2, 5, 0, 6 },
154 | { "GC2", 2, 6, 0, 6 },
155 | { "GD2", 2, 7, 0, 6 },
156 | { "GE2", 1, 0, 0, 6 },
157 | { "GF2", 1, 1, 0, 6 },
158 | { "GG2", 1, 2, 0, 6 },
159 | { "GH2", 1, 3, 0, 6 },
160 |
161 | { "HA1", 0, 7, 2, 4 },
162 | { "HB1", 0, 7, 2, 5 },
163 | { "HC1", 0, 7, 2, 6 },
164 | { "HD1", 0, 7, 2, 7 },
165 | { "HE1", 0, 7, 1, 0 },
166 | { "HF1", 0, 7, 1, 1 },
167 | { "HG1", 0, 7, 1, 2 },
168 | { "HH1", 0, 7, 1, 3 },
169 |
170 | { "HA2", 2, 4, 0, 7 },
171 | { "HB2", 2, 5, 0, 7 },
172 | { "HC2", 2, 6, 0, 7 },
173 | { "HD2", 2, 7, 0, 7 },
174 | { "HE2", 1, 0, 0, 7 },
175 | { "HF2", 1, 1, 0, 7 },
176 | { "HG2", 1, 2, 0, 7 },
177 | { "HH2", 1, 3, 0, 7 },
178 |
179 | { NULL, 0, 0, 0, 0 }
180 | };
181 |
182 | led_charlieplex_t led_analog_watch_v1 = {
183 | 0,
184 | led_analog_watch_v1_ports,
185 | led_analog_watch_v1_leds
186 | };
187 |
188 |
--------------------------------------------------------------------------------
/led_analog_clock/led_analog_watch_v1.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef LED_ANALOG_WATCH_V1_H
21 | #define LED_ANALOG_WATCH_V1_H
22 |
23 | #include
24 |
25 | led_charlieplex_t led_analog_watch_v1;
26 |
27 | #endif /* LED_ANALOG_WATCH_V1_H */
28 |
--------------------------------------------------------------------------------
/led_analog_clock/led_mapping.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | /**
21 | * @file
22 | *
23 | * Mapping tables of all LEDs into logical positions.
24 | */
25 |
26 | /**
27 | * Map of 60 LEDs in outer ring for minutes
28 | * A{A:H}1, B{A:G}1, C{A:H}1, D{A:G}1, E{A:H}1, F{A:G}1, G{A:H}1, H{A:G}1
29 | */
30 | char *led_mapping_minute[60] = {
31 | "AA1", /* 00 */
32 | "AB1", /* 01 */
33 | "AC1", /* 02 */
34 | "AD1", /* 03 */
35 | "AE1", /* 04 */
36 | "AF1", /* 05 */
37 | "AG1", /* 06 */
38 | "AH1", /* 07 */
39 | "BA1", /* 08 */
40 | "BB1", /* 09 */
41 | "BC1", /* 10 */
42 | "BD1", /* 11 */
43 | "BE1", /* 12 */
44 | "BF1", /* 13 */
45 | "BG1", /* 14 */
46 |
47 | "CA1", /* 15 */
48 | "CB1", /* 16 */
49 | "CC1", /* 17 */
50 | "CD1", /* 18 */
51 | "CE1", /* 19 */
52 | "CF1", /* 20 */
53 | "CG1", /* 21 */
54 | "CH1", /* 22 */
55 | "DA1", /* 23 */
56 | "DB1", /* 24 */
57 | "DC1", /* 25 */
58 | "DD1", /* 26 */
59 | "DE1", /* 27 */
60 | "DF1", /* 28 */
61 | "DG1", /* 29 */
62 |
63 | "EA1", /* 30 */
64 | "EB1", /* 31 */
65 | "EC1", /* 32 */
66 | "ED1", /* 33 */
67 | "EE1", /* 34 */
68 | "EF1", /* 35 */
69 | "EG1", /* 36 */
70 | "EH1", /* 37 */
71 | "FA1", /* 38 */
72 | "FB1", /* 39 */
73 | "FC1", /* 40 */
74 | "FD1", /* 41 */
75 | "FE1", /* 42 */
76 | "FF1", /* 43 */
77 | "FG1", /* 44 */
78 |
79 | "GA1", /* 45 */
80 | "GB1", /* 46 */
81 | "GC1", /* 47 */
82 | "GD1", /* 48 */
83 | "GE1", /* 49 */
84 | "GF1", /* 50 */
85 | "GG1", /* 51 */
86 | "GH1", /* 52 */
87 | "HA1", /* 53 */
88 | "HB1", /* 54 */
89 | "HC1", /* 55 */
90 | "HD1", /* 56 */
91 | "HE1", /* 57 */
92 | "HF1", /* 58 */
93 | "HG1", /* 59 */
94 | };
95 |
96 | /**
97 | * Map of 48 LEDs in inner ring for quarter hours
98 | * A{A:H}2, B{A:D}2, C{A:H}2, D{A:D}2, E{A:H}2, F{A:D}2, G{A:H}2, H{A:D}2
99 | */
100 | char *led_mapping_qhour[48] = {
101 | "AA2", /* 00 */
102 | "AB2", /* 01 */
103 | "AC2", /* 02 */
104 | "AD2", /* 03 */
105 |
106 | "AE2", /* 04 */
107 | "AF2", /* 05 */
108 | "AG2", /* 06 */
109 | "AH2", /* 07 */
110 |
111 | "BA2", /* 08 */
112 | "BB2", /* 09 */
113 | "BC2", /* 10 */
114 | "BD2", /* 11 */
115 |
116 | "CA2", /* 12 */
117 | "CB2", /* 13 */
118 | "CC2", /* 14 */
119 | "CD2", /* 15 */
120 |
121 | "CE2", /* 16 */
122 | "CF2", /* 17 */
123 | "CG2", /* 18 */
124 | "CH2", /* 19 */
125 |
126 | "DA2", /* 20 */
127 | "DB2", /* 21 */
128 | "DC2", /* 22 */
129 | "DD2", /* 23 */
130 |
131 | "EA2", /* 24 */
132 | "EB2", /* 25 */
133 | "EC2", /* 26 */
134 | "ED2", /* 27 */
135 |
136 | "EE2", /* 28 */
137 | "EF2", /* 29 */
138 | "EG2", /* 30 */
139 | "EH2", /* 31 */
140 |
141 | "FA2", /* 32 */
142 | "FB2", /* 33 */
143 | "FC2", /* 34 */
144 | "FD2", /* 35 */
145 |
146 | "GA2", /* 36 */
147 | "GB2", /* 37 */
148 | "GC2", /* 38 */
149 | "GD2", /* 39 */
150 |
151 | "GE2", /* 40 */
152 | "GF2", /* 41 */
153 | "GG2", /* 42 */
154 | "GH2", /* 43 */
155 |
156 | "HA2", /* 44 */
157 | "HB2", /* 45 */
158 | "HC2", /* 46 */
159 | "HD2", /* 47 */
160 | };
161 |
162 | /**
163 | * Map of 5 LEDs in bar at 0 degrees
164 | * B{E:H}2, BH1
165 | */
166 | char *led_mapping_bar000[5] = {
167 | "BE2", /* 00 */
168 | "BF2", /* 01 */
169 | "BG2", /* 02 */
170 | "BH2", /* 03 */
171 | "BH1" /* 04 */
172 | };
173 |
174 | /**
175 | * Map of 5 LEDs in bar at 90 degrees
176 | * D{E:H}2, DH1
177 | */
178 | char *led_mapping_bar090[5] = {
179 | "DE2", /* 00 */
180 | "DF2", /* 01 */
181 | "DG2", /* 02 */
182 | "DH2", /* 03 */
183 | "DH1" /* 04 */
184 | };
185 |
186 | /**
187 | * Map of 5 LEDs in bar at 180 degrees
188 | * F{E:H}2, FH1
189 | */
190 | char *led_mapping_bar180[5] = {
191 | "FE2", /* 00 */
192 | "FF2", /* 01 */
193 | "FG2", /* 02 */
194 | "FH2", /* 03 */
195 | "FH1" /* 04 */
196 | };
197 |
198 | /**
199 | * Map of 5 LEDs in bar at 270 degrees
200 | * H{E:H}2, HH1
201 | */
202 | char *led_mapping_bar270[5] = {
203 | "HE2", /* 00 */
204 | "HF2", /* 01 */
205 | "HG2", /* 02 */
206 | "HH2", /* 03 */
207 | "HH1", /* 04 */
208 | };
209 |
210 | /**
211 | * Map of all bars, iterating across
212 | */
213 | char *led_mapping_across_all_bars[20] = {
214 | "BE2", /* 00 */
215 | "BF2", /* 01 */
216 | "BG2", /* 02 */
217 | "BH2", /* 03 */
218 | "BH1", /* 04 */
219 |
220 | "DE2", /* 00 */
221 | "DF2", /* 01 */
222 | "DG2", /* 02 */
223 | "DH2", /* 03 */
224 | "DH1", /* 04 */
225 |
226 | "FE2", /* 00 */
227 | "FF2", /* 01 */
228 | "FG2", /* 02 */
229 | "FH2", /* 03 */
230 | "FH1", /* 04 */
231 |
232 | "HE2", /* 00 */
233 | "HF2", /* 01 */
234 | "HG2", /* 02 */
235 | "HH2", /* 03 */
236 | "HH1", /* 04 */
237 | };
238 |
239 | /**
240 | * Map of all bars, iterating around
241 | */
242 | char *led_mapping_around_all_bars[20] = {
243 | "BE2", /* 00 */
244 | "DE2", /* 00 */
245 | "FE2", /* 00 */
246 | "HE2", /* 00 */
247 |
248 | "BF2", /* 01 */
249 | "DF2", /* 01 */
250 | "FF2", /* 01 */
251 | "HF2", /* 01 */
252 |
253 | "BG2", /* 02 */
254 | "DG2", /* 02 */
255 | "FG2", /* 02 */
256 | "HG2", /* 02 */
257 |
258 | "BH2", /* 03 */
259 | "DH2", /* 03 */
260 | "FH2", /* 03 */
261 | "HH2", /* 03 */
262 |
263 | "BH1", /* 04 */
264 | "DH1", /* 04 */
265 | "FH1", /* 04 */
266 | "HH1", /* 04 */
267 | };
268 |
269 | /**
270 | * Innermost 4 LEDs in bars
271 | */
272 | char *led_mapping_inner[4] = {
273 | "BH1",
274 | "DH1",
275 | "FH1",
276 | "HH1",
277 | };
278 |
--------------------------------------------------------------------------------
/led_analog_clock/led_mapping.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef LED_MAPPING_H
21 | #define LED_MAPPING_H
22 |
23 | extern char *led_mapping_minute[60];
24 | extern char *led_mapping_qhour[48];
25 | extern char *led_mapping_bar000[5];
26 | extern char *led_mapping_bar090[5];
27 | extern char *led_mapping_bar180[5];
28 | extern char *led_mapping_bar270[5];
29 | extern char *led_mapping_across_all_bars[20];
30 | extern char *led_mapping_around_all_bars[20];
31 | extern char *led_mapping_inner[4];
32 |
33 | #endif /* LED_MAPPING_H */
34 |
--------------------------------------------------------------------------------
/led_charlieplex/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | led_charlieplex
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 |
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | make
31 |
32 |
33 | org.eclipse.cdt.make.core.buildLocation
34 | ${workspace_loc:/led_charlieplex/Release}
35 |
36 |
37 | org.eclipse.cdt.make.core.cleanBuildTarget
38 | clean
39 |
40 |
41 | org.eclipse.cdt.make.core.contents
42 | org.eclipse.cdt.make.core.activeConfigSettings
43 |
44 |
45 | org.eclipse.cdt.make.core.enableAutoBuild
46 | false
47 |
48 |
49 | org.eclipse.cdt.make.core.enableCleanBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.enableFullBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.fullBuildTarget
58 | all
59 |
60 |
61 | org.eclipse.cdt.make.core.stopOnError
62 | true
63 |
64 |
65 | org.eclipse.cdt.make.core.useDefaultBuildCmd
66 | true
67 |
68 |
69 |
70 |
71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
72 |
73 |
74 |
75 |
76 |
77 | org.eclipse.cdt.core.cnature
78 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
79 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
80 | de.innot.avreclipse.core.avrnature
81 |
82 |
83 |
--------------------------------------------------------------------------------
/led_charlieplex/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/MCUType=atmega644
11 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.lib.release.541968731.51744801/UseExtendedRAMforHeap=true
13 | avrtarget/perConfig=false
14 | eclipse.preferences.version=1
15 |
--------------------------------------------------------------------------------
/led_charlieplex/led_charlieplex.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include "led_charlieplex.h"
25 |
26 | void led_charlieplex_init(led_charlieplex_t *charlieplex)
27 | {
28 | led_charlieplex_port_t *port = charlieplex->port;
29 |
30 | for(; port->pins != 0x00; port++)
31 | {
32 | *(port->ddr) &= ~(port->pins);
33 | *(port->port) &= ~(port->pins);
34 | }
35 | }
36 |
37 | uint8_t led_charlieplex_find_index_by_name(led_charlieplex_t *charlieplex, char *name)
38 | {
39 | led_charlieplex_led_t *led = charlieplex->led;
40 | uint8_t index = 0;
41 |
42 | for(; led->name != NULL; led++, index++)
43 | {
44 | if(strcasecmp(led->name, name) == 0)
45 | return index;
46 | }
47 |
48 | return LED_CHARLIEPLEX_LED_UNKNOWN;
49 | }
50 |
51 | inline void led_charlieplex_unset(led_charlieplex_t *charlieplex, led_charlieplex_led_t *led)
52 | {
53 | *(charlieplex->port[led->h_port].ddr) &= ~_BV(led->h_value);
54 | *(charlieplex->port[led->l_port].ddr) &= ~_BV(led->l_value);
55 |
56 | *(charlieplex->port[led->h_port].port) &= ~_BV(led->h_value);
57 | *(charlieplex->port[led->l_port].port) &= ~_BV(led->l_value);
58 | }
59 |
60 | inline void led_charlieplex_unset_last_inline(led_charlieplex_t *charlieplex)
61 | {
62 | if(charlieplex->last_led)
63 | {
64 | led_charlieplex_unset(charlieplex, charlieplex->last_led);
65 | charlieplex->last_led = NULL;
66 | }
67 | }
68 |
69 | void led_charlieplex_unset_last(led_charlieplex_t *charlieplex)
70 | {
71 | led_charlieplex_unset_last_inline(charlieplex);
72 | }
73 |
74 | inline void led_charlieplex_set(led_charlieplex_t *charlieplex, led_charlieplex_led_t *led)
75 | {
76 | led_charlieplex_unset_last_inline(charlieplex);
77 |
78 | /*
79 | * Set the data direction registers so that unused pins for this LED
80 | * are not set as outputs. This will ensure that the pullups and
81 | * pulldowns for that pin are disabled
82 | */
83 | *(charlieplex->port[led->h_port].ddr) |= _BV(led->h_value);
84 | *(charlieplex->port[led->l_port].ddr) |= _BV(led->l_value);
85 |
86 | /*
87 | * Enable the pullup on the high side of the LED and enable the pulldown
88 | * on the low side.
89 | */
90 | *(charlieplex->port[led->h_port].port) |= _BV(led->h_value);
91 | *(charlieplex->port[led->l_port].port) &= ~_BV(led->l_value);
92 |
93 | /* Track the LED set so that it can be quickly unset later. */
94 | charlieplex->last_led = led;
95 | }
96 |
97 | void led_charlieplex_set_by_name(led_charlieplex_t *charlieplex, char *name)
98 | {
99 | uint8_t led_index;
100 |
101 | led_index = led_charlieplex_find_index_by_name(charlieplex, name);
102 |
103 | if(led_index == LED_CHARLIEPLEX_LED_UNKNOWN)
104 | return;
105 |
106 | led_charlieplex_set(charlieplex, &charlieplex->led[led_index]);
107 | }
108 |
109 | void led_charlieplex_set_by_index(led_charlieplex_t *charlieplex, uint8_t index)
110 | {
111 | led_charlieplex_set(charlieplex, &charlieplex->led[index]);
112 | }
113 |
--------------------------------------------------------------------------------
/led_charlieplex/led_charlieplex.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | /**
21 |
22 | @mainpage
23 |
24 | A library to handle a charlieplexed matrix of LEDs.
25 |
26 | @section about About Charliplexing
27 |
28 | Charlieplexing is a technique used to allow a large number of LEDs to be
29 | used in a matrix display, while only using a small number of IO pins. It
30 | depends on tri-state logic to allow pins to "float".
31 |
32 | A charlieplexed display is arranged in an X-Y matrix of cells as typical,
33 | but each cell contains two LEDs in opposite polarities as follows:
34 |
35 | @verbatim
36 | X Y
37 | | |
38 | +-->|--+ (a)
39 | +--|<--+ (b)
40 | @endverbatim
41 |
42 | Due to LEDs being polarized one pin is pulled high and the other is pulled
43 | low, one of the two LEDs will light. When these cells are used in this way,
44 | a 4x4 matrix could be constructed as follows:
45 |
46 | @verbatim
47 | X0 X1 X2 X3
48 | ---- ---- ---- ----
49 | Y0 | x0y0 x1y0 x2y0 x3y0
50 | Y1 | x0y1 x1y1 x2y1 x3y1
51 | Y2 | x0y2 x1y2 x2y2 x3y2
52 | Y3 | x0y3 x1y3 x2y3 x3y3
53 | @endverbatim
54 |
55 | If X0 is pulled high and Y0 is pulled low while X{1-3} and Y{1-3} are allowed
56 | to float (tri-stated), only x0y0a will light. In order to minimize ghosting
57 | and other display artifacts, only one LED can be lit at a time.
58 |
59 | If a high enough refresh rate can be maintained, a charlieplexed display (as
60 | any other LED display) can appear as though several LEDs are lit simultaneously.
61 |
62 | More information can be found on Wikipedia:
63 |
64 | http://en.wikipedia.org/wiki/Charlieplexing
65 |
66 | @section usage Use of this library
67 |
68 | Typically you will want to populate a led_charlieplex_t structure
69 | representing your charlieplexed matrix. Usually it is easiest to do this
70 | in three steps by creating and populating the sub-structures first. For
71 | example, using the previous 4x4 matrix, with:
72 |
73 | @li \c X{0-3} connected to \c PB{0-3}
74 | @li \c Y{0-3} connected to \c PD{4-7}
75 |
76 | The led_charlieplex_port_t would be populated as follows:
77 |
78 | @code
79 | led_charlieplex_port_t led_example_ports[] = {
80 | { &PINB, &DDRB, &PORTB, (_BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3)) },
81 | { &PIND, &DDRD, &PORTD, (_BV(PD4) | _BV(PD5) | _BV(PD6) | _BV(PD7)) },
82 | { NULL, NULL, NULL, 0 },
83 | };
84 | @endcode
85 |
86 | The led_charlieplex_led_t would be populated as follows:
87 |
88 | @code
89 | led_charlieplex_led_t led_example_leds[] = {
90 | { "x0y0a", 0, 0, 1, 4 },
91 | { "x1y0a", 0, 1, 1, 4 },
92 | { "x2y0a", 0, 2, 1, 4 },
93 | { "x3y0a", 0, 3, 1, 4 },
94 |
95 | { "x0y0b", 1, 4, 0, 0 },
96 | { "x1y0b", 1, 4, 0, 1 },
97 | { "x2y0b", 1, 4, 0, 2 },
98 | { "x3y0b", 1, 4, 0, 3 },
99 |
100 | ...
101 |
102 | { "x0y1a", 0, 0, 1, 5 },
103 | { "x1y1a", 0, 1, 1, 5 },
104 | { "x2y1a", 0, 2, 1, 5 },
105 | { "x3y1a", 0, 3, 1, 5 },
106 |
107 | { "x0y1b", 1, 5, 0, 0 },
108 | { "x1y1b", 1, 5, 0, 1 },
109 | { "x2y1b", 1, 5, 0, 2 },
110 | { "x3y1b", 1, 5, 0, 3 },
111 |
112 | ...
113 |
114 | { NULL, 0, 0, 0, 0 }
115 | };
116 | @endcode
117 |
118 | And then the led_charlieplex_t would be populated by referencing both supporting
119 | structures as follows:
120 |
121 | @code
122 | led_charlieplex_t led_example = {
123 | 0,
124 | led_example_ports,
125 | led_example_leds
126 | };
127 | @endcode
128 |
129 | */
130 |
131 | #ifndef LED_CHARLIEPLEX_H
132 | #define LED_CHARLIEPLEX_H
133 |
134 | /**
135 | * A special value meaning that no LED was found, returned where an index
136 | * would otherwise be returned. This limits the maximum number of LEDs in a
137 | * matrix to 254, as index 255 is hereby reserved.
138 | */
139 | #define LED_CHARLIEPLEX_LED_UNKNOWN 0xff
140 |
141 | /**
142 | * A structure used to contain the PIN*, DDR*, PORT* and a bitmap of pins
143 | * in use on a single port used for this charlieplexed matrix.
144 | */
145 | typedef struct _led_charlieplex_port_t
146 | {
147 | volatile uint8_t *pin; /**< The PIN* for this port, e.g. &PINC. */
148 | volatile uint8_t *ddr; /**< The DDR* for this port, e.g. &DDRC. */
149 | volatile uint8_t *port; /**< The PORT* for this port, e.g. &PORTC. */
150 | volatile uint8_t pins; /**< The pins in use for this display, e.g. (_BV(PC0) & _BV(PC1)) or 0xFF. */
151 | } led_charlieplex_port_t;
152 |
153 | /**
154 | * A structure used to contain all pins name, and high and low pin information.
155 | *
156 | * The h_port and l_port members are indexes into the display's ->port array.
157 | *
158 | * The h_value and l_value members are the pin number (0-7) of the pin on the
159 | * associated port. It is expanded later in all calculations as necessary.
160 | */
161 | typedef struct _led_charlieplex_led_t
162 | {
163 | char *name; /**< The name of this LED, preferably short, e.g. "AA1". */
164 | uint8_t h_port:4; /**< The high (+) port index, e.g. 0. */
165 | uint8_t h_value:4; /**< The high (+) pin number, e.g. 1. */
166 | uint8_t l_port:4; /**< The low (GND) port index, e.g. 1. */
167 | uint8_t l_value:4; /**< The low (GND) pin number, e.g. 2. */
168 | } led_charlieplex_led_t;
169 |
170 | /**
171 | * A structure used to contain information about a charlieplexed matrix.
172 | */
173 | typedef struct _led_charlieplex_t
174 | {
175 | uint8_t dummy;
176 |
177 | /**
178 | * A NULL-terminated array of pointers to led_charlieplex_port_t structures
179 | * representing all of the ports in use for this charlieplexed matrix.
180 | */
181 | led_charlieplex_port_t *port;
182 |
183 | /**
184 | * A NULL-terminated array of pointers to led_charlieplex_led_t structures
185 | * representing the names and positions of all LEDs present in this charlie-
186 | * plexed matrix.
187 | */
188 | led_charlieplex_led_t *led;
189 |
190 | /**
191 | * (Internal use only.) A pointer to the last LED enabled, so that it can be
192 | * efficiently toggled off without affecting the rest of the matrix.
193 | */
194 | led_charlieplex_led_t *last_led;
195 | } led_charlieplex_t;
196 |
197 | /**
198 | * Initialize a charlieplexed matrix, clearing all LEDs.
199 | */
200 | extern void led_charlieplex_init(led_charlieplex_t *charlieplex);
201 |
202 | /**
203 | * Find the index into the led_charlieplex_t.led structure for led.
204 | *
205 | * @param[in] charlieplex A pointer to the led_charlieplex_t structure.
206 | * @param[in] name The name of the LED to search for.
207 | *
208 | * @return The index of the LED, if found, or LED_CHARLIEPLEX_LED_UNKNOWN if not found.
209 | */
210 | extern uint8_t led_charlieplex_find_index_by_name(led_charlieplex_t *charlieplex, char *name);
211 |
212 | /**
213 | * Set (enable) an LED by name.
214 | *
215 | * @param[in] charlieplex A pointer to the led_charlieplex_t structure.
216 | * @param[in] name The name of the LED to set.
217 | */
218 | extern void led_charlieplex_set_by_name(led_charlieplex_t *charlieplex, char *name);
219 |
220 | /**
221 | * Set (enable) an LED by index in the led_charlieplex_t.led array.
222 | *
223 | * @param[in] charlieplex A pointer to the led_charlieplex_t structure.
224 | * @param[in] index The index of the LED to set.
225 | */
226 | extern void led_charlieplex_set_by_index(led_charlieplex_t *charlieplex, uint8_t index);
227 |
228 | /**
229 | * Unset (disable) the last LED set, clearing the matrix.
230 | *
231 | * @param[in] charlieplex A pointer to the led_charlieplex_t structure.
232 | */
233 | extern void led_charlieplex_unset_last(led_charlieplex_t *charlieplex);
234 |
235 | #endif /* LED_CHARLIEPLEX_H */
236 |
--------------------------------------------------------------------------------
/led_sequencer/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | led_sequencer
4 |
5 |
6 | led_charlieplex
7 |
8 |
9 |
10 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
11 | clean,full,incremental,
12 |
13 |
14 | ?name?
15 |
16 |
17 |
18 | org.eclipse.cdt.make.core.append_environment
19 | true
20 |
21 |
22 | org.eclipse.cdt.make.core.autoBuildTarget
23 | all
24 |
25 |
26 | org.eclipse.cdt.make.core.buildArguments
27 |
28 |
29 |
30 | org.eclipse.cdt.make.core.buildCommand
31 | make
32 |
33 |
34 | org.eclipse.cdt.make.core.buildLocation
35 | ${workspace_loc:/led_sequencer/Release}
36 |
37 |
38 | org.eclipse.cdt.make.core.cleanBuildTarget
39 | clean
40 |
41 |
42 | org.eclipse.cdt.make.core.contents
43 | org.eclipse.cdt.make.core.activeConfigSettings
44 |
45 |
46 | org.eclipse.cdt.make.core.enableAutoBuild
47 | false
48 |
49 |
50 | org.eclipse.cdt.make.core.enableCleanBuild
51 | true
52 |
53 |
54 | org.eclipse.cdt.make.core.enableFullBuild
55 | true
56 |
57 |
58 | org.eclipse.cdt.make.core.fullBuildTarget
59 | all
60 |
61 |
62 | org.eclipse.cdt.make.core.stopOnError
63 | true
64 |
65 |
66 | org.eclipse.cdt.make.core.useDefaultBuildCmd
67 | true
68 |
69 |
70 |
71 |
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
73 |
74 |
75 |
76 |
77 |
78 | org.eclipse.cdt.core.cnature
79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
81 | de.innot.avreclipse.core.avrnature
82 |
83 |
84 |
--------------------------------------------------------------------------------
/led_sequencer/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/MCUType=atmega644
11 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.lib.release.1214275602.1933955972/UseExtendedRAMforHeap=true
13 | avrtarget/perConfig=false
14 | eclipse.preferences.version=1
15 |
--------------------------------------------------------------------------------
/led_sequencer/led_sequencer.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 |
31 | #include "led_sequencer.h"
32 |
33 | led_sequencer_t *sequencer_global = NULL;
34 |
35 | /**
36 | * Dump the current animation sequence as a series of Sequence and Step lines
37 | * using printf. This is used only for debugging (mostly debugging the this
38 | * library itself).
39 | */
40 | void led_sequencer_dump_sequence()
41 | {
42 | led_sequence_t *sequence;
43 | led_sequence_step_t *step;
44 |
45 | for(sequence = sequencer_global->sequence; sequence; sequence = sequence->next)
46 | {
47 | printf_P(PSTR("Sequence 0x%04x, %s\n"),
48 | (uint16_t)sequence, sequence->name);
49 | for(step = sequence->step; step; step = step->next)
50 | {
51 | printf_P(PSTR(" Step 0x%04x, JIT 0x%04x, %i ticks\n"),
52 | (uint16_t)step, (uint16_t)step->jit_function, step->ticks_remaining);
53 | }
54 | }
55 | }
56 |
57 | /**
58 | * Interrupt handler for "tick" interrupt set up by led_sequencer_timer_init().
59 | */
60 | ISR(TIMER0_COMPA_vect)
61 | {
62 | led_sequencer_tick();
63 | }
64 |
65 | /**
66 | * Initialize Timer 0 to fire "hz" times per second.
67 | */
68 | void led_sequencer_timer_init(uint16_t hz)
69 | {
70 | /* Set pre-scaler to /256 */
71 | TCCR0B |= _BV(CS02);
72 |
73 | /* Force Output Compare A */
74 | TCCR0B |= _BV(FOC0A);
75 |
76 | /* Output Compare Interrupt Enable A */
77 | TIMSK0 |= _BV(OCIE0A);
78 |
79 | /* Set initial counter value */
80 | TCNT0 = 0;
81 |
82 | /* Set Output Compare Register to aim for 1ms interrupt */
83 | OCR0A = (F_CPU / 256) / hz ;
84 | }
85 |
86 | /**
87 | * Initialize the sequencer library, including the timer and memory structures.
88 | */
89 | led_sequencer_t *led_sequencer_init(uint16_t hz)
90 | {
91 | sequencer_global = malloc(sizeof(led_sequencer_t));
92 |
93 | led_sequencer_timer_init(hz);
94 |
95 | sequencer_global->matrix = NULL;
96 | sequencer_global->sequence = NULL;
97 | sequencer_global->status = LED_SEQUENCER_HALTED;
98 |
99 | return sequencer_global;
100 | }
101 |
102 | void led_sequencer_halt()
103 | {
104 | if(sequencer_global)
105 | sequencer_global->status = LED_SEQUENCER_HALTED;
106 | }
107 |
108 | void led_sequencer_run()
109 | {
110 | if(sequencer_global)
111 | sequencer_global->status = LED_SEQUENCER_RUNNING;
112 | }
113 |
114 | /**
115 | * For a given sequence step, if ticks_remaining has reached zero, free
116 | * the step. Then, if the current step isn't perpetual, subtract a tick
117 | * from the step's ticks_remaining.
118 | */
119 | void led_sequencer_tick_sequence_step(led_sequence_t *sequence)
120 | {
121 | led_sequence_step_t *free_step;
122 |
123 | if(sequence->step->ticks_remaining == 0)
124 | {
125 | if(sequence->step->jit_function
126 | && ((*sequence->step->jit_function)(sequence->step, LED_SEQUENCER_JIT_EMPTY) == LED_SEQUENCER_JIT_CONTINUE)
127 | && (sequence->step->ticks_remaining > 0))
128 | goto refilled;
129 |
130 | free_step = sequence->step;
131 | sequence->step = sequence->step->next;
132 | free(free_step);
133 |
134 | if(sequence->step && sequence->step->jit_function)
135 | (*sequence->step->jit_function)(sequence->step, LED_SEQUENCER_JIT_INITIAL);
136 | }
137 |
138 | refilled:
139 | if(sequence->step && sequence->step->ticks_remaining != 0 && sequence->step->ticks_remaining != 0xff)
140 | {
141 | sequence->step->ticks_remaining--;
142 | }
143 | }
144 |
145 | /**
146 | * Iterate through all sequences in the global sequence list, for each of them,
147 | * call led_sequencer_tick_sequence_step.
148 | */
149 | void led_sequencer_tick_sequence()
150 | {
151 | led_sequence_t *sequence;
152 | uint8_t sequence_steps = 0;
153 |
154 | for(sequence = sequencer_global->sequence; sequence; sequence = sequence->next)
155 | {
156 | if(sequence->step != NULL)
157 | {
158 | led_sequencer_tick_sequence_step(sequence);
159 | sequence_steps++;
160 | }
161 | }
162 | }
163 |
164 | /**
165 | * Progress the animation sequence by one tick, often 1ms, but depends on
166 | * the value 'hz' passed to led_sequencer_init(). Normally called by the
167 | * Timer 0 Output Compare A interrupt (TIMER0_COMPA_vect). This function
168 | * really just does the housekeeping and sanity checking and then calls out
169 | * to led_sequencer_tick_sequence() to do the real work.
170 | */
171 | void led_sequencer_tick()
172 | {
173 | TCNT0 = 0;
174 |
175 | if(sequencer_global && sequencer_global->status == LED_SEQUENCER_RUNNING)
176 | {
177 | led_sequencer_tick_sequence();
178 | }
179 | }
180 |
181 | /**
182 | * Play through one cycle of the LEDs which should currently be illuminated.
183 | * Normally this function is called during all spare time in the main loop,
184 | * and most other functions are called between runs of led_sequencer_run() or
185 | * through interrupts.
186 | */
187 | void led_sequencer_display()
188 | {
189 | led_sequence_t *sequence;
190 |
191 | if(sequencer_global->status != LED_SEQUENCER_RUNNING)
192 | return;
193 |
194 | for(sequence = sequencer_global->sequence; sequence; sequence = sequence->next)
195 | {
196 | if(sequence->step && sequence->step->type == LED_SEQUENCER_STEP_SHOW)
197 | {
198 | led_charlieplex_set_by_index(sequence->step->matrix->charlieplex, sequence->step->matrix_index);
199 | _delay_us(20);
200 | led_charlieplex_unset_last(sequence->step->matrix->charlieplex);
201 | }
202 | }
203 |
204 | }
205 |
206 | /**
207 | * Find a matrix in the global matrix list by its name.
208 | */
209 | led_matrix_t *led_sequencer_find_matrix_by_name(char *matrix_name)
210 | {
211 | led_matrix_t *matrix = sequencer_global->matrix;
212 |
213 | for(; matrix != NULL; matrix = matrix->next)
214 | {
215 | if(strcmp(matrix->name, matrix_name) == 0)
216 | return matrix;
217 | }
218 |
219 | return NULL;
220 | }
221 |
222 | /**
223 | * Push a matrix to the global matrix list.
224 | */
225 | led_matrix_t *led_sequencer_push_front_matrix(char *matrix_name, led_charlieplex_t *charlieplex)
226 | {
227 | led_matrix_t *matrix;
228 |
229 | if((matrix = malloc(sizeof(led_matrix_t))))
230 | {
231 | matrix->name = malloc(strlen(matrix_name)+1);
232 | strcpy(matrix->name, matrix_name);
233 | matrix->charlieplex = charlieplex;
234 | matrix->next = sequencer_global->matrix;
235 | sequencer_global->matrix = matrix;
236 | }
237 |
238 | return matrix;
239 | }
240 |
241 | /**
242 | * Find a sequence in the global sequence list by name.
243 | */
244 | led_sequence_t *led_sequencer_find_sequence_by_name(char *sequence_name)
245 | {
246 | led_sequence_t *sequence = sequencer_global->sequence;
247 |
248 | for(; sequence != NULL; sequence = sequence->next)
249 | {
250 | if(strcmp(sequence->name, sequence_name) == 0)
251 | return sequence;
252 | }
253 |
254 | return NULL;
255 | }
256 |
257 | /**
258 | * Add a sequence to the global sequence list, and return a pointer to it.
259 | */
260 | led_sequence_t *led_sequencer_push_back_sequence(char *sequence_name)
261 | {
262 | led_sequence_t *sequence, *last_sequence;
263 |
264 | if((sequence = malloc(sizeof(led_sequence_t))))
265 | {
266 | sequence->name = malloc(strlen(sequence_name)+1);
267 | strcpy(sequence->name, sequence_name);
268 | sequence->step = NULL;
269 | sequence->next = NULL;
270 | }
271 |
272 | if(sequencer_global->sequence)
273 | {
274 | for(last_sequence = sequencer_global->sequence; last_sequence->next; last_sequence = last_sequence->next);
275 | last_sequence->next = sequence;
276 | }
277 | else
278 | {
279 | sequencer_global->sequence = sequence;
280 | }
281 |
282 | return sequence;
283 | }
284 |
285 | void led_sequencer_sequence_push_back_jit(char *sequence_name, led_sequence_step_type_t type, char *matrix_name, led_sequencer_jit_function_t *jit_function)
286 | {
287 | led_sequence_step_t *step;
288 | step = led_sequencer_sequence_push_back_step(sequence_name, type, matrix_name, NULL, 254);
289 | step->jit_function = jit_function;
290 | (*step->jit_function)(step, LED_SEQUENCER_JIT_INITIAL);
291 | }
292 |
293 | /**
294 | * Push a step on to the end of a sequence.
295 | */
296 | led_sequence_step_t *led_sequencer_sequence_push_back_step(char *sequence_name, led_sequence_step_type_t type, char *matrix_name, char *led_name, uint8_t ticks)
297 | {
298 | led_sequence_t *sequence;
299 | led_sequence_step_t *step, *last_step;
300 |
301 | if((step = malloc(sizeof(led_sequence_step_t))))
302 | {
303 | sequence = led_sequencer_find_sequence_by_name(sequence_name);
304 |
305 | step->type = type;
306 | step->matrix = led_sequencer_find_matrix_by_name(matrix_name);
307 | if(led_name)
308 | {
309 | step->matrix_index = led_charlieplex_find_index_by_name(step->matrix->charlieplex, led_name);
310 | }
311 | step->ticks_remaining = ticks;
312 | step->next = NULL;
313 |
314 | if(sequence->step)
315 | {
316 | for(last_step = sequence->step; last_step->next; last_step = last_step->next) {}
317 | last_step->next = step;
318 | }
319 | else
320 | {
321 | sequence->step = step;
322 | }
323 |
324 | return step;
325 | }
326 |
327 | return NULL;
328 | }
329 |
330 | /**
331 | * Modify a step in place within a sequence. This is mostly useful for steps
332 | * with a 'ticks' value of 255 (never ending).
333 | */
334 | void led_sequencer_sequence_modify_step(led_sequence_step_t *step, char *led_name, uint8_t ticks)
335 | {
336 | step->matrix_index = led_charlieplex_find_index_by_name(step->matrix->charlieplex, led_name);
337 | step->ticks_remaining = ticks;
338 | }
339 |
340 | /**
341 | * Clear an entire sequence of any steps remaining.
342 | */
343 | void led_sequencer_sequence_clear(char *sequence_name)
344 | {
345 | led_sequence_t *sequence;
346 |
347 | sequence = led_sequencer_find_sequence_by_name(sequence_name);
348 |
349 | for(; sequence->step; sequence->step = sequence->step->next)
350 | {
351 | free(sequence->step);
352 | }
353 | }
354 |
--------------------------------------------------------------------------------
/led_sequencer/led_sequencer.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | /*
21 |
22 | Sequence 0
23 | Step 0
24 | type
25 | matrix, matrix_index
26 | ticks_remaining
27 | next
28 | ...
29 | Step N
30 | NULL
31 | ...
32 | Sequence N
33 | NULL
34 |
35 | */
36 |
37 | #ifndef LED_SEQUENCER_H
38 | #define LED_SEQUENCER_H
39 |
40 | #include
41 |
42 | #include
43 |
44 | /**
45 | * An LED matrix registered by name with the led_sequencer library.
46 | * Currently this only support the led_charlieplex library, but in the future
47 | * this should be extended to work with some others, in which case the main
48 | * charlieplex pointer will be renamed and changed to a void *.
49 | */
50 | typedef struct _led_matrix_t
51 | {
52 | char *name;
53 | led_charlieplex_t *charlieplex;
54 | struct _led_matrix_t *next;
55 | } led_matrix_t;
56 |
57 | /**
58 | * Different types of steps, which primarily allows for inserting blank delays
59 | * into sequences.
60 | */
61 | typedef enum _led_sequence_step_type_t
62 | {
63 | LED_SEQUENCER_STEP_DELAY_MS,
64 | LED_SEQUENCER_STEP_SHOW,
65 | LED_SEQUENCER_STEP_UNKNOWN = 255
66 | } led_sequence_step_type_t;
67 |
68 |
69 | #define LED_SEQUENCER_JIT_CONTINUE 1
70 | #define LED_SEQUENCER_JIT_DEQUEUE 2
71 | #define LED_SEQUENCER_JIT_INITIAL 100
72 | #define LED_SEQUENCER_JIT_EMPTY 101
73 | #define LED_SEQUENCER_JIT_ERROR 255
74 |
75 | //typedef struct _led_sequence_step_t;
76 | struct _led_sequence_step_t;
77 | typedef uint8_t (led_sequencer_jit_function_t)(struct _led_sequence_step_t *step, uint8_t status) ;
78 |
79 | /**
80 | * A single step and structure for singly linked list of steps within a
81 | * sequence. Each step is executed for 'ticks_remaining' ticks of the global
82 | * sequencer clock.
83 | */
84 | typedef struct _led_sequence_step_t
85 | {
86 | led_sequence_step_type_t type;
87 | led_matrix_t *matrix;
88 | uint8_t matrix_index;
89 | uint8_t ticks_remaining;
90 | led_sequencer_jit_function_t *jit_function;
91 | struct _led_sequence_step_t *next;
92 | } led_sequence_step_t;
93 |
94 | /**
95 | * A sequence, registered by name and containing a singly linked list of
96 | * sequencer steps.
97 | */
98 | typedef struct _led_sequence_t
99 | {
100 | char *name;
101 | led_sequence_step_t *step;
102 | struct _led_sequence_t *next;
103 | } led_sequence_t;
104 |
105 | typedef enum _led_sequencer_status_t
106 | {
107 | LED_SEQUENCER_HALTED = 0,
108 | LED_SEQUENCER_RUNNING = 1,
109 | } led_sequencer_status_t;
110 |
111 | /**
112 | * A global structure containing the two main items: all registered matrixes
113 | * and all registered sequences. Due to its manipulation within ISRs, this
114 | * is only really useful as a global.
115 | */
116 | typedef struct _led_sequencer_t
117 | {
118 | led_matrix_t *matrix;
119 | led_sequence_t *sequence;
120 | led_sequencer_status_t status;
121 | } led_sequencer_t;
122 |
123 | /**
124 | * A global structure holding all sequencer-related data.
125 | */
126 | extern led_sequencer_t *sequencer_global;
127 |
128 | extern led_sequencer_t *led_sequencer_init(uint16_t hz);
129 |
130 | extern void led_sequencer_halt();
131 | extern void led_sequencer_run();
132 |
133 | extern void led_sequencer_tick();
134 | extern void led_sequencer_display();
135 | extern void led_sequencer_dump_sequence();
136 | extern void led_sequencer_timer_init(uint16_t hz);
137 |
138 | extern led_matrix_t *led_sequencer_find_matrix_by_name(char *matrix_name);
139 | extern led_matrix_t *led_sequencer_push_front_matrix(char *matrix_name, led_charlieplex_t *charlieplex);
140 |
141 | extern led_sequence_t *led_sequencer_find_sequence_by_name(char *sequence_name);
142 | extern led_sequence_t *led_sequencer_push_back_sequence(char *sequence_name);
143 | extern void led_sequencer_sequence_push_back_jit(char *sequence_name, led_sequence_step_type_t type, char *matrix_name, led_sequencer_jit_function_t *jit_function);
144 | extern led_sequence_step_t *led_sequencer_sequence_push_back_step(char *sequence_name, led_sequence_step_type_t type, char *matrix_name, char *led_name, uint8_t ticks);
145 | extern void led_sequencer_sequence_modify_step(led_sequence_step_t *step, char *led_name, uint8_t ticks);
146 | extern void led_sequencer_sequence_clear(char *sequence_name);
147 |
148 | #endif /* LED_SEQUENCER_H */
149 |
--------------------------------------------------------------------------------
/nmea/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | nmea
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
25 | de.innot.avreclipse.core.avrnature
26 |
27 |
28 |
--------------------------------------------------------------------------------
/nmea/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/MCUType=atmega1284p
11 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781.939001143/UseExtendedRAMforHeap=true
13 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/ClockFrequency=8000000
14 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/ExtRAMSize=0
15 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/ExtendedRAM=false
16 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/MCUType=atmega644
17 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/UseEEPROM=false
18 | avrtarget/de.innot.avreclipse.configuration.lib.release.2123079960.1021803781/UseExtendedRAMforHeap=true
19 | avrtarget/perConfig=true
20 | eclipse.preferences.version=1
21 |
--------------------------------------------------------------------------------
/nmea/nmea.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef NMEA_H_
21 | #define NMEA_H_
22 |
23 | #include
24 |
25 | #define NMEA_EPOCH 80
26 |
27 | #define NMEA_INVALID_TYPE 0x0001
28 | #define NMEA_INVALID_SENTENCE 0x0002
29 | #define NMEA_INVALID_TIME 0x0004
30 | #define NMEA_INVALID_DATE 0x0008
31 | #define NMEA_INVALID_LATITUDE 0x0010
32 | #define NMEA_INVALID_LONGITUDE 0x0020
33 | #define NMEA_INVALID_UNIT 0x2000
34 | #define NMEA_INVALID_STATUS 0x4000
35 | #define NMEA_INVALID_CHECKSUM 0x8000
36 |
37 | typedef struct _nmea_date_t
38 | {
39 | uint16_t year;
40 | uint8_t month;
41 | uint8_t day;
42 | } nmea_date_t;
43 |
44 | typedef struct _nmea_time_t
45 | {
46 | uint8_t hour;
47 | uint8_t minute;
48 | uint8_t second;
49 | uint16_t millisecond;
50 | } nmea_time_t;
51 |
52 | typedef struct _nmea_position_t
53 | {
54 | float latitude;
55 | float longitude;
56 | } nmea_position_t;
57 |
58 | typedef struct _nmea_velocity_t
59 | {
60 | float speed;
61 | float heading;
62 | } nmea_velocity_t;
63 |
64 | typedef struct _nmea_gprmc_t
65 | {
66 | char status;
67 | char mode;
68 | nmea_date_t date;
69 | nmea_time_t time;
70 | nmea_position_t position;
71 | nmea_velocity_t velocity;
72 | char checksum;
73 | } nmea_gprmc_t;
74 |
75 | typedef struct _nmea_gpgga_t
76 | {
77 | nmea_time_t time;
78 | nmea_position_t position;
79 | uint8_t fix_quality;
80 | uint8_t satellites_tracked;
81 | float hdop;
82 | float altitude;
83 | float geoid_height;
84 | char checksum;
85 | } nmea_gpgga_t;
86 |
87 | typedef struct _nmea_gpgsa_t
88 | {
89 | char mode;
90 | char fix_type;
91 | uint8_t satellite_prn[12];
92 | float pdop;
93 | float hdop;
94 | float vdop;
95 | char checksum;
96 | } nmea_gpgsa_t;
97 |
98 | typedef struct _nmea_gpgsv_satellite_t
99 | {
100 | uint8_t index;
101 | uint8_t prn;
102 | uint8_t altitude;
103 | uint16_t azimuth;
104 | uint8_t snr;
105 | } nmea_gpgsv_satellite_t;
106 |
107 | typedef struct _nmea_gpgsv_t
108 | {
109 | uint8_t sentence_total;
110 | uint8_t sentence_number;
111 | uint8_t satellites_in_view;
112 | nmea_gpgsv_satellite_t satellite[4];
113 | char checksum;
114 | } nmea_gpgsv_t;
115 |
116 | extern unsigned int nmea_parse_gprmc(char *sentence, nmea_gprmc_t *data);
117 | extern unsigned int nmea_parse_gpgga(char *sentence, nmea_gpgga_t *data);
118 | extern unsigned int nmea_parse_gpgsa(char *sentence, nmea_gpgsa_t *data);
119 | extern unsigned int nmea_parse_gpgsv(char *sentence, nmea_gpgsv_t *data);
120 |
121 | #endif /* NMEA_H_ */
122 |
--------------------------------------------------------------------------------
/rtc/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | rtc
4 |
5 |
6 | i2c
7 |
8 |
9 |
10 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
11 | clean,full,incremental,
12 |
13 |
14 | ?name?
15 |
16 |
17 |
18 | org.eclipse.cdt.make.core.append_environment
19 | true
20 |
21 |
22 | org.eclipse.cdt.make.core.autoBuildTarget
23 | all
24 |
25 |
26 | org.eclipse.cdt.make.core.buildArguments
27 |
28 |
29 |
30 | org.eclipse.cdt.make.core.buildCommand
31 | make
32 |
33 |
34 | org.eclipse.cdt.make.core.buildLocation
35 | ${workspace_loc:/rtc_ds1307/Release}
36 |
37 |
38 | org.eclipse.cdt.make.core.cleanBuildTarget
39 | clean
40 |
41 |
42 | org.eclipse.cdt.make.core.contents
43 | org.eclipse.cdt.make.core.activeConfigSettings
44 |
45 |
46 | org.eclipse.cdt.make.core.enableAutoBuild
47 | false
48 |
49 |
50 | org.eclipse.cdt.make.core.enableCleanBuild
51 | true
52 |
53 |
54 | org.eclipse.cdt.make.core.enableFullBuild
55 | true
56 |
57 |
58 | org.eclipse.cdt.make.core.fullBuildTarget
59 | all
60 |
61 |
62 | org.eclipse.cdt.make.core.stopOnError
63 | true
64 |
65 |
66 | org.eclipse.cdt.make.core.useDefaultBuildCmd
67 | true
68 |
69 |
70 |
71 |
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
73 |
74 |
75 |
76 |
77 |
78 | org.eclipse.cdt.core.cnature
79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
81 | de.innot.avreclipse.core.avrnature
82 |
83 |
84 |
--------------------------------------------------------------------------------
/rtc/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=10
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/NoChipErase=false
14 | avrtarget/avrdude/NoSigCheck=false
15 | avrtarget/avrdude/NoVerify=false
16 | avrtarget/avrdude/NoWrite=false
17 | avrtarget/avrdude/OtherOptions=
18 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
19 | avrtarget/avrdude/UseCounter=false
20 | avrtarget/avrdude/WriteEEPROM=false
21 | avrtarget/avrdude/WriteFlash=true
22 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/ClockFrequency=8000000
23 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/ExtRAMSize=0
24 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/ExtendedRAM=false
25 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/MCUType=atmega1284p
26 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/UseEEPROM=false
27 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907.627179608/UseExtendedRAMforHeap=true
28 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/ClockFrequency=8000000
29 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/ExtRAMSize=0
30 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/ExtendedRAM=false
31 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/MCUType=atmega644
32 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/UseEEPROM=false
33 | avrtarget/de.innot.avreclipse.configuration.lib.release.1550075577.766250907/UseExtendedRAMforHeap=true
34 | avrtarget/perConfig=true
35 | eclipse.preferences.version=1
36 |
--------------------------------------------------------------------------------
/rtc/rtc.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include "rtc.h"
21 |
22 | uint8_t rtc_days_in_month[13][2] = {
23 | {0, 0},
24 | {31, 31},
25 | {28, 29},
26 | {31, 31},
27 | {30, 30},
28 | {31, 31},
29 | {30, 30},
30 | {31, 31},
31 | {31, 31},
32 | {30, 30},
33 | {31, 31},
34 | {30, 30},
35 | {31, 31}
36 | };
37 |
38 | char *rtc_month_abbreviations[13] = {
39 | "",
40 | "Jan",
41 | "Feb",
42 | "Mar",
43 | "Apr",
44 | "May",
45 | "Jun",
46 | "Jul",
47 | "Aug",
48 | "Sep",
49 | "Oct",
50 | "Nov",
51 | "Dec"
52 | };
53 |
54 | char *rtc_dow_names[8] = {
55 | "",
56 | "Sunday",
57 | "Monday",
58 | "Tuesday",
59 | "Wednesday",
60 | "Thursday",
61 | "Friday",
62 | "Saturday"
63 | };
64 |
65 | uint8_t rtc_init(rtc_device_t *rtc)
66 | {
67 | return((*rtc->init)());
68 | }
69 |
70 | uint8_t rtc_clock_start(rtc_device_t *rtc)
71 | {
72 | return((*rtc->clock_start)());
73 | }
74 |
75 | uint8_t rtc_clock_stop(rtc_device_t *rtc)
76 | {
77 | return((*rtc->clock_stop)());
78 | }
79 |
80 | uint8_t rtc_sqw_enable(rtc_device_t *rtc)
81 | {
82 | return((*rtc->sqw_enable)());
83 | }
84 |
85 | uint8_t rtc_sqw_disable(rtc_device_t *rtc)
86 | {
87 | return((*rtc->sqw_disable)());
88 | }
89 |
90 | uint8_t rtc_sqw_rate(rtc_device_t *rtc, uint16_t rate)
91 | {
92 | return((*rtc->sqw_rate)(rate));
93 | }
94 |
95 | uint8_t rtc_read(rtc_device_t *rtc, rtc_datetime_24h_t *dt)
96 | {
97 | return((*rtc->read)(dt));
98 | }
99 |
100 | uint8_t rtc_write(rtc_device_t *rtc, rtc_datetime_24h_t *dt)
101 | {
102 | return((*rtc->write)(dt));
103 | }
104 |
105 | uint8_t rtc_find_dow(uint16_t y, uint8_t m, uint8_t d)
106 | {
107 | static uint8_t t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
108 | y -= m < 3;
109 | return (uint8_t)(1 + ((y + y/4 - y/100 + y/400 + t[m-1] + d) % 7));
110 | }
111 |
112 | int8_t rtc_find_dst_offset(rtc_datetime_24h_t time, rtc_dst_date_t dst_dates[])
113 | {
114 | uint8_t i;
115 |
116 | for(i=0; dst_dates[i].year != 0; i++)
117 | {
118 | /* Skip through the dst_dates array looking for the current year. */
119 | if(dst_dates[i].year > time.year) return(0);
120 | if(dst_dates[i].year < time.year) continue;
121 |
122 | /* The year matches, check the month, day, and hour to try to
123 | * discern whether DST is in effect. */
124 | if( (time.month == dst_dates[i].start_month) &&
125 | (time.date == dst_dates[i].start_date) &&
126 | (time.hour >= 2) )
127 | return(1);
128 | if( (time.month == dst_dates[i].end_month) &&
129 | (time.date == dst_dates[i].end_date) &&
130 | (time.hour < 2) )
131 | return(1);
132 | if( (time.month == dst_dates[i].start_month) &&
133 | (time.date > dst_dates[i].start_date) )
134 | return(1);
135 | if( (time.month == dst_dates[i].end_month) &&
136 | (time.date < dst_dates[i].end_date) )
137 | return(1);
138 | if( (time.month > dst_dates[i].start_month) &&
139 | (time.month < dst_dates[i].end_month) )
140 | return(1);
141 |
142 | /* None of the above were true; DST is not in effect currently. */
143 | return(0);
144 | }
145 |
146 | /* We didn't find an entry in the dst_dates list; assume no DST. */
147 | return(0);
148 | }
149 |
150 | uint8_t rtc_offset_time(rtc_datetime_24h_t *from, rtc_datetime_24h_t *to, uint8_t offset_hours)
151 | {
152 | to->millisecond = from->millisecond;
153 | to->second = from->second;
154 | to->minute = from->minute;
155 | to->hour = from->hour;
156 | to->date = from->date;
157 | to->month = from->month;
158 | to->year = from->year;
159 | to->day_of_week = from->day_of_week;
160 |
161 | to->hour += offset_hours;
162 |
163 | if(to->hour < 0)
164 | {
165 | to->day_of_week -= 1;
166 | if(to->day_of_week == 0)
167 | {
168 | to->day_of_week = 7;
169 | }
170 |
171 | to->date -= 1;
172 | if(to->date == 0)
173 | {
174 | to->month -= 1;
175 | if(to->month == 0)
176 | {
177 | to->year -= 1;
178 | to->month = 12;
179 | }
180 | to->date = rtc_days_in_month[to->month][0]; /* XXX */
181 | }
182 | to->hour += 24;
183 | }
184 |
185 | if(to->hour >= 24)
186 | {
187 | to->day_of_week += 1;
188 | if(to->day_of_week == 8)
189 | {
190 | to->day_of_week = 1;
191 | }
192 |
193 | to->date += 1;
194 | if(to->date > rtc_days_in_month[to->month][0])
195 | {
196 | to->month += 1;
197 | if(to->month == 13)
198 | {
199 | to->year += 1;
200 | to->month = 1;
201 | }
202 | to->date = 1;
203 | }
204 | to->hour -= 24;
205 | }
206 |
207 | return 0;
208 | }
209 |
210 |
--------------------------------------------------------------------------------
/rtc/rtc.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef RTC_H_
21 | #define RTC_H_
22 |
23 | #include
24 | #include "rtc_types.h"
25 |
26 | extern uint8_t rtc_days_in_month[13][2];
27 | extern char *rtc_month_abbreviations[13];
28 | extern char *rtc_dow_names[8];
29 |
30 | extern uint8_t rtc_init(rtc_device_t *rtc);
31 | extern uint8_t rtc_clock_start(rtc_device_t *rtc);
32 | extern uint8_t rtc_clock_stop(rtc_device_t *rtc);
33 | extern uint8_t rtc_sqw_enable(rtc_device_t *rtc);
34 | extern uint8_t rtc_sqw_disable(rtc_device_t *rtc);
35 | extern uint8_t rtc_sqw_rate(rtc_device_t *rtc, uint16_t rate);
36 | extern uint8_t rtc_read(rtc_device_t *rtc, rtc_datetime_24h_t *dt);
37 | extern uint8_t rtc_write(rtc_device_t *rtc, rtc_datetime_24h_t *dt);
38 |
39 | extern uint8_t rtc_find_dow(uint16_t y, uint8_t m, uint8_t d);
40 | extern int8_t rtc_find_dst_offset(rtc_datetime_24h_t time, rtc_dst_date_t dst_dates[]);
41 | extern uint8_t rtc_offset_time(rtc_datetime_24h_t *from, rtc_datetime_24h_t *to, uint8_t offset_hours);
42 |
43 | #endif /* RTC_H_ */
44 |
--------------------------------------------------------------------------------
/rtc/rtc_ds1307.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include "rtc_ds1307.h"
22 |
23 | uint8_t rtc_ds1307_hardware_init(void)
24 | {
25 | uint8_t rc;
26 |
27 | rc = i2c_start(RTC_DS1307_I2C_ID, I2C_WRITE);
28 | if(rc) return 1;
29 |
30 | rc = i2c_write(0x00);
31 | if(rc) return 2;
32 |
33 | i2c_stop();
34 |
35 | rc = i2c_rep_start(RTC_DS1307_I2C_ID, I2C_READ);
36 | if(rc) return 3;
37 |
38 | i2c_read_nak();
39 | i2c_stop();
40 |
41 | return 0;
42 | }
43 | uint8_t rtc_ds1307_read_ram(uint8_t address, uint8_t length, unsigned char *data)
44 | {
45 | uint8_t rc;
46 | uint8_t pos;
47 |
48 | rc = i2c_start(RTC_DS1307_I2C_ID, I2C_WRITE);
49 | if(rc) return 1;
50 |
51 | rc = i2c_write(address);
52 | if(rc) return 2;
53 |
54 | i2c_stop();
55 |
56 | rc = i2c_rep_start(RTC_DS1307_I2C_ID, I2C_READ);
57 | if(rc) return 3;
58 |
59 | for(pos=0; pos < length; pos++, data++)
60 | {
61 | *data = (char)i2c_read(pos != (length-1));
62 | }
63 | i2c_stop();
64 |
65 | return 0;
66 | }
67 |
68 | uint8_t rtc_ds1307_write_ram(uint8_t address, uint8_t length, unsigned char *data)
69 | {
70 | uint8_t rc;
71 | uint8_t pos;
72 |
73 | rc = i2c_start(RTC_DS1307_I2C_ID, I2C_WRITE);
74 | if(rc) return 1;
75 |
76 | rc = i2c_write(address);
77 | if(rc) return 2;
78 |
79 | for(pos=0; pos < length; pos++, data++)
80 | {
81 | rc = i2c_write((uint8_t)*data);
82 | if(rc)
83 | {
84 | i2c_stop();
85 | return 3;
86 | }
87 | }
88 |
89 | i2c_stop();
90 |
91 | return 0;
92 | }
93 |
94 | uint8_t rtc_ds1307_read_register(uint8_t address, uint8_t *value)
95 | {
96 | return rtc_ds1307_read_ram(address, 1, (uint8_t *)value);
97 | }
98 |
99 | uint8_t rtc_ds1307_write_register(uint8_t address, uint8_t *value)
100 | {
101 | return rtc_ds1307_write_ram(address, 1, (uint8_t *)value);
102 | }
103 |
104 | uint8_t rtc_ds1307_read_clock_raw(rtc_ds1307_clock_raw_t *raw)
105 | {
106 | return rtc_ds1307_read_ram(0x00, 8, (unsigned char *)raw);
107 | }
108 |
109 | uint8_t rtc_ds1307_write_clock_raw(rtc_ds1307_clock_raw_t *raw)
110 | {
111 | return rtc_ds1307_write_ram(0x00, 8, (unsigned char *)raw);
112 | }
113 |
114 | uint8_t rtc_ds1307_set_register_bit(uint8_t address, uint8_t bit, uint8_t value)
115 | {
116 | uint8_t rc;
117 | uint8_t data;
118 |
119 | rc = rtc_ds1307_read_register(address, &data);
120 | if(rc) return 1;
121 |
122 | if(value)
123 | {
124 | if(data & _BV(bit)) return 0;
125 | data |= _BV(bit);
126 | }
127 | else
128 | {
129 | if(!(data & _BV(bit))) return 0;
130 | data &= ~_BV(bit);
131 | }
132 |
133 | rc = rtc_ds1307_write_register(address, &data);
134 | if(rc) return 2;
135 |
136 | return 0;
137 | }
138 |
139 | uint8_t rtc_ds1307_hour_style(uint8_t style)
140 | {
141 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_HOUR_STYLE,
142 | RTC_DS1307_CONTROL_HOUR_STYLE, style);
143 | }
144 |
145 | uint8_t rtc_ds1307_sqw_output_fixed(uint8_t output)
146 | {
147 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_SQW_OUTPUT_FIXED,
148 | RTC_DS1307_CONTROL_SQW_OUTPUT_FIXED, output);
149 | }
150 |
151 | uint8_t rtc_ds1307_init(void)
152 | {
153 | uint8_t rc;
154 |
155 | rc = rtc_ds1307_hardware_init();
156 | if(rc) return 1;
157 |
158 | rc = rtc_ds1307_hour_style(RTC_DS1307_HOUR_STYLE_24H);
159 | if(rc) return 2;
160 |
161 | return 0;
162 | }
163 |
164 | uint8_t rtc_ds1307_clock_start(void)
165 | {
166 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_CLOCK_HALT,
167 | RTC_DS1307_CONTROL_CLOCK_HALT, RTC_DS1307_CLOCK_RUN);
168 | }
169 |
170 | uint8_t rtc_ds1307_clock_stop(void)
171 | {
172 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_CLOCK_HALT,
173 | RTC_DS1307_CONTROL_CLOCK_HALT, RTC_DS1307_CLOCK_HALT);
174 | }
175 |
176 | uint8_t rtc_ds1307_sqw_enable(void)
177 | {
178 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_SQW_ENABLE,
179 | RTC_DS1307_CONTROL_SQW_ENABLE, RTC_DS1307_SQW_ENABLE);
180 | }
181 |
182 | uint8_t rtc_ds1307_sqw_disable(void)
183 | {
184 | return rtc_ds1307_set_register_bit(RTC_DS1307_REGISTER_SQW_ENABLE,
185 | RTC_DS1307_CONTROL_SQW_ENABLE, RTC_DS1307_SQW_DISABLE);
186 | }
187 |
188 | uint8_t rtc_ds1307_sqw_rate(uint16_t rate)
189 | {
190 | uint8_t rc;
191 | uint8_t data;
192 | uint8_t rate_control_code;
193 |
194 | switch(rate)
195 | {
196 | case 1:
197 | rate_control_code = RTC_DS1307_SQW_RATE_1HZ;
198 | break;
199 | case 4096:
200 | rate_control_code = RTC_DS1307_SQW_RATE_4096HZ;
201 | break;
202 | case 8192:
203 | rate_control_code = RTC_DS1307_SQW_RATE_8192HZ;
204 | break;
205 | case 32768:
206 | rate_control_code = RTC_DS1307_SQW_RATE_32768HZ;
207 | break;
208 | default:
209 | return 1;
210 | }
211 |
212 | rc = rtc_ds1307_read_register(RTC_DS1307_REGISTER_SQW_RATE, &data);
213 | if(rc) return 1;
214 |
215 | data &= ~(3 << RTC_DS1307_CONTROL_SQW_RATE);
216 | data |= (rate_control_code & 3) << RTC_DS1307_CONTROL_SQW_RATE;
217 |
218 | rc = rtc_ds1307_write_register(RTC_DS1307_REGISTER_SQW_RATE, &data);
219 | if(rc) return 2;
220 |
221 | return 0;
222 | }
223 |
224 | uint8_t rtc_ds1307_read(rtc_datetime_24h_t *dt)
225 | {
226 | uint8_t rc;
227 | rtc_ds1307_clock_raw_t raw;
228 |
229 | rc = rtc_ds1307_read_clock_raw(&raw);
230 | if(rc) return rc;
231 |
232 | if(raw.control_mode_24h == RTC_DS1307_HOUR_STYLE_12H)
233 | return 100;
234 |
235 | dt->year = (raw.year_1 * 10) + raw.year_0;
236 | dt->month = (raw.month_1 * 10) + raw.month_0;
237 | dt->date = (raw.date_1 * 10) + raw.date_0;
238 | dt->hour = (raw.hour_1 * 10) + raw.hour_0;
239 | dt->minute = (raw.minute_1 * 10) + raw.minute_0;
240 | dt->second = (raw.second_1 * 10) + raw.second_0;
241 | dt->millisecond = 0; /* Not supported by this RTC */
242 | dt->day_of_week = raw.day_of_week;
243 |
244 | dt->year += (dt->year < RTC_DS1307_YEAR_EPOCH)?2000:1900;
245 |
246 | return 0;
247 | }
248 |
249 | uint8_t rtc_ds1307_write(rtc_datetime_24h_t *dt)
250 | {
251 | uint8_t rc;
252 | rtc_ds1307_clock_raw_t raw;
253 | uint16_t tmp_year;
254 |
255 | rc = rtc_ds1307_read_clock_raw(&raw);
256 | if(rc) return rc;
257 |
258 | if(raw.control_mode_24h == RTC_DS1307_HOUR_STYLE_12H)
259 | return 100;
260 |
261 | tmp_year = dt->year - ((dt->year>=2000)?2000:1900);
262 | raw.year_0 = tmp_year % 10;
263 | raw.year_1 = (tmp_year - raw.year_0) / 10;
264 |
265 | raw.month_0 = dt->month % 10;
266 | raw.month_1 = (dt->month - raw.month_0) / 10;
267 |
268 | raw.date_0 = dt->date % 10;
269 | raw.date_1 = (dt->date - raw.date_0) / 10;
270 |
271 | raw.hour_0 = dt->hour % 10;
272 | raw.hour_1 = (dt->hour - raw.hour_0) / 10;
273 |
274 | raw.minute_0 = dt->minute % 10;
275 | raw.minute_1 = (dt->minute - raw.minute_0) / 10;
276 |
277 | raw.second_0 = dt->second % 10;
278 | raw.second_1 = (dt->second - raw.second_0) / 10;
279 |
280 | raw.day_of_week = dt->day_of_week;
281 |
282 | rc = rtc_ds1307_write_clock_raw(&raw);
283 | if(rc) return rc;
284 |
285 | return 0;
286 | }
287 |
288 | rtc_device_t rtc_ds1307 = {
289 | .init = rtc_ds1307_init,
290 | .clock_start = rtc_ds1307_clock_start,
291 | .clock_stop = rtc_ds1307_clock_stop,
292 | .sqw_enable = rtc_ds1307_sqw_enable,
293 | .sqw_disable = rtc_ds1307_sqw_disable,
294 | .sqw_rate = rtc_ds1307_sqw_rate,
295 | .read = rtc_ds1307_read,
296 | .write = rtc_ds1307_write
297 | };
298 |
--------------------------------------------------------------------------------
/rtc/rtc_ds1307.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef RTC_DS1307_H
21 | #define RTC_DS1307_H
22 |
23 | #include
24 | #include
25 |
26 | #include "rtc_types.h"
27 |
28 | #define RTC_DS1307_I2C_ID 0xD0
29 |
30 | #define RTC_DS1307_YEAR_EPOCH 50
31 |
32 | #define RTC_DS1307_CLOCK_HALT 1
33 | #define RTC_DS1307_CLOCK_RUN 0
34 |
35 | #define RTC_DS1307_HOUR_STYLE_24H 0
36 | #define RTC_DS1307_HOUR_STYLE_12H 1
37 |
38 | #define RTC_DS1307_SQW_DISABLE 0
39 | #define RTC_DS1307_SQW_ENABLE 1
40 |
41 | #define RTC_DS1307_SQW_RS1 1
42 | #define RTC_DS1307_SQW_RS0 0
43 |
44 | #define RTC_DS1307_SQW_RATE_1HZ ( 0 )
45 | #define RTC_DS1307_SQW_RATE_4096HZ ( _BV(RTC_DS1307_SQW_RS0) )
46 | #define RTC_DS1307_SQW_RATE_8192HZ ( _BV(RTC_DS1307_SQW_RS1) )
47 | #define RTC_DS1307_SQW_RATE_32768HZ ( _BV(RTC_DS1307_SQW_RS1) | _BV(RTC_DS1307_SQW_RS0) )
48 |
49 | #define RTC_DS1307_CONTROL_CLOCK_HALT 7
50 | #define RTC_DS1307_CONTROL_HOUR_STYLE 6
51 | #define RTC_DS1307_CONTROL_SQW_RATE 0
52 | #define RTC_DS1307_CONTROL_SQW_OUTPUT_FIXED 7
53 | #define RTC_DS1307_CONTROL_SQW_ENABLE 4
54 |
55 | #define RTC_DS1307_REGISTER_CLOCK_HALT 0x00
56 | #define RTC_DS1307_REGISTER_HOUR_STYLE 0x02
57 | #define RTC_DS1307_REGISTER_SQW_RATE 0x07
58 | #define RTC_DS1307_REGISTER_SQW_OUTPUT_FIXED 0x07
59 | #define RTC_DS1307_REGISTER_SQW_ENABLE 0x07
60 |
61 | typedef struct _rtc_ds1307_clock_raw_t
62 | {
63 | uint8_t second_0:4;
64 | uint8_t second_1:3;
65 | uint8_t control_clock_halt:1;
66 | uint8_t minute_0:4;
67 | uint8_t minute_1:3;
68 | uint8_t padding0:1;
69 | uint8_t hour_0:4;
70 | uint8_t hour_1:2;
71 | uint8_t control_mode_24h:1;
72 | uint8_t padding1:1;
73 | uint8_t day_of_week:3;
74 | uint8_t padding2:5;
75 | uint8_t date_0:4;
76 | uint8_t date_1:2;
77 | uint8_t padding3:2;
78 | uint8_t month_0:4;
79 | uint8_t month_1:1;
80 | uint8_t padding4:3;
81 | uint8_t year_0:4;
82 | uint8_t year_1:4;
83 | uint8_t control_rs:2;
84 | uint8_t padding5:2;
85 | uint8_t control_sqwe:1;
86 | uint8_t padding6:2;
87 | uint8_t control_out:1;
88 | } rtc_ds1307_clock_raw_t;
89 |
90 | extern rtc_device_t rtc_ds1307;
91 |
92 | #endif /* RTC_DS1307_H */
93 |
--------------------------------------------------------------------------------
/rtc/rtc_types.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #ifndef RTC_TYPES_H_
21 | #define RTC_TYPES_H_
22 |
23 | #include
24 |
25 | typedef struct _rtc_datetime_24h_t
26 | {
27 | int16_t year;
28 | int8_t month;
29 | int8_t date;
30 | int8_t hour;
31 | int8_t minute;
32 | int8_t second;
33 | int16_t millisecond;
34 | int8_t day_of_week;
35 | } rtc_datetime_24h_t;
36 |
37 | typedef struct _rtc_device_t
38 | {
39 | uint8_t (*init)(void);
40 | uint8_t (*clock_start)(void);
41 | uint8_t (*clock_stop)(void);
42 | uint8_t (*sqw_enable)(void);
43 | uint8_t (*sqw_disable)(void);
44 | uint8_t (*sqw_rate)(uint16_t);
45 | uint8_t (*read)(rtc_datetime_24h_t *);
46 | uint8_t (*write)(rtc_datetime_24h_t *);
47 | } rtc_device_t;
48 |
49 | typedef struct _rtc_dst_date_t
50 | {
51 | int16_t year;
52 | int8_t start_month;
53 | int8_t start_date;
54 | int8_t end_month;
55 | int8_t end_date;
56 | } rtc_dst_date_t;
57 |
58 | #endif /* RTC_TYPES_H_ */
59 |
--------------------------------------------------------------------------------
/rtc_test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | rtc_test
4 |
5 |
6 | i2c
7 | rtc
8 | uart
9 |
10 |
11 |
12 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
13 | clean,full,incremental,
14 |
15 |
16 | ?name?
17 |
18 |
19 |
20 | org.eclipse.cdt.make.core.append_environment
21 | true
22 |
23 |
24 | org.eclipse.cdt.make.core.autoBuildTarget
25 | all
26 |
27 |
28 | org.eclipse.cdt.make.core.buildArguments
29 |
30 |
31 |
32 | org.eclipse.cdt.make.core.buildCommand
33 | make
34 |
35 |
36 | org.eclipse.cdt.make.core.buildLocation
37 | ${workspace_loc:/rtc_i2c/Release}
38 |
39 |
40 | org.eclipse.cdt.make.core.cleanBuildTarget
41 | clean
42 |
43 |
44 | org.eclipse.cdt.make.core.contents
45 | org.eclipse.cdt.make.core.activeConfigSettings
46 |
47 |
48 | org.eclipse.cdt.make.core.enableAutoBuild
49 | false
50 |
51 |
52 | org.eclipse.cdt.make.core.enableCleanBuild
53 | true
54 |
55 |
56 | org.eclipse.cdt.make.core.enableFullBuild
57 | true
58 |
59 |
60 | org.eclipse.cdt.make.core.fullBuildTarget
61 | all
62 |
63 |
64 | org.eclipse.cdt.make.core.stopOnError
65 | true
66 |
67 |
68 | org.eclipse.cdt.make.core.useDefaultBuildCmd
69 | true
70 |
71 |
72 |
73 |
74 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
75 |
76 |
77 |
78 |
79 |
80 | org.eclipse.cdt.core.cnature
81 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
82 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
83 | de.innot.avreclipse.core.avrnature
84 |
85 |
86 |
--------------------------------------------------------------------------------
/rtc_test/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | #Tue Aug 17 18:17:58 PDT 2010
2 | avrtarget/ClockFrequency=8000000
3 | avrtarget/ExtRAMSize=0
4 | avrtarget/ExtendedRAM=false
5 | avrtarget/MCUType=atmega644
6 | avrtarget/UseEEPROM=false
7 | avrtarget/UseExtendedRAMforHeap=true
8 | avrtarget/avrdude/BitBangDelay=
9 | avrtarget/avrdude/Bitclock=10
10 | avrtarget/avrdude/EEPROMFile=
11 | avrtarget/avrdude/EEPROMFromConfig=true
12 | avrtarget/avrdude/FlashFile=
13 | avrtarget/avrdude/FlashFromConfig=true
14 | avrtarget/avrdude/Fuses/ByteValues=194\:25\:255
15 | avrtarget/avrdude/Fuses/FileName=
16 | avrtarget/avrdude/Fuses/MCUid=atmega644p
17 | avrtarget/avrdude/Fuses/UseFile=false
18 | avrtarget/avrdude/Fuses/Write=true
19 | avrtarget/avrdude/Locks/ByteValues=-1
20 | avrtarget/avrdude/Locks/FileName=
21 | avrtarget/avrdude/Locks/MCUid=atmega644p
22 | avrtarget/avrdude/Locks/UseFile=false
23 | avrtarget/avrdude/Locks/Write=false
24 | avrtarget/avrdude/NoChipErase=false
25 | avrtarget/avrdude/NoSigCheck=false
26 | avrtarget/avrdude/NoVerify=false
27 | avrtarget/avrdude/NoWrite=false
28 | avrtarget/avrdude/OtherOptions=
29 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
30 | avrtarget/avrdude/UseCounter=false
31 | avrtarget/avrdude/WriteEEPROM=false
32 | avrtarget/avrdude/WriteFlash=true
33 | avrtarget/perConfig=false
34 | eclipse.preferences.version=1
35 |
--------------------------------------------------------------------------------
/rtc_test/rtc_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | int main(void)
35 | {
36 | uart_t *u0;
37 | uint8_t rc;
38 | rtc_device_t *rtc = &rtc_ds1307;
39 | rtc_datetime_24h_t current_dt, offset_dt;
40 |
41 | _delay_ms(1000);
42 |
43 | u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU));
44 | uart_init_stdout(u0);
45 |
46 | i2c_init();
47 |
48 | DDRC = _BV(PC0) | _BV(PC1);
49 | PORTC = _BV(PC0) | _BV(PC1);
50 |
51 | sei();
52 |
53 | printf("\n\nBooted up!\n");
54 |
55 | rc = rtc_init(rtc);
56 | printf("Inited RTC, rc=%i\n", rc);
57 |
58 | rc = rtc_sqw_rate(rtc, 1);
59 | printf("Set sqw rate, rc=%i\n", rc);
60 |
61 | rc = rtc_sqw_enable(rtc);
62 | printf("Set sqw enable, rc=%i\n", rc);
63 |
64 | rc = rtc_clock_start(rtc);
65 | printf("Started clock, rc=%i\n", rc);
66 |
67 | _delay_ms(1000);
68 |
69 | while(1)
70 | {
71 | rc = rtc_read(rtc, ¤t_dt);
72 |
73 | rtc_offset_time(¤t_dt, &offset_dt, -7);
74 |
75 | printf("rc = %i, %04i-%02i-%02i %02i:%02i:%02i %i offset: %04i-%02i-%02i %02i:%02i:%02i %i\n",
76 | rc,
77 | current_dt.year, current_dt.month, current_dt.date,
78 | current_dt.hour, current_dt.minute, current_dt.second,
79 | current_dt.day_of_week,
80 | offset_dt.year, offset_dt.month, offset_dt.date,
81 | offset_dt.hour, offset_dt.minute, offset_dt.second,
82 | offset_dt.day_of_week
83 | );
84 |
85 | _delay_ms(1000);
86 | }
87 |
88 | return(0);
89 | }
90 |
--------------------------------------------------------------------------------
/uart/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | uart
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 |
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | make
31 |
32 |
33 | org.eclipse.cdt.make.core.buildLocation
34 | ${workspace_loc:/uart/Release}
35 |
36 |
37 | org.eclipse.cdt.make.core.cleanBuildTarget
38 | clean
39 |
40 |
41 | org.eclipse.cdt.make.core.contents
42 | org.eclipse.cdt.make.core.activeConfigSettings
43 |
44 |
45 | org.eclipse.cdt.make.core.enableAutoBuild
46 | false
47 |
48 |
49 | org.eclipse.cdt.make.core.enableCleanBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.enableFullBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.fullBuildTarget
58 | all
59 |
60 |
61 | org.eclipse.cdt.make.core.stopOnError
62 | true
63 |
64 |
65 | org.eclipse.cdt.make.core.useDefaultBuildCmd
66 | true
67 |
68 |
69 |
70 |
71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
72 |
73 |
74 |
75 |
76 |
77 | org.eclipse.cdt.core.cnature
78 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
79 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
80 | de.innot.avreclipse.core.avrnature
81 |
82 |
83 |
--------------------------------------------------------------------------------
/uart/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega644
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/ClockFrequency=8000000
8 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/ExtRAMSize=0
9 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/ExtendedRAM=false
10 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/MCUType=atmega1284p
11 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/UseEEPROM=false
12 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354.1163634307/UseExtendedRAMforHeap=true
13 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/ClockFrequency=8000000
14 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/ExtRAMSize=0
15 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/ExtendedRAM=false
16 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/MCUType=atmega644
17 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/UseEEPROM=false
18 | avrtarget/de.innot.avreclipse.configuration.lib.release.1460611472.2131147354/UseExtendedRAMforHeap=true
19 | avrtarget/perConfig=true
20 | eclipse.preferences.version=1
21 |
--------------------------------------------------------------------------------
/uart/README:
--------------------------------------------------------------------------------
1 | Interrupt-driven UART library with support for multiple UARTs, using ring
2 | buffers for receive/transmit and support for stdout/printf. At compile time,
3 | all UARTs are detected and populated into the uart_descriptions global
4 | structure, which is used by other functions during runtime.
5 |
6 | The core of this library is closely based on Peter Fleury's UART library,
7 | with heavy refactoring, reformatting, and updating.
8 |
9 | This library is based on Peter Fleury's original files with the IDs:
10 | "uart.c,v 1.6.2.1 2007/07/01 11:14:38"
11 | "uart.h,v 1.8.2.1 2007/07/01 11:14:38"
12 |
13 | Peter's copyright is as follows:
14 | Copyright (c) 2006 Peter Fleury http://jump.to/fleury
15 |
16 | DESCRIPTION:
17 | An interrupt is generated when the UART has finished transmitting or
18 | receiving a byte. The interrupt handling routines use circular buffers
19 | for buffering received and transmitted data.
20 |
21 | The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
22 | the buffer size in bytes. Note that these variables must be a
23 | power of 2.
24 |
25 | USAGE:
26 | Refer to the header file uart.h for a description of the routines.
27 | See also example test_uart.c.
28 |
29 | NOTES:
30 | Originally based on Atmel Application Note AVR306.
31 |
--------------------------------------------------------------------------------
/uart/TODO:
--------------------------------------------------------------------------------
1 | Current TODO list is:
2 |
3 | * Ability to shut down a UART after having used it, freeing the buffers
4 | allocated and shutting it down.
5 |
6 | * Ability to temporarily suspend a UART to save power?
7 |
8 | * Ability to toggle an RTS pin for RS485 half-duplex.
9 |
10 | * Test more ATmega MCUs, especially with 2+ UARTs.
11 |
12 | * Optimization of the ISRs to not do string based searches for every call.
13 |
14 | * Add support for the ATxmega MCUs, especially with 4+ UARTs.
--------------------------------------------------------------------------------
/uart/uart.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 | Copyright (c) 2006, Peter Fleury
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 |
19 | */
20 |
21 | #include "uart.h"
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | /*
31 | * Module global variables
32 | */
33 |
34 | uart_instance_t *uart_instances = NULL;
35 | uart_stdout_t uart_stdout;
36 |
37 | #include "uart_quirks.h"
38 |
39 | #if defined(UART0_RXC_INT) && defined(UART0_DRE_INT)
40 | ISR(UART0_RXC_INT) { uart_isr_rxc("0"); }
41 | ISR(UART0_DRE_INT) { uart_isr_dre("0"); }
42 | #endif
43 |
44 | #if defined(USART1_RX_vect)
45 | ISR(USART1_RX_vect) { uart_isr_rxc("1"); }
46 | ISR(USART1_UDRE_vect) { uart_isr_dre("1"); }
47 | #endif
48 |
49 | #if defined(USART2_RX_vect)
50 | ISR(USART2_RX_vect) { uart_isr_rxc("2"); }
51 | ISR(USART2_UDRE_vect) { uart_isr_dre("2"); }
52 | #endif
53 |
54 | #if defined(USART3_RX_vect)
55 | ISR(USART3_RX_vect) { uart_isr_rxc("3"); }
56 | ISR(USART3_UDRE_vect) { uart_isr_dre("3"); }
57 | #endif
58 |
59 |
60 | inline uart_instance_t *uart_instance_add(uart_t *uart)
61 | {
62 | uart_instance_t *instance, *current;
63 |
64 | instance = malloc(sizeof(uart_instance_t));
65 |
66 | if(uart_instances == NULL)
67 | {
68 | uart_instances = instance;
69 | } else {
70 | for(current = uart_instances; current->next; current = current->next) { };
71 | current->next = instance;
72 | }
73 | instance->next = NULL;
74 | instance->uart = uart;
75 |
76 | return uart_instances;
77 | }
78 |
79 | uart_t *uart_by_name(char *name)
80 | {
81 | uart_instance_t *instance;
82 | for(instance=uart_instances; instance; instance = instance->next)
83 | {
84 | if(!(strcmp(instance->uart->description->name, name)))
85 | return instance->uart;
86 | }
87 | return NULL;
88 | }
89 |
90 | uart_description_t *uart_description_by_name(char *name)
91 | {
92 | uart_description_t *d;
93 | for(d=uart_descriptions; d; d++)
94 | {
95 | if(!(strcmp(d->name, name)))
96 | return d;
97 | }
98 | return NULL;
99 | }
100 |
101 | uart_t *uart_init(char *name, unsigned int baudrate)
102 | {
103 | uart_t *uart;
104 | uart_description_t *description;
105 |
106 | description = uart_description_by_name(name);
107 |
108 | uart = malloc(sizeof(uart_t));
109 | uart->tx.buffer = malloc(UART_TX_BUFFER_SIZE);
110 | uart->rx.buffer = malloc(UART_RX_BUFFER_SIZE);
111 | uart->tx.head = 0;
112 | uart->tx.tail = 0;
113 | uart->rx.head = 0;
114 | uart->rx.tail = 0;
115 | uart->rx_callback = NULL;
116 | uart->description = description;
117 |
118 | uart_set_baudrate(uart, baudrate);
119 |
120 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
121 | uart_set_frame_format(uart,
122 | uart->description->format_async
123 | | uart->description->format_8n1);
124 |
125 | /* Enable UART receiver, transmitter, and RX complete interrupt. */
126 | if(uart->description->control_enable)
127 | {
128 | *uart->description->registers.control |= uart->description->control_enable;
129 | }
130 |
131 | uart_instance_add(uart);
132 |
133 | return uart;
134 | }
135 |
136 | void uart_set_baudrate(uart_t *uart, unsigned int baudrate)
137 | {
138 | if( uart->description->status_u2x && (baudrate & UART_BAUD_RATE_2X) )
139 | {
140 | /* Enable 2x speed */
141 | *uart->description->registers.status = uart->description->status_u2x;
142 | }
143 |
144 | baudrate &= ~UART_BAUD_RATE_2X;
145 |
146 | /* Set baud rate */
147 | if(uart->description->registers.baud_h)
148 | {
149 | *uart->description->registers.baud_h = (unsigned char) (baudrate >> 8);
150 | }
151 |
152 | *uart->description->registers.baud_l = (unsigned char) (baudrate & 0x00ff);
153 | }
154 |
155 | void uart_set_frame_format(uart_t *uart, int frame_format)
156 | {
157 | /* TODO: Make this resettable by not just using |= */
158 | *uart->description->registers.format |= frame_format;
159 | }
160 |
161 | void uart_set_rx_callback(uart_t *uart, void (*rx_callback)(uart_t *))
162 | {
163 | uart->rx_callback = rx_callback;
164 | }
165 |
166 | void uart_isr_rxc(char *name)
167 | {
168 | uart_t *uart;
169 | unsigned char tmp_rx_head;
170 | unsigned char data;
171 | unsigned char usr;
172 | unsigned char rx_error;
173 |
174 | uart = uart_by_name(name);
175 |
176 | /* Read UART status register and UART data register */
177 | usr = *uart->description->registers.status;
178 | data = *uart->description->registers.data;
179 |
180 | rx_error = (usr & (uart->description->error_fe | uart->description->error_dor) );
181 |
182 | /* calculate buffer index */
183 | tmp_rx_head = ( uart->rx.head + 1) & UART_RX_BUFFER_MASK;
184 |
185 | if ( tmp_rx_head == uart->rx.tail )
186 | {
187 | /* error: receive buffer overflow */
188 | rx_error = UART_BUFFER_OVERFLOW >> 8;
189 | } else {
190 | /* store new index */
191 | uart->rx.head = tmp_rx_head;
192 | /* store received data in buffer */
193 | uart->rx.buffer[tmp_rx_head] = data;
194 | }
195 | uart->rx.error = rx_error;
196 |
197 | if(uart->rx_callback)
198 | uart->rx_callback(uart);
199 | }
200 |
201 | void uart_isr_dre(char *name)
202 | {
203 | uart_t *uart;
204 | unsigned char tmp_tx_tail;
205 |
206 | uart = uart_by_name(name);
207 |
208 | if ( uart->tx.head != uart->tx.tail)
209 | {
210 | /* Calculate and store new buffer index */
211 | tmp_tx_tail = (uart->tx.tail + 1) & UART_TX_BUFFER_MASK;
212 | uart->tx.tail = tmp_tx_tail;
213 | /* Get one byte from buffer and write it to UART */
214 | *uart->description->registers.data = uart->tx.buffer[tmp_tx_tail]; /* start transmission */
215 | } else {
216 | /* TX buffer empty, disable UDRE interrupt */
217 | *uart->description->registers.control &= ~uart->description->control_udrie;
218 | }
219 | }
220 |
221 | unsigned char uart_data_ready(uart_t *uart)
222 | {
223 | if (uart->rx.head == uart->rx.tail)
224 | return 0;
225 | return 1;
226 | }
227 |
228 | unsigned int uart_getc(uart_t *uart)
229 | {
230 | unsigned char tmp_rx_tail, data;
231 |
232 | if (uart_data_ready(uart) == 0)
233 | {
234 | return UART_NO_DATA; /* no data available */
235 | }
236 |
237 | /* Calculate new tail of receive buffer */
238 | tmp_rx_tail = (uart->rx.tail + 1) & UART_RX_BUFFER_MASK;
239 |
240 | /* Get data from new tail of receive buffer */
241 | data = uart->rx.buffer[tmp_rx_tail];
242 |
243 | /* Adjust tail pointer, allowing writes into buffer to unblock */
244 | uart->rx.tail = tmp_rx_tail;
245 |
246 | return (uart->rx.error << 8) + data;
247 | }
248 |
249 | void uart_putc(uart_t *uart, unsigned char data)
250 | {
251 | unsigned char tmp_tx_head;
252 |
253 | tmp_tx_head = (uart->tx.head + 1) & UART_TX_BUFFER_MASK;
254 |
255 | while ( tmp_tx_head == uart->tx.tail ){
256 | /* Wait for free space in buffer. */
257 | }
258 |
259 | uart->tx.buffer[tmp_tx_head] = data;
260 | uart->tx.head = tmp_tx_head;
261 |
262 | /* enable UDRE interrupt */
263 | *uart->description->registers.control |= uart->description->control_udrie;
264 | }
265 |
266 | void uart_puts(uart_t *uart, const char *s)
267 | {
268 | while (*s)
269 | uart_putc(uart, *s++);
270 | }
271 |
272 | void uart_puts_P(uart_t *uart, const char *progmem_s)
273 | {
274 | register char c;
275 |
276 | while ( (c = pgm_read_byte(progmem_s++)) )
277 | uart_putc(uart, c);
278 | }
279 |
280 | void uart_init_stdout(uart_t *uart)
281 | {
282 | uart_stdout.uart = uart;
283 | fdev_setup_stream(&uart_stdout.file, uart_putchar, NULL, _FDEV_SETUP_WRITE);
284 | stdout = &uart_stdout.file;
285 | stderr = &uart_stdout.file;
286 | }
287 |
288 | int uart_putchar(char c, FILE *stream)
289 | {
290 | if(c == '\n')
291 | uart_putchar('\r', stream);
292 |
293 | uart_putc(uart_stdout.uart, c);
294 |
295 | return 0;
296 | }
297 |
--------------------------------------------------------------------------------
/uart/uart.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 | Copyright (c) 2006, Peter Fleury
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 |
19 | */
20 |
21 | /**
22 | * @defgroup pfleury_uart UART Library
23 | * @code #include @endcode
24 | *
25 | * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
26 | *
27 | * This library can be used to transmit and receive data through the built in UART.
28 | *
29 | * An interrupt is generated when the UART has finished transmitting or
30 | * receiving a byte. The interrupt handling routines use circular buffers
31 | * for buffering received and transmitted data.
32 | *
33 | * @note Based on Atmel Application Note AVR306
34 | * @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
35 | */
36 |
37 | /**@{*/
38 |
39 | #ifndef UART_H
40 | #define UART_H
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 |
47 | #include "uart_description.h"
48 |
49 | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
50 | #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
51 | #endif
52 |
53 | typedef struct _uart_buffer_t
54 | {
55 | volatile unsigned char *buffer;
56 | volatile unsigned char head;
57 | volatile unsigned char tail;
58 | volatile unsigned char error;
59 | } uart_buffer_t;
60 |
61 |
62 | typedef struct _uart_t
63 | {
64 | uart_description_t *description;
65 | uart_buffer_t tx;
66 | uart_buffer_t rx;
67 | void (*rx_callback)(struct _uart_t *);
68 | } uart_t;
69 |
70 | typedef struct _uart_stdout_t
71 | {
72 | uart_t *uart;
73 | FILE file;
74 | } uart_stdout_t;
75 |
76 | typedef struct _uart_instance_t
77 | {
78 | uart_t *uart;
79 | struct _uart_instance_t *next;
80 | } uart_instance_t;
81 |
82 | extern uart_instance_t *uart_instances;
83 | extern uart_stdout_t uart_stdout;
84 |
85 | extern uart_t *uart_by_name(char *name);
86 | extern uart_description_t *uart_description_by_name(char *name);
87 |
88 | extern void uart_init_stdout(uart_t *uart);
89 | extern int uart_putchar(char c, FILE *stream);
90 |
91 | extern uart_t *uart_init(char *name, unsigned int baudrate);
92 | extern void uart_set_baudrate(uart_t *uart, unsigned int baudrate);
93 | extern void uart_set_frame_format(uart_t *uart, int frame_format);
94 | extern void uart_set_rx_callback(uart_t *uart, void (*rx_callback)(uart_t *));
95 | extern void uart_isr_rxc(char *name);
96 | extern void uart_isr_dre(char *name);
97 | extern unsigned char uart_data_ready(uart_t *uart);
98 | extern unsigned int uart_getc(uart_t *uart);
99 | extern void uart_putc(uart_t *uart, unsigned char data);
100 | extern void uart_puts(uart_t *uart, const char *s);
101 | extern void uart_puts_P(uart_t *uart, const char *progmem_s);
102 |
103 | /*
104 | ** constants and macros
105 | */
106 |
107 | /** The high bit in the baud rate is used to indicate that double speed
108 | * should be used when initializing the UART.
109 | */
110 | #define UART_BAUD_RATE_2X 0x8000
111 |
112 | /** @brief UART Baudrate Expression
113 | * @param xtalcpu system clock in Mhz, e.g. 4000000L for 4Mhz
114 | * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
115 | */
116 | #define UART_BAUD_SELECT(baud_rate, xtal_cpu) \
117 | ((xtal_cpu) / ((baud_rate) * 16l) - 1)
118 |
119 | /** @brief UART Baudrate Expression for ATmega double speed mode
120 | * @param xtalcpu system clock in Mhz, e.g. 4000000L for 4Mhz
121 | * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
122 | */
123 | #define UART_BAUD_SELECT_DOUBLE_SPEED(baud_rate, xtal_cpu) \
124 | (((xtal_cpu) / ((baud_rate) * 8l) - 1) | UART_BAUD_RATE_2X)
125 |
126 |
127 | /** Default size of the circular receive buffers, must be power of 2 */
128 | #define UART_RX_BUFFER_SIZE 32
129 |
130 | /** Default size of the circular transmit buffers, must be power of 2 */
131 | #define UART_TX_BUFFER_SIZE 32
132 |
133 | /* size of RX/TX buffers */
134 | #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
135 | #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
136 |
137 | #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
138 | #error "UART_RX_BUFFER_SIZE must be a power of two!"
139 | #endif
140 | #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
141 | #error "UART_TX_BUFFER_SIZE must be a power of two!"
142 | #endif
143 |
144 | /* Test if the size of the circular buffers fits into SRAM */
145 | #if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
146 | #error "Size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
147 | #endif
148 |
149 | /*
150 | ** High byte error return code of uart_getc()
151 | */
152 | #define UART_FRAME_ERROR 0x0800 /* Framing Error by UART */
153 | #define UART_OVERRUN_ERROR 0x0400 /* Overrun condition by UART */
154 | #define UART_BUFFER_OVERFLOW 0x0200 /* Receive ringbuffer overflow */
155 | #define UART_NO_DATA 0x0100 /* No receive data available */
156 |
157 | /**@}*/
158 |
159 | #endif // UART_H
160 |
161 |
--------------------------------------------------------------------------------
/uart/uart_description.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include "uart_description.h"
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "uart_quirks.h"
27 |
28 | #define UARTX_DESCRIPTION(name, suffix) \
29 | { name, \
30 | { \
31 | &UCSR##suffix##A, \
32 | &UCSR##suffix##B, \
33 | &UCSR##suffix##C, \
34 | &UDR##suffix, \
35 | &UBRR##suffix##H, \
36 | &UBRR##suffix##L \
37 | }, \
38 | (_BV(RXCIE##suffix) | _BV(RXEN##suffix)| _BV(TXEN##suffix)), \
39 | _BV(UDRIE##suffix), \
40 | _BV(U2X##suffix), \
41 | 0, \
42 | (_BV(UCSZ##suffix##1) | _BV(UCSZ##suffix##0)), \
43 | _BV(FE##suffix), \
44 | _BV(DOR##suffix) \
45 | }
46 |
47 |
48 | uart_description_t uart_descriptions[] = {
49 |
50 | #if defined(UART0_STATUS)
51 | { "0",
52 | {
53 | &UART0_STATUS,
54 | &UART0_CONTROL,
55 | &UART0_FORMAT,
56 | &UART0_DATA,
57 | &UART0_UBRRH,
58 | &UART0_UBRRL
59 | },
60 | UART0_ENABLE,
61 | UART0_UDRIE,
62 | UART0_U2X,
63 | 0,
64 | UART0_FORMAT_8N1,
65 | UART0_ERROR_FE,
66 | UART0_ERROR_DOR
67 | },
68 | #endif
69 |
70 | #if defined(UDRIE1)
71 | UARTX_DESCRIPTION("1", 1),
72 | #endif
73 |
74 | #if defined(UDRIE2)
75 | UARTX_DESCRIPTION("2", 2),
76 | #endif
77 |
78 | #if defined(UDRIE3)
79 | UARTX_DESCRIPTION("3", 3),
80 | #endif
81 |
82 | { NULL, {NULL, NULL, NULL, NULL, NULL, NULL}, 0, 0, 0, 0, 0, 0 }
83 | };
84 |
85 |
--------------------------------------------------------------------------------
/uart/uart_description.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 | #ifndef UART_DESCRIPTION_H
20 | #define UART_DESCRIPTION_H
21 |
22 | #include
23 | #include
24 |
25 | typedef struct _uart_registers_t
26 | {
27 | volatile uint8_t *status;
28 | volatile uint8_t *control;
29 | volatile uint8_t *format;
30 | volatile uint8_t *data;
31 | volatile uint8_t *baud_h;
32 | volatile uint8_t *baud_l;
33 | } uart_registers_t;
34 |
35 | typedef struct _uart_description_t
36 | {
37 | char *name;
38 | uart_registers_t registers;
39 | uint8_t control_enable;
40 | uint8_t control_udrie;
41 | uint8_t status_u2x;
42 | uint8_t format_async;
43 | uint8_t format_8n1;
44 | uint8_t error_fe;
45 | uint8_t error_dor;
46 | } uart_description_t;
47 |
48 |
49 | extern uart_description_t uart_descriptions[];
50 |
51 | #endif /* UART_DESCRIPTION_H */
52 |
--------------------------------------------------------------------------------
/uart/uart_quirks.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 | Copyright (c) 2006, Peter Fleury
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 |
19 | */
20 |
21 | #ifndef UART_QUIRKS_H
22 | #define UART_QUIRKS_H
23 |
24 | #include
25 |
26 | /*
27 | * Old AVR AT90 classic or ATmega103 with one UART.
28 | * - Status/Control Registers: Split USR/UCR
29 | * - Numeric Suffixes on Regs: No
30 | * - Numeric Suffixes on ISRs: No
31 | */
32 | #if defined(__AVR_AT90S2313__) \
33 | || defined(__AVR_AT90S4414__) \
34 | || defined(__AVR_AT90S4434__) \
35 | || defined(__AVR_AT90S8515__) \
36 | || defined(__AVR_AT90S8535__) \
37 | || defined(__AVR_ATmega103__)
38 |
39 | #define UART0_PRESENT 1
40 | #define UART0_RXC_INT UART_RX_vect
41 | #define UART0_TXC_INT UART_TX_vect
42 | #define UART0_DRE_INT UART_UDRE_vect
43 | #define UART0_STATUS USR
44 | #define UART0_CONTROL UCR
45 | #define UART0_DATA UDR
46 | #define UART0_UBRRL UBRR
47 | #undef UART0_UBRRH
48 | #define UART0_UDRIE _BV(UDRIE)
49 | #undef UART0_U2X
50 | #undef UART0_ENABLE
51 | #define UART0_FORMAT_8N1 (_BV(UCSZ01) | _BV(UCSZ00))
52 | #define UART0_ERROR_FE _BV(FE)
53 | #define UART0_ERROR_DOR _BV(DOR)
54 |
55 | /*
56 | * Old AVR AT90 classic with one UART.
57 | * - Status/Control Registers: Combined A/B
58 | * - Numeric Suffixes on Regs: No
59 | * - Numeric Suffixes on ISRs: No
60 | */
61 | #elif defined(__AVR_AT90S2333__) \
62 | || defined(__AVR_AT90S4433__)
63 |
64 | #define UART0_RXC_INT UART_RX_vect
65 | #define UART0_TXC_INT UART_TX_vect
66 | #define UART0_DRE_INT UART_UDRE_vect
67 | #define UART0_STATUS UCSRA
68 | #define UART0_CONTROL UCSRB
69 | #define UART0_FORMAT UCSRC
70 | #define UART0_DATA UDR
71 | #define UART0_UBRRL UBRR
72 | #undef UART0_UBRRH
73 | #define UART0_UDRIE _BV(UDRIE)
74 | #undef UART0_U2X
75 | #undef UART0_ENABLE
76 | #define UART0_FORMAT_8N1 (_BV(UCSZ1) | _BV(UCSZ0))
77 | #define UART0_ERROR_FE _BV(FE)
78 | #define UART0_ERROR_DOR _BV(DOR)
79 |
80 | /* ATmega with one UART/USART
81 | * - Status/Control Registers: Combined A/B
82 | * - Numeric Suffixes on Regs: No
83 | * - Numeric Suffixes on ISRs: No
84 | */
85 | #elif defined(__AVR_ATmega8__) \
86 | || defined(__AVR_ATmega16__) \
87 | || defined(__AVR_ATmega32__) \
88 | || defined(__AVR_ATmega323__) \
89 | || defined(__AVR_ATmega8515__) \
90 | || defined(__AVR_ATmega8535__) \
91 | || defined(__AVR_ATtiny2313__) \
92 | || defined(__AVR_ATmega163__) \
93 | || defined(__AVR_ATmega169__)
94 |
95 | #undef UART0_RXC_INT
96 | #undef UART0_TXC_INT
97 | #undef UART0_DRE_INT
98 | #define UART0_STATUS UCSRA
99 | #define UART0_CONTROL UCSRB
100 | #define UART0_FORMAT UCSRC
101 | #define UART0_DATA UDR
102 | #if defined(UBRRHI)
103 | /* This is a UART, not a USART */
104 | #define UART0_UBRRL UBRR
105 | #define UART0_UBRRH UBRRHI
106 | #else
107 | #define UART0_UBRRL UBRRL
108 | #define UART0_UBRRH UBRRH
109 | #endif
110 | #define UART0_UDRIE _BV(UDRIE)
111 | #define UART0_U2X _BV(U2X)
112 | #define UART0_ENABLE (_BV(RXCIE) | _BV(RXEN)| _BV(TXEN))
113 | #define UART0_FORMAT_8N1 (_BV(UCSZ1) | _BV(UCSZ0))
114 | #define UART0_ERROR_FE _BV(FE)
115 | #define UART0_ERROR_DOR _BV(DOR)
116 |
117 | /* ATmega with one USART
118 | * - Status/Control Registers: Combined A/B
119 | * - Numeric Suffixes on Regs: Yes
120 | * - Numeric Suffixes on ISRs: Yes
121 | */
122 | #elif defined(__AVR_ATmega48__) \
123 | || defined(__AVR_ATmega88__) \
124 | || defined(__AVR_ATmega168__) \
125 | || defined(__AVR_ATmega329__) \
126 | || defined(__AVR_ATmega3290__) \
127 | || defined(__AVR_ATmega649__) \
128 | || defined(__AVR_ATmega6490__) \
129 | || defined(__AVR_ATmega325__) \
130 | || defined(__AVR_ATmega3250__) \
131 | || defined(__AVR_ATmega645__) \
132 | || defined(__AVR_ATmega6450__) \
133 | || defined(__AVR_ATmega644__)
134 |
135 | #undef UART0_RXC_INT
136 | #undef UART0_TXC_INT
137 | #undef UART0_DRE_INT
138 | #define UART0_STATUS UCSR0A
139 | #define UART0_CONTROL UCSR0B
140 | #define UART0_FORMAT UCSR0C
141 | #define UART0_DATA UDR0
142 | #define UART0_UBRRL UBRR0L
143 | #define UART0_UBRRH UBRR0H
144 | #define UART0_UDRIE _BV(UDRIE0)
145 | #define UART0_U2X _BV(U2X0)
146 | #define UART0_ENABLE (_BV(RXCIE0) | _BV(RXEN0)| _BV(TXEN0))
147 | #define UART0_FORMAT_8N1 (_BV(UCSZ01) | _BV(UCSZ00))
148 | #define UART0_ERROR_FE _BV(FE0)
149 | #define UART0_ERROR_DOR _BV(DOR0)
150 |
151 | /* ATmega with two USART */
152 | #elif defined(__AVR_ATmega162__) \
153 | || defined(__AVR_ATmega64__) \
154 | || defined(__AVR_ATmega128__) \
155 | || defined(__AVR_ATmega2560__) \
156 | || defined(__AVR_ATmega1280__) \
157 | || defined(__AVR_ATmega640__) \
158 | || defined(__AVR_ATmega164P__) \
159 | || defined(__AVR_ATmega324P__) \
160 | || defined(__AVR_ATmega644P__) \
161 | || defined(__AVR_ATmega1284P__)
162 |
163 | #undef UART0_RXC_INT
164 | #undef UART0_TXC_INT
165 | #undef UART0_DRE_INT
166 | #define UART0_STATUS UCSR0A
167 | #define UART0_CONTROL UCSR0B
168 | #define UART0_FORMAT UCSR0C
169 | #define UART0_DATA UDR0
170 | #define UART0_UBRRL UBRR0L
171 | #define UART0_UBRRH UBRR0H
172 | #define UART0_UDRIE _BV(UDRIE0)
173 | #define UART0_U2X _BV(U2X0)
174 | #define UART0_ENABLE (_BV(RXCIE0) | _BV(RXEN0)| _BV(TXEN0))
175 | #define UART0_FORMAT_8N1 (_BV(UCSZ01) | _BV(UCSZ00))
176 | #define UART0_ERROR_FE _BV(FE0)
177 | #define UART0_ERROR_DOR _BV(DOR0)
178 |
179 | #else
180 | #error "No UART definition for MCU available"
181 | #endif
182 |
183 | #if !defined(USART0_RXC_INT)
184 | #if defined(USART0_RX_vect)
185 | #define UART0_RXC_INT USART0_RX_vect
186 | #elif defined(USART_RX_vect)
187 | #define UART0_RXC_INT USART_RX_vect
188 | #elif defined(UART0_RXC_vect)
189 | #define UART0_RXC_INT USART0_RXC_vect
190 | #elif defined(UART_RXC_vect)
191 | #define UART0_RXC_INT USART_RXC_vect
192 | #else
193 | #error "Couldn't find a usable interrupt vector for UART0_RXC_INT!"
194 | #endif
195 | #endif
196 |
197 | #if !defined(USART0_TXC_INT)
198 | #if defined(USART0_TX_vect)
199 | #define UART0_TXC_INT USART0_TX_vect
200 | #elif defined(USART_TX_vect)
201 | #define UART0_TXC_INT USART_TX_vect
202 | #elif defined(UART0_TXC_vect)
203 | #define UART0_TXC_INT USART0_TXC_vect
204 | #elif defined(UART_TXC_vect)
205 | #define UART0_TXC_INT USART_TXC_vect
206 | #else
207 | #error "Couldn't find a usable interrupt vector for UART0_TXC_INT!"
208 | #endif
209 | #endif
210 |
211 | #if !defined(USART0_DRE_INT)
212 | #if defined(USART0_UDRE_vect)
213 | #define UART0_DRE_INT USART0_UDRE_vect
214 | #elif defined(USART_UDRE_vect)
215 | #define UART0_DRE_INT USART_UDRE_vect
216 | #else
217 | #error "Couldn't find a usable interrupt vector for UART0_DRE_INT!"
218 | #endif
219 | #endif
220 |
221 | #endif /* UART_QUIRKS_H */
222 |
--------------------------------------------------------------------------------
/uart_test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | uart_test
4 |
5 |
6 | uart
7 |
8 |
9 |
10 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
11 | clean,full,incremental,
12 |
13 |
14 | ?name?
15 |
16 |
17 |
18 | org.eclipse.cdt.make.core.append_environment
19 | true
20 |
21 |
22 | org.eclipse.cdt.make.core.autoBuildTarget
23 | all
24 |
25 |
26 | org.eclipse.cdt.make.core.buildArguments
27 |
28 |
29 |
30 | org.eclipse.cdt.make.core.buildCommand
31 | make
32 |
33 |
34 | org.eclipse.cdt.make.core.buildLocation
35 | ${workspace_loc:/uart_test/Release}
36 |
37 |
38 | org.eclipse.cdt.make.core.cleanBuildTarget
39 | clean
40 |
41 |
42 | org.eclipse.cdt.make.core.contents
43 | org.eclipse.cdt.make.core.activeConfigSettings
44 |
45 |
46 | org.eclipse.cdt.make.core.enableAutoBuild
47 | false
48 |
49 |
50 | org.eclipse.cdt.make.core.enableCleanBuild
51 | true
52 |
53 |
54 | org.eclipse.cdt.make.core.enableFullBuild
55 | true
56 |
57 |
58 | org.eclipse.cdt.make.core.fullBuildTarget
59 | all
60 |
61 |
62 | org.eclipse.cdt.make.core.stopOnError
63 | true
64 |
65 |
66 | org.eclipse.cdt.make.core.useDefaultBuildCmd
67 | true
68 |
69 |
70 |
71 |
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
73 |
74 |
75 |
76 |
77 |
78 | org.eclipse.cdt.core.cnature
79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
81 | de.innot.avreclipse.core.avrnature
82 |
83 |
84 |
--------------------------------------------------------------------------------
/uart_test/.settings/de.innot.avreclipse.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=8000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega1284p
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/Fuses/ByteValues=194\:217\:255
14 | avrtarget/avrdude/Fuses/FileName=
15 | avrtarget/avrdude/Fuses/MCUid=atmega644
16 | avrtarget/avrdude/Fuses/UseFile=false
17 | avrtarget/avrdude/Fuses/Write=true
18 | avrtarget/avrdude/NoChipErase=false
19 | avrtarget/avrdude/NoSigCheck=false
20 | avrtarget/avrdude/NoVerify=false
21 | avrtarget/avrdude/NoWrite=false
22 | avrtarget/avrdude/OtherOptions=
23 | avrtarget/avrdude/ProgrammerID=programmerconfig.1
24 | avrtarget/avrdude/UseCounter=false
25 | avrtarget/avrdude/WriteEEPROM=false
26 | avrtarget/avrdude/WriteFlash=true
27 | avrtarget/perConfig=false
28 | eclipse.preferences.version=1
29 |
--------------------------------------------------------------------------------
/uart_test/uart_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Jeremy Cole
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 |
31 | void uart_dump()
32 | {
33 | uart_description_t *d;
34 | for(d=uart_descriptions; d->name; d++)
35 | {
36 | printf("UART: %s\n", d->name);
37 | printf(" status: %02x u2x: %02x\n",
38 | (unsigned int)d->registers.status,
39 | d->status_u2x);
40 | printf(" control: %02x enable: %02x udrie: %02x\n",
41 | (unsigned int)d->registers.control,
42 | d->control_enable,
43 | d->control_udrie);
44 | printf(" format: %02x 8n1: %02x\n",
45 | (unsigned int)d->registers.format,
46 | d->format_8n1);
47 | printf(" data: %02x\n", (unsigned int)d->registers.data);
48 | printf(" baud_h: %02x\n", (unsigned int)d->registers.baud_h);
49 | printf(" baud_l: %02x\n", (unsigned int)d->registers.baud_l);
50 | printf("\n");
51 | }
52 | }
53 |
54 | int main(void)
55 | {
56 | uart_t *u0;
57 | //uart_t *u1;
58 | _delay_ms(1000);
59 |
60 | u0 = uart_init("0", UART_BAUD_SELECT(9600, F_CPU));
61 | //u1 = uart_init("1", 0);
62 | uart_init_stdout(u0);
63 |
64 | sei();
65 |
66 | uart_puts(u0, "\r\n\r\nBooted up!\r\n");
67 |
68 | uart_dump();
69 |
70 | while(1)
71 | {
72 | uart_puts(u0, "Test on UART 0!\r\n");
73 | //uart_puts(u1, "Test on UART 1!\r\n");
74 | _delay_ms(100);
75 | }
76 |
77 | return(0);
78 | }
79 |
--------------------------------------------------------------------------------