diff options
Diffstat (limited to 'drivers/avr')
-rw-r--r-- | drivers/avr/analog.c | 53 | ||||
-rw-r--r-- | drivers/avr/analog.h | 26 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/apa102.c | 147 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/apa102.h | 5 | ||||
-rw-r--r-- | drivers/avr/glcdfont.c | 280 | ||||
-rw-r--r-- | drivers/avr/hd44780.c | 510 | ||||
-rw-r--r-- | drivers/avr/hd44780.h | 303 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/i2c_master.c | 260 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/i2c_master.h | 12 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/i2c_slave.c | 18 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/avr/i2c_slave.h | 2 | ||||
-rw-r--r-- | drivers/avr/pro_micro.h | 270 | ||||
-rw-r--r-- | drivers/avr/ssd1306.c | 427 | ||||
-rw-r--r-- | drivers/avr/ssd1306.h | 84 | ||||
-rw-r--r-- | drivers/avr/ws2812.c | 384 | ||||
-rw-r--r-- | drivers/avr/ws2812.h | 17 |
16 files changed, 1195 insertions, 1603 deletions
diff --git a/drivers/avr/analog.c b/drivers/avr/analog.c index 1ec38df75..1a8da4261 100644 --- a/drivers/avr/analog.c +++ b/drivers/avr/analog.c | |||
@@ -21,49 +21,38 @@ | |||
21 | #include <stdint.h> | 21 | #include <stdint.h> |
22 | #include "analog.h" | 22 | #include "analog.h" |
23 | 23 | ||
24 | static uint8_t aref = (1 << REFS0); // default to AREF = Vcc | ||
24 | 25 | ||
25 | static uint8_t aref = (1<<REFS0); // default to AREF = Vcc | 26 | void analogReference(uint8_t mode) { aref = mode & 0xC0; } |
26 | |||
27 | |||
28 | void analogReference(uint8_t mode) | ||
29 | { | ||
30 | aref = mode & 0xC0; | ||
31 | } | ||
32 | |||
33 | 27 | ||
34 | // Arduino compatible pin input | 28 | // Arduino compatible pin input |
35 | int16_t analogRead(uint8_t pin) | 29 | int16_t analogRead(uint8_t pin) { |
36 | { | ||
37 | #if defined(__AVR_ATmega32U4__) | 30 | #if defined(__AVR_ATmega32U4__) |
38 | static const uint8_t PROGMEM pin_to_mux[] = { | 31 | static const uint8_t PROGMEM pin_to_mux[] = {0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20}; |
39 | 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, | 32 | if (pin >= 12) return 0; |
40 | 0x25, 0x24, 0x23, 0x22, 0x21, 0x20}; | 33 | return adc_read(pgm_read_byte(pin_to_mux + pin)); |
41 | if (pin >= 12) return 0; | ||
42 | return adc_read(pgm_read_byte(pin_to_mux + pin)); | ||
43 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | 34 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) |
44 | if (pin >= 8) return 0; | 35 | if (pin >= 8) return 0; |
45 | return adc_read(pin); | 36 | return adc_read(pin); |
46 | #else | 37 | #else |
47 | return 0; | 38 | return 0; |
48 | #endif | 39 | #endif |
49 | } | 40 | } |
50 | 41 | ||
51 | // Mux input | 42 | // Mux input |
52 | int16_t adc_read(uint8_t mux) | 43 | int16_t adc_read(uint8_t mux) { |
53 | { | ||
54 | #if defined(__AVR_AT90USB162__) | 44 | #if defined(__AVR_AT90USB162__) |
55 | return 0; | 45 | return 0; |
56 | #else | 46 | #else |
57 | uint8_t low; | 47 | uint8_t low; |
58 | 48 | ||
59 | ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC | 49 | ADCSRA = (1 << ADEN) | ADC_PRESCALER; // enable ADC |
60 | ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode | 50 | ADCSRB = (1 << ADHSM) | (mux & 0x20); // high speed mode |
61 | ADMUX = aref | (mux & 0x1F); // configure mux input | 51 | ADMUX = aref | (mux & 0x1F); // configure mux input |
62 | ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion | 52 | ADCSRA = (1 << ADEN) | ADC_PRESCALER | (1 << ADSC); // start the conversion |
63 | while (ADCSRA & (1<<ADSC)) ; // wait for result | 53 | while (ADCSRA & (1 << ADSC)) |
64 | low = ADCL; // must read LSB first | 54 | ; // wait for result |
65 | return (ADCH << 8) | low; // must read MSB only once! | 55 | low = ADCL; // must read LSB first |
56 | return (ADCH << 8) | low; // must read MSB only once! | ||
66 | #endif | 57 | #endif |
67 | } | 58 | } |
68 | |||
69 | |||
diff --git a/drivers/avr/analog.h b/drivers/avr/analog.h index 8d93de7dc..32452a1ec 100644 --- a/drivers/avr/analog.h +++ b/drivers/avr/analog.h | |||
@@ -19,34 +19,34 @@ | |||
19 | 19 | ||
20 | #include <stdint.h> | 20 | #include <stdint.h> |
21 | 21 | ||
22 | void analogReference(uint8_t mode); | 22 | void analogReference(uint8_t mode); |
23 | int16_t analogRead(uint8_t pin); | 23 | int16_t analogRead(uint8_t pin); |
24 | int16_t adc_read(uint8_t mux); | 24 | int16_t adc_read(uint8_t mux); |
25 | 25 | ||
26 | #define ADC_REF_POWER (1<<REFS0) | 26 | #define ADC_REF_POWER (1 << REFS0) |
27 | #define ADC_REF_INTERNAL ((1<<REFS1) | (1<<REFS0)) | 27 | #define ADC_REF_INTERNAL ((1 << REFS1) | (1 << REFS0)) |
28 | #define ADC_REF_EXTERNAL (0) | 28 | #define ADC_REF_EXTERNAL (0) |
29 | 29 | ||
30 | // These prescaler values are for high speed mode, ADHSM = 1 | 30 | // These prescaler values are for high speed mode, ADHSM = 1 |
31 | #if F_CPU == 16000000L | 31 | #if F_CPU == 16000000L |
32 | #define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS1)) | 32 | # define ADC_PRESCALER ((1 << ADPS2) | (1 << ADPS1)) |
33 | #elif F_CPU == 8000000L | 33 | #elif F_CPU == 8000000L |
34 | #define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS0)) | 34 | # define ADC_PRESCALER ((1 << ADPS2) | (1 << ADPS0)) |
35 | #elif F_CPU == 4000000L | 35 | #elif F_CPU == 4000000L |
36 | #define ADC_PRESCALER ((1<<ADPS2)) | 36 | # define ADC_PRESCALER ((1 << ADPS2)) |
37 | #elif F_CPU == 2000000L | 37 | #elif F_CPU == 2000000L |
38 | #define ADC_PRESCALER ((1<<ADPS1) | (1<<ADPS0)) | 38 | # define ADC_PRESCALER ((1 << ADPS1) | (1 << ADPS0)) |
39 | #elif F_CPU == 1000000L | 39 | #elif F_CPU == 1000000L |
40 | #define ADC_PRESCALER ((1<<ADPS1)) | 40 | # define ADC_PRESCALER ((1 << ADPS1)) |
41 | #else | 41 | #else |
42 | #define ADC_PRESCALER ((1<<ADPS0)) | 42 | # define ADC_PRESCALER ((1 << ADPS0)) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | // some avr-libc versions do not properly define ADHSM | 45 | // some avr-libc versions do not properly define ADHSM |
46 | #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | 46 | #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) |
47 | #if !defined(ADHSM) | 47 | # if !defined(ADHSM) |
48 | #define ADHSM (7) | 48 | # define ADHSM (7) |
49 | #endif | 49 | # endif |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #endif | 52 | #endif |
diff --git a/drivers/avr/apa102.c b/drivers/avr/apa102.c index 55a0d5777..f4d97a158 100755..100644 --- a/drivers/avr/apa102.c +++ b/drivers/avr/apa102.c | |||
@@ -1,24 +1,24 @@ | |||
1 | /* | 1 | /* |
2 | * APA102 lib V1.0a | 2 | * APA102 lib V1.0a |
3 | * | 3 | * |
4 | * Controls APA102 RGB-LEDs | 4 | * Controls APA102 RGB-LEDs |
5 | * Author: Mikkel (Duckle29 on github) | 5 | * Author: Mikkel (Duckle29 on github) |
6 | * | 6 | * |
7 | * Dec 22th, 2017 v1.0a Initial Version | 7 | * Dec 22th, 2017 v1.0a Initial Version |
8 | * | 8 | * |
9 | * This program is free software: you can redistribute it and/or modify | 9 | * This program is free software: you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation, either version 2 of the License, or | 11 | * the Free Software Foundation, either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include "apa102.h" | 23 | #include "apa102.h" |
24 | #include <avr/interrupt.h> | 24 | #include <avr/interrupt.h> |
@@ -27,75 +27,70 @@ | |||
27 | #include "debug.h" | 27 | #include "debug.h" |
28 | 28 | ||
29 | // Setleds for standard RGB | 29 | // Setleds for standard RGB |
30 | void inline apa102_setleds(LED_TYPE *ledarray, uint16_t leds){ | 30 | void inline apa102_setleds(LED_TYPE *ledarray, uint16_t leds) { apa102_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF), _BV(RGB_CLK_PIN & 0xF)); } |
31 | apa102_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF), _BV(RGB_CLK_PIN & 0xF)); | ||
32 | } | ||
33 | 31 | ||
34 | void static inline apa102_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask_DI, uint8_t pinmask_CLK){ | 32 | void static inline apa102_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask_DI, uint8_t pinmask_CLK) { |
35 | pinMode(RGB_DI_PIN, PinDirectionOutput); | 33 | pinMode(RGB_DI_PIN, PinDirectionOutput); |
36 | pinMode(RGB_CLK_PIN, PinDirectionOutput); | 34 | pinMode(RGB_CLK_PIN, PinDirectionOutput); |
37 | 35 | ||
38 | apa102_send_array((uint8_t*)ledarray,leds) | 36 | apa102_send_array((uint8_t *)ledarray, leds) |
39 | } | 37 | } |
40 | 38 | ||
41 | void apa102_send_array(uint8_t *data, uint16_t leds){ // Data is struct of 3 bytes. RGB - leds is number of leds in data | 39 | void apa102_send_array(uint8_t *data, uint16_t leds) { // Data is struct of 3 bytes. RGB - leds is number of leds in data |
42 | apa102_start_frame(); | 40 | apa102_start_frame(); |
43 | while(leds--){ | 41 | while (leds--) { |
44 | apa102_send_frame(0xFF000000 | (data->b << 16) | (data->g << 8) | data->r); | 42 | apa102_send_frame(0xFF000000 | (data->b << 16) | (data->g << 8) | data->r); |
45 | data++; | 43 | data++; |
46 | } | 44 | } |
47 | apa102_end_frame(leds); | 45 | apa102_end_frame(leds); |
48 | } | 46 | } |
49 | 47 | ||
50 | void apa102_send_frame(uint32_t frame){ | 48 | void apa102_send_frame(uint32_t frame) { |
51 | for(uint32_t i=0xFF; i>0;){ | 49 | for (uint32_t i = 0xFF; i > 0;) { |
52 | apa102_send_byte(frame & i); | 50 | apa102_send_byte(frame & i); |
53 | i = i << 8; | 51 | i = i << 8; |
54 | } | 52 | } |
55 | } | 53 | } |
56 | 54 | ||
57 | void apa102_start_frame(){ | 55 | void apa102_start_frame() { apa102_send_frame(0); } |
58 | apa102_send_frame(0); | ||
59 | } | ||
60 | 56 | ||
61 | void apa102_end_frame(uint16_t leds) | 57 | void apa102_end_frame(uint16_t leds) { |
62 | { | 58 | // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h |
63 | // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h | 59 | // and adapted. The code is MIT licensed. I think thats compatible? |
64 | // and adapted. The code is MIT licensed. I think thats compatible? | ||
65 | 60 | ||
66 | // We need to send some more bytes to ensure that all the LEDs in the | 61 | // We need to send some more bytes to ensure that all the LEDs in the |
67 | // chain see their new color and start displaying it. | 62 | // chain see their new color and start displaying it. |
68 | // | 63 | // |
69 | // The data stream seen by the last LED in the chain will be delayed by | 64 | // The data stream seen by the last LED in the chain will be delayed by |
70 | // (count - 1) clock edges, because each LED before it inverts the clock | 65 | // (count - 1) clock edges, because each LED before it inverts the clock |
71 | // line and delays the data by one clock edge. Therefore, to make sure | 66 | // line and delays the data by one clock edge. Therefore, to make sure |
72 | // the last LED actually receives the data we wrote, the number of extra | 67 | // the last LED actually receives the data we wrote, the number of extra |
73 | // edges we send at the end of the frame must be at least (count - 1). | 68 | // edges we send at the end of the frame must be at least (count - 1). |
74 | // For the APA102C, that is sufficient. | 69 | // For the APA102C, that is sufficient. |
75 | // | 70 | // |
76 | // The SK9822 only updates after it sees 32 zero bits followed by one more | 71 | // The SK9822 only updates after it sees 32 zero bits followed by one more |
77 | // rising edge. To avoid having the update time depend on the color of | 72 | // rising edge. To avoid having the update time depend on the color of |
78 | // the last LED, we send a dummy 0xFF byte. (Unfortunately, this means | 73 | // the last LED, we send a dummy 0xFF byte. (Unfortunately, this means |
79 | // that partial updates of the beginning of an LED strip are not possible; | 74 | // that partial updates of the beginning of an LED strip are not possible; |
80 | // the LED after the last one you are trying to update will be black.) | 75 | // the LED after the last one you are trying to update will be black.) |
81 | // After that, to ensure that the last LED in the chain sees 32 zero bits | 76 | // After that, to ensure that the last LED in the chain sees 32 zero bits |
82 | // and a rising edge, we need to send at least 65 + (count - 1) edges. It | 77 | // and a rising edge, we need to send at least 65 + (count - 1) edges. It |
83 | // is sufficent and simpler to just send (5 + count/16) bytes of zeros. | 78 | // is sufficent and simpler to just send (5 + count/16) bytes of zeros. |
84 | // | 79 | // |
85 | // We are ignoring the specification for the end frame in the APA102/SK9822 | 80 | // We are ignoring the specification for the end frame in the APA102/SK9822 |
86 | // datasheets because it does not actually ensure that all the LEDs will | 81 | // datasheets because it does not actually ensure that all the LEDs will |
87 | // start displaying their new colors right away. | 82 | // start displaying their new colors right away. |
88 | 83 | ||
89 | apa102_send_byte(0xFF); | 84 | apa102_send_byte(0xFF); |
90 | for (uint16_t i = 0; i < 5 + leds / 16; i++){ | 85 | for (uint16_t i = 0; i < 5 + leds / 16; i++) { |
91 | apa102_send_byte(0); | 86 | apa102_send_byte(0); |
92 | } | 87 | } |
93 | } | 88 | } |
94 | 89 | ||
95 | void apa102_send_byte(uint8_t byte){ | 90 | void apa102_send_byte(uint8_t byte) { |
96 | uint8_t i; | 91 | uint8_t i; |
97 | for (i = 0; i < 8; i++){ | 92 | for (i = 0; i < 8; i++) { |
98 | digitalWrite(RGB_DI_PIN, !!(byte & (1 << (7-i))); | 93 | digitalWrite(RGB_DI_PIN, !!(byte & (1 << (7-i))); |
99 | digitalWrite(RGB_CLK_PIN, PinLevelHigh); | 94 | digitalWrite(RGB_CLK_PIN, PinLevelHigh); |
100 | } | 95 | } |
101 | } | 96 | } |
diff --git a/drivers/avr/apa102.h b/drivers/avr/apa102.h index 5d852e067..d4c1e18ee 100755..100644 --- a/drivers/avr/apa102.h +++ b/drivers/avr/apa102.h | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include "color.h" | 28 | #include "color.h" |
29 | 29 | ||
30 | |||
31 | /* User Interface | 30 | /* User Interface |
32 | * | 31 | * |
33 | * Input: | 32 | * Input: |
@@ -41,6 +40,6 @@ | |||
41 | * - Wait 50�s to reset the LEDs | 40 | * - Wait 50�s to reset the LEDs |
42 | */ | 41 | */ |
43 | 42 | ||
44 | void apa102_setleds (LED_TYPE *ledarray, uint16_t number_of_leds); | 43 | void apa102_setleds(LED_TYPE *ledarray, uint16_t number_of_leds); |
45 | void apa102_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask); | 44 | void apa102_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask); |
46 | void apa102_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); | 45 | void apa102_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); |
diff --git a/drivers/avr/glcdfont.c b/drivers/avr/glcdfont.c index 6f88bd23a..2c332ea6d 100644 --- a/drivers/avr/glcdfont.c +++ b/drivers/avr/glcdfont.c | |||
@@ -5,272 +5,30 @@ | |||
5 | #define FONT5X7_H | 5 | #define FONT5X7_H |
6 | 6 | ||
7 | #ifdef __AVR__ | 7 | #ifdef __AVR__ |
8 | #include <avr/io.h> | 8 | # include <avr/io.h> |
9 | #include <avr/pgmspace.h> | 9 | # include <avr/pgmspace.h> |
10 | #elif defined(ESP8266) | 10 | #elif defined(ESP8266) |
11 | #include <pgmspace.h> | 11 | # include <pgmspace.h> |
12 | #else | 12 | #else |
13 | #define PROGMEM | 13 | # define PROGMEM |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | // Standard ASCII 5x7 font | 16 | // Standard ASCII 5x7 font |
17 | 17 | ||
18 | static const unsigned char font[] PROGMEM = { | 18 | static const unsigned char font[] PROGMEM = { |
19 | 0x00, 0x00, 0x00, 0x00, 0x00, | 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24, 0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, |
20 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, | 20 | 0x30, 0x38, 0x3E, 0x38, 0x30, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, |
21 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, | 21 | 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, |
22 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, | 22 | 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C, |
23 | 0x18, 0x3C, 0x7E, 0x3C, 0x18, | 23 | 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut |
24 | 0x1C, 0x57, 0x7D, 0x57, 0x1C, | 24 | 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut |
25 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, | 25 | 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49, 0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut |
26 | 0x00, 0x18, 0x3C, 0x18, 0x00, | 26 | 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut |
27 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, | 27 | 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code |
28 | 0x00, 0x18, 0x24, 0x18, 0x00, | 28 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block |
29 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, | 29 | 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block |
30 | 0x30, 0x48, 0x3A, 0x06, 0x0E, | 30 | 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17, 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, |
31 | 0x26, 0x29, 0x79, 0x29, 0x26, | 31 | 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta |
32 | 0x40, 0x7F, 0x05, 0x05, 0x07, | 32 | 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP |
33 | 0x40, 0x7F, 0x05, 0x25, 0x3F, | ||
34 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, | ||
35 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08, | ||
36 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F, | ||
37 | 0x14, 0x22, 0x7F, 0x22, 0x14, | ||
38 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F, | ||
39 | 0x06, 0x09, 0x7F, 0x01, 0x7F, | ||
40 | 0x00, 0x66, 0x89, 0x95, 0x6A, | ||
41 | 0x60, 0x60, 0x60, 0x60, 0x60, | ||
42 | 0x94, 0xA2, 0xFF, 0xA2, 0x94, | ||
43 | 0x08, 0x04, 0x7E, 0x04, 0x08, | ||
44 | 0x10, 0x20, 0x7E, 0x20, 0x10, | ||
45 | 0x08, 0x08, 0x2A, 0x1C, 0x08, | ||
46 | 0x08, 0x1C, 0x2A, 0x08, 0x08, | ||
47 | 0x1E, 0x10, 0x10, 0x10, 0x10, | ||
48 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, | ||
49 | 0x30, 0x38, 0x3E, 0x38, 0x30, | ||
50 | 0x06, 0x0E, 0x3E, 0x0E, 0x06, | ||
51 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
52 | 0x00, 0x00, 0x5F, 0x00, 0x00, | ||
53 | 0x00, 0x07, 0x00, 0x07, 0x00, | ||
54 | 0x14, 0x7F, 0x14, 0x7F, 0x14, | ||
55 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, | ||
56 | 0x23, 0x13, 0x08, 0x64, 0x62, | ||
57 | 0x36, 0x49, 0x56, 0x20, 0x50, | ||
58 | 0x00, 0x08, 0x07, 0x03, 0x00, | ||
59 | 0x00, 0x1C, 0x22, 0x41, 0x00, | ||
60 | 0x00, 0x41, 0x22, 0x1C, 0x00, | ||
61 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, | ||
62 | 0x08, 0x08, 0x3E, 0x08, 0x08, | ||
63 | 0x00, 0x80, 0x70, 0x30, 0x00, | ||
64 | 0x08, 0x08, 0x08, 0x08, 0x08, | ||
65 | 0x00, 0x00, 0x60, 0x60, 0x00, | ||
66 | 0x20, 0x10, 0x08, 0x04, 0x02, | ||
67 | 0x3E, 0x51, 0x49, 0x45, 0x3E, | ||
68 | 0x00, 0x42, 0x7F, 0x40, 0x00, | ||
69 | 0x72, 0x49, 0x49, 0x49, 0x46, | ||
70 | 0x21, 0x41, 0x49, 0x4D, 0x33, | ||
71 | 0x18, 0x14, 0x12, 0x7F, 0x10, | ||
72 | 0x27, 0x45, 0x45, 0x45, 0x39, | ||
73 | 0x3C, 0x4A, 0x49, 0x49, 0x31, | ||
74 | 0x41, 0x21, 0x11, 0x09, 0x07, | ||
75 | 0x36, 0x49, 0x49, 0x49, 0x36, | ||
76 | 0x46, 0x49, 0x49, 0x29, 0x1E, | ||
77 | 0x00, 0x00, 0x14, 0x00, 0x00, | ||
78 | 0x00, 0x40, 0x34, 0x00, 0x00, | ||
79 | 0x00, 0x08, 0x14, 0x22, 0x41, | ||
80 | 0x14, 0x14, 0x14, 0x14, 0x14, | ||
81 | 0x00, 0x41, 0x22, 0x14, 0x08, | ||
82 | 0x02, 0x01, 0x59, 0x09, 0x06, | ||
83 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, | ||
84 | 0x7C, 0x12, 0x11, 0x12, 0x7C, | ||
85 | 0x7F, 0x49, 0x49, 0x49, 0x36, | ||
86 | 0x3E, 0x41, 0x41, 0x41, 0x22, | ||
87 | 0x7F, 0x41, 0x41, 0x41, 0x3E, | ||
88 | 0x7F, 0x49, 0x49, 0x49, 0x41, | ||
89 | 0x7F, 0x09, 0x09, 0x09, 0x01, | ||
90 | 0x3E, 0x41, 0x41, 0x51, 0x73, | ||
91 | 0x7F, 0x08, 0x08, 0x08, 0x7F, | ||
92 | 0x00, 0x41, 0x7F, 0x41, 0x00, | ||
93 | 0x20, 0x40, 0x41, 0x3F, 0x01, | ||
94 | 0x7F, 0x08, 0x14, 0x22, 0x41, | ||
95 | 0x7F, 0x40, 0x40, 0x40, 0x40, | ||
96 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, | ||
97 | 0x7F, 0x04, 0x08, 0x10, 0x7F, | ||
98 | 0x3E, 0x41, 0x41, 0x41, 0x3E, | ||
99 | 0x7F, 0x09, 0x09, 0x09, 0x06, | ||
100 | 0x3E, 0x41, 0x51, 0x21, 0x5E, | ||
101 | 0x7F, 0x09, 0x19, 0x29, 0x46, | ||
102 | 0x26, 0x49, 0x49, 0x49, 0x32, | ||
103 | 0x03, 0x01, 0x7F, 0x01, 0x03, | ||
104 | 0x3F, 0x40, 0x40, 0x40, 0x3F, | ||
105 | 0x1F, 0x20, 0x40, 0x20, 0x1F, | ||
106 | 0x3F, 0x40, 0x38, 0x40, 0x3F, | ||
107 | 0x63, 0x14, 0x08, 0x14, 0x63, | ||
108 | 0x03, 0x04, 0x78, 0x04, 0x03, | ||
109 | 0x61, 0x59, 0x49, 0x4D, 0x43, | ||
110 | 0x00, 0x7F, 0x41, 0x41, 0x41, | ||
111 | 0x02, 0x04, 0x08, 0x10, 0x20, | ||
112 | 0x00, 0x41, 0x41, 0x41, 0x7F, | ||
113 | 0x04, 0x02, 0x01, 0x02, 0x04, | ||
114 | 0x40, 0x40, 0x40, 0x40, 0x40, | ||
115 | 0x00, 0x03, 0x07, 0x08, 0x00, | ||
116 | 0x20, 0x54, 0x54, 0x78, 0x40, | ||
117 | 0x7F, 0x28, 0x44, 0x44, 0x38, | ||
118 | 0x38, 0x44, 0x44, 0x44, 0x28, | ||
119 | 0x38, 0x44, 0x44, 0x28, 0x7F, | ||
120 | 0x38, 0x54, 0x54, 0x54, 0x18, | ||
121 | 0x00, 0x08, 0x7E, 0x09, 0x02, | ||
122 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, | ||
123 | 0x7F, 0x08, 0x04, 0x04, 0x78, | ||
124 | 0x00, 0x44, 0x7D, 0x40, 0x00, | ||
125 | 0x20, 0x40, 0x40, 0x3D, 0x00, | ||
126 | 0x7F, 0x10, 0x28, 0x44, 0x00, | ||
127 | 0x00, 0x41, 0x7F, 0x40, 0x00, | ||
128 | 0x7C, 0x04, 0x78, 0x04, 0x78, | ||
129 | 0x7C, 0x08, 0x04, 0x04, 0x78, | ||
130 | 0x38, 0x44, 0x44, 0x44, 0x38, | ||
131 | 0xFC, 0x18, 0x24, 0x24, 0x18, | ||
132 | 0x18, 0x24, 0x24, 0x18, 0xFC, | ||
133 | 0x7C, 0x08, 0x04, 0x04, 0x08, | ||
134 | 0x48, 0x54, 0x54, 0x54, 0x24, | ||
135 | 0x04, 0x04, 0x3F, 0x44, 0x24, | ||
136 | 0x3C, 0x40, 0x40, 0x20, 0x7C, | ||
137 | 0x1C, 0x20, 0x40, 0x20, 0x1C, | ||
138 | 0x3C, 0x40, 0x30, 0x40, 0x3C, | ||
139 | 0x44, 0x28, 0x10, 0x28, 0x44, | ||
140 | 0x4C, 0x90, 0x90, 0x90, 0x7C, | ||
141 | 0x44, 0x64, 0x54, 0x4C, 0x44, | ||
142 | 0x00, 0x08, 0x36, 0x41, 0x00, | ||
143 | 0x00, 0x00, 0x77, 0x00, 0x00, | ||
144 | 0x00, 0x41, 0x36, 0x08, 0x00, | ||
145 | 0x02, 0x01, 0x02, 0x04, 0x02, | ||
146 | 0x3C, 0x26, 0x23, 0x26, 0x3C, | ||
147 | 0x1E, 0xA1, 0xA1, 0x61, 0x12, | ||
148 | 0x3A, 0x40, 0x40, 0x20, 0x7A, | ||
149 | 0x38, 0x54, 0x54, 0x55, 0x59, | ||
150 | 0x21, 0x55, 0x55, 0x79, 0x41, | ||
151 | 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut | ||
152 | 0x21, 0x55, 0x54, 0x78, 0x40, | ||
153 | 0x20, 0x54, 0x55, 0x79, 0x40, | ||
154 | 0x0C, 0x1E, 0x52, 0x72, 0x12, | ||
155 | 0x39, 0x55, 0x55, 0x55, 0x59, | ||
156 | 0x39, 0x54, 0x54, 0x54, 0x59, | ||
157 | 0x39, 0x55, 0x54, 0x54, 0x58, | ||
158 | 0x00, 0x00, 0x45, 0x7C, 0x41, | ||
159 | 0x00, 0x02, 0x45, 0x7D, 0x42, | ||
160 | 0x00, 0x01, 0x45, 0x7C, 0x40, | ||
161 | 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut | ||
162 | 0xF0, 0x28, 0x25, 0x28, 0xF0, | ||
163 | 0x7C, 0x54, 0x55, 0x45, 0x00, | ||
164 | 0x20, 0x54, 0x54, 0x7C, 0x54, | ||
165 | 0x7C, 0x0A, 0x09, 0x7F, 0x49, | ||
166 | 0x32, 0x49, 0x49, 0x49, 0x32, | ||
167 | 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut | ||
168 | 0x32, 0x4A, 0x48, 0x48, 0x30, | ||
169 | 0x3A, 0x41, 0x41, 0x21, 0x7A, | ||
170 | 0x3A, 0x42, 0x40, 0x20, 0x78, | ||
171 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D, | ||
172 | 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut | ||
173 | 0x3D, 0x40, 0x40, 0x40, 0x3D, | ||
174 | 0x3C, 0x24, 0xFF, 0x24, 0x24, | ||
175 | 0x48, 0x7E, 0x49, 0x43, 0x66, | ||
176 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, | ||
177 | 0xFF, 0x09, 0x29, 0xF6, 0x20, | ||
178 | 0xC0, 0x88, 0x7E, 0x09, 0x03, | ||
179 | 0x20, 0x54, 0x54, 0x79, 0x41, | ||
180 | 0x00, 0x00, 0x44, 0x7D, 0x41, | ||
181 | 0x30, 0x48, 0x48, 0x4A, 0x32, | ||
182 | 0x38, 0x40, 0x40, 0x22, 0x7A, | ||
183 | 0x00, 0x7A, 0x0A, 0x0A, 0x72, | ||
184 | 0x7D, 0x0D, 0x19, 0x31, 0x7D, | ||
185 | 0x26, 0x29, 0x29, 0x2F, 0x28, | ||
186 | 0x26, 0x29, 0x29, 0x29, 0x26, | ||
187 | 0x30, 0x48, 0x4D, 0x40, 0x20, | ||
188 | 0x38, 0x08, 0x08, 0x08, 0x08, | ||
189 | 0x08, 0x08, 0x08, 0x08, 0x38, | ||
190 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA, | ||
191 | 0x2F, 0x10, 0x28, 0x34, 0xFA, | ||
192 | 0x00, 0x00, 0x7B, 0x00, 0x00, | ||
193 | 0x08, 0x14, 0x2A, 0x14, 0x22, | ||
194 | 0x22, 0x14, 0x2A, 0x14, 0x08, | ||
195 | 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code | ||
196 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block | ||
197 | 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block | ||
198 | 0x00, 0x00, 0x00, 0xFF, 0x00, | ||
199 | 0x10, 0x10, 0x10, 0xFF, 0x00, | ||
200 | 0x14, 0x14, 0x14, 0xFF, 0x00, | ||
201 | 0x10, 0x10, 0xFF, 0x00, 0xFF, | ||
202 | 0x10, 0x10, 0xF0, 0x10, 0xF0, | ||
203 | 0x14, 0x14, 0x14, 0xFC, 0x00, | ||
204 | 0x14, 0x14, 0xF7, 0x00, 0xFF, | ||
205 | 0x00, 0x00, 0xFF, 0x00, 0xFF, | ||
206 | 0x14, 0x14, 0xF4, 0x04, 0xFC, | ||
207 | 0x14, 0x14, 0x17, 0x10, 0x1F, | ||
208 | 0x10, 0x10, 0x1F, 0x10, 0x1F, | ||
209 | 0x14, 0x14, 0x14, 0x1F, 0x00, | ||
210 | 0x10, 0x10, 0x10, 0xF0, 0x00, | ||
211 | 0x00, 0x00, 0x00, 0x1F, 0x10, | ||
212 | 0x10, 0x10, 0x10, 0x1F, 0x10, | ||
213 | 0x10, 0x10, 0x10, 0xF0, 0x10, | ||
214 | 0x00, 0x00, 0x00, 0xFF, 0x10, | ||
215 | 0x10, 0x10, 0x10, 0x10, 0x10, | ||
216 | 0x10, 0x10, 0x10, 0xFF, 0x10, | ||
217 | 0x00, 0x00, 0x00, 0xFF, 0x14, | ||
218 | 0x00, 0x00, 0xFF, 0x00, 0xFF, | ||
219 | 0x00, 0x00, 0x1F, 0x10, 0x17, | ||
220 | 0x00, 0x00, 0xFC, 0x04, 0xF4, | ||
221 | 0x14, 0x14, 0x17, 0x10, 0x17, | ||
222 | 0x14, 0x14, 0xF4, 0x04, 0xF4, | ||
223 | 0x00, 0x00, 0xFF, 0x00, 0xF7, | ||
224 | 0x14, 0x14, 0x14, 0x14, 0x14, | ||
225 | 0x14, 0x14, 0xF7, 0x00, 0xF7, | ||
226 | 0x14, 0x14, 0x14, 0x17, 0x14, | ||
227 | 0x10, 0x10, 0x1F, 0x10, 0x1F, | ||
228 | 0x14, 0x14, 0x14, 0xF4, 0x14, | ||
229 | 0x10, 0x10, 0xF0, 0x10, 0xF0, | ||
230 | 0x00, 0x00, 0x1F, 0x10, 0x1F, | ||
231 | 0x00, 0x00, 0x00, 0x1F, 0x14, | ||
232 | 0x00, 0x00, 0x00, 0xFC, 0x14, | ||
233 | 0x00, 0x00, 0xF0, 0x10, 0xF0, | ||
234 | 0x10, 0x10, 0xFF, 0x10, 0xFF, | ||
235 | 0x14, 0x14, 0x14, 0xFF, 0x14, | ||
236 | 0x10, 0x10, 0x10, 0x1F, 0x00, | ||
237 | 0x00, 0x00, 0x00, 0xF0, 0x10, | ||
238 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
239 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, | ||
240 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, | ||
241 | 0x00, 0x00, 0x00, 0xFF, 0xFF, | ||
242 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, | ||
243 | 0x38, 0x44, 0x44, 0x38, 0x44, | ||
244 | 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta | ||
245 | 0x7E, 0x02, 0x02, 0x06, 0x06, | ||
246 | 0x02, 0x7E, 0x02, 0x7E, 0x02, | ||
247 | 0x63, 0x55, 0x49, 0x41, 0x63, | ||
248 | 0x38, 0x44, 0x44, 0x3C, 0x04, | ||
249 | 0x40, 0x7E, 0x20, 0x1E, 0x20, | ||
250 | 0x06, 0x02, 0x7E, 0x02, 0x02, | ||
251 | 0x99, 0xA5, 0xE7, 0xA5, 0x99, | ||
252 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C, | ||
253 | 0x4C, 0x72, 0x01, 0x72, 0x4C, | ||
254 | 0x30, 0x4A, 0x4D, 0x4D, 0x30, | ||
255 | 0x30, 0x48, 0x78, 0x48, 0x30, | ||
256 | 0xBC, 0x62, 0x5A, 0x46, 0x3D, | ||
257 | 0x3E, 0x49, 0x49, 0x49, 0x00, | ||
258 | 0x7E, 0x01, 0x01, 0x01, 0x7E, | ||
259 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, | ||
260 | 0x44, 0x44, 0x5F, 0x44, 0x44, | ||
261 | 0x40, 0x51, 0x4A, 0x44, 0x40, | ||
262 | 0x40, 0x44, 0x4A, 0x51, 0x40, | ||
263 | 0x00, 0x00, 0xFF, 0x01, 0x03, | ||
264 | 0xE0, 0x80, 0xFF, 0x00, 0x00, | ||
265 | 0x08, 0x08, 0x6B, 0x6B, 0x08, | ||
266 | 0x36, 0x12, 0x36, 0x24, 0x36, | ||
267 | 0x06, 0x0F, 0x09, 0x0F, 0x06, | ||
268 | 0x00, 0x00, 0x18, 0x18, 0x00, | ||
269 | 0x00, 0x00, 0x10, 0x10, 0x00, | ||
270 | 0x30, 0x40, 0xFF, 0x01, 0x01, | ||
271 | 0x00, 0x1F, 0x01, 0x01, 0x1E, | ||
272 | 0x00, 0x19, 0x1D, 0x17, 0x12, | ||
273 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C, | ||
274 | 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP | ||
275 | }; | 33 | }; |
276 | #endif // FONT5X7_H | 34 | #endif // FONT5X7_H |
diff --git a/drivers/avr/hd44780.c b/drivers/avr/hd44780.c index 51414d8f9..f71069dec 100644 --- a/drivers/avr/hd44780.c +++ b/drivers/avr/hd44780.c | |||
@@ -3,7 +3,7 @@ | |||
3 | Author: Peter Fleury <pfleury@gmx.ch> http://tinyurl.com/peterfleury | 3 | Author: Peter Fleury <pfleury@gmx.ch> http://tinyurl.com/peterfleury |
4 | License: GNU General Public License Version 3 | 4 | License: GNU General Public License Version 3 |
5 | File: $Id: lcd.c,v 1.15.2.2 2015/01/17 12:16:05 peter Exp $ | 5 | File: $Id: lcd.c,v 1.15.2.2 2015/01/17 12:16:05 peter Exp $ |
6 | Software: AVR-GCC 3.3 | 6 | Software: AVR-GCC 3.3 |
7 | Target: any AVR device, memory mapped mode only for AT90S4414/8515/Mega | 7 | Target: any AVR device, memory mapped mode only for AT90S4414/8515/Mega |
8 | 8 | ||
9 | DESCRIPTION | 9 | DESCRIPTION |
@@ -13,15 +13,15 @@ | |||
13 | changed lcd_init(), added additional constants for lcd_command(), | 13 | changed lcd_init(), added additional constants for lcd_command(), |
14 | added 4-bit I/O mode, improved and optimized code. | 14 | added 4-bit I/O mode, improved and optimized code. |
15 | 15 | ||
16 | Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in | 16 | Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in |
17 | 4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported. | 17 | 4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported. |
18 | 18 | ||
19 | Memory mapped mode compatible with Kanda STK200, but supports also | 19 | Memory mapped mode compatible with Kanda STK200, but supports also |
20 | generation of R/W signal through A8 address line. | 20 | generation of R/W signal through A8 address line. |
21 | 21 | ||
22 | USAGE | 22 | USAGE |
23 | See the C include lcd.h file for a description of each function | 23 | See the C include lcd.h file for a description of each function |
24 | 24 | ||
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | #include <inttypes.h> | 26 | #include <inttypes.h> |
27 | #include <avr/io.h> | 27 | #include <avr/io.h> |
@@ -29,55 +29,54 @@ | |||
29 | #include <util/delay.h> | 29 | #include <util/delay.h> |
30 | #include "hd44780.h" | 30 | #include "hd44780.h" |
31 | 31 | ||
32 | /* | 32 | /* |
33 | ** constants/macros | 33 | ** constants/macros |
34 | */ | 34 | */ |
35 | #define DDR(x) (*(&x - 1)) /* address of data direction register of port x */ | 35 | #define DDR(x) (*(&x - 1)) /* address of data direction register of port x */ |
36 | #if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) | 36 | #if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) |
37 | /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */ | 37 | /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */ |
38 | #define PIN(x) ( &PORTF==&(x) ? _SFR_IO8(0x00) : (*(&x - 2)) ) | 38 | # define PIN(x) (&PORTF == &(x) ? _SFR_IO8(0x00) : (*(&x - 2))) |
39 | #else | 39 | #else |
40 | #define PIN(x) (*(&x - 2)) /* address of input register of port x */ | 40 | # define PIN(x) (*(&x - 2)) /* address of input register of port x */ |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | |||
44 | #if LCD_IO_MODE | 43 | #if LCD_IO_MODE |
45 | #define lcd_e_delay() _delay_us(LCD_DELAY_ENABLE_PULSE) | 44 | # define lcd_e_delay() _delay_us(LCD_DELAY_ENABLE_PULSE) |
46 | #define lcd_e_high() LCD_E_PORT |= _BV(LCD_E_PIN); | 45 | # define lcd_e_high() LCD_E_PORT |= _BV(LCD_E_PIN); |
47 | #define lcd_e_low() LCD_E_PORT &= ~_BV(LCD_E_PIN); | 46 | # define lcd_e_low() LCD_E_PORT &= ~_BV(LCD_E_PIN); |
48 | #define lcd_e_toggle() toggle_e() | 47 | # define lcd_e_toggle() toggle_e() |
49 | #define lcd_rw_high() LCD_RW_PORT |= _BV(LCD_RW_PIN) | 48 | # define lcd_rw_high() LCD_RW_PORT |= _BV(LCD_RW_PIN) |
50 | #define lcd_rw_low() LCD_RW_PORT &= ~_BV(LCD_RW_PIN) | 49 | # define lcd_rw_low() LCD_RW_PORT &= ~_BV(LCD_RW_PIN) |
51 | #define lcd_rs_high() LCD_RS_PORT |= _BV(LCD_RS_PIN) | 50 | # define lcd_rs_high() LCD_RS_PORT |= _BV(LCD_RS_PIN) |
52 | #define lcd_rs_low() LCD_RS_PORT &= ~_BV(LCD_RS_PIN) | 51 | # define lcd_rs_low() LCD_RS_PORT &= ~_BV(LCD_RS_PIN) |
53 | #endif | 52 | #endif |
54 | 53 | ||
55 | #if LCD_IO_MODE | 54 | #if LCD_IO_MODE |
56 | #if LCD_LINES==1 | 55 | # if LCD_LINES == 1 |
57 | #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE | 56 | # define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE |
57 | # else | ||
58 | # define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES | ||
59 | # endif | ||
58 | #else | 60 | #else |
59 | #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES | 61 | # if LCD_LINES == 1 |
60 | #endif | 62 | # define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_1LINE |
61 | #else | 63 | # else |
62 | #if LCD_LINES==1 | 64 | # define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_2LINES |
63 | #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_1LINE | 65 | # endif |
64 | #else | ||
65 | #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_2LINES | ||
66 | #endif | ||
67 | #endif | 66 | #endif |
68 | 67 | ||
69 | #if LCD_CONTROLLER_KS0073 | 68 | #if LCD_CONTROLLER_KS0073 |
70 | #if LCD_LINES==4 | 69 | # if LCD_LINES == 4 |
71 | 70 | ||
72 | #define KS0073_EXTENDED_FUNCTION_REGISTER_ON 0x2C /* |0|010|1100 4-bit mode, extension-bit RE = 1 */ | 71 | # define KS0073_EXTENDED_FUNCTION_REGISTER_ON 0x2C /* |0|010|1100 4-bit mode, extension-bit RE = 1 */ |
73 | #define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x28 /* |0|010|1000 4-bit mode, extension-bit RE = 0 */ | 72 | # define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x28 /* |0|010|1000 4-bit mode, extension-bit RE = 0 */ |
74 | #define KS0073_4LINES_MODE 0x09 /* |0|000|1001 4 lines mode */ | 73 | # define KS0073_4LINES_MODE 0x09 /* |0|000|1001 4 lines mode */ |
75 | 74 | ||
76 | #endif | 75 | # endif |
77 | #endif | 76 | #endif |
78 | 77 | ||
79 | /* | 78 | /* |
80 | ** function prototypes | 79 | ** function prototypes |
81 | */ | 80 | */ |
82 | #if LCD_IO_MODE | 81 | #if LCD_IO_MODE |
83 | static void toggle_e(void); | 82 | static void toggle_e(void); |
@@ -87,93 +86,83 @@ static void toggle_e(void); | |||
87 | ** local functions | 86 | ** local functions |
88 | */ | 87 | */ |
89 | 88 | ||
90 | 89 | /************************************************************************* | |
91 | /************************************************************************* | ||
92 | delay for a minimum of <us> microseconds | 90 | delay for a minimum of <us> microseconds |
93 | the number of loops is calculated at compile-time from MCU clock frequency | 91 | the number of loops is calculated at compile-time from MCU clock frequency |
94 | *************************************************************************/ | 92 | *************************************************************************/ |
95 | #define delay(us) _delay_us(us) | 93 | #define delay(us) _delay_us(us) |
96 | |||
97 | 94 | ||
98 | #if LCD_IO_MODE | 95 | #if LCD_IO_MODE |
99 | /* toggle Enable Pin to initiate write */ | 96 | /* toggle Enable Pin to initiate write */ |
100 | static void toggle_e(void) | 97 | static void toggle_e(void) { |
101 | { | ||
102 | lcd_e_high(); | 98 | lcd_e_high(); |
103 | lcd_e_delay(); | 99 | lcd_e_delay(); |
104 | lcd_e_low(); | 100 | lcd_e_low(); |
105 | } | 101 | } |
106 | #endif | 102 | #endif |
107 | 103 | ||
108 | |||
109 | /************************************************************************* | 104 | /************************************************************************* |
110 | Low-level function to write byte to LCD controller | 105 | Low-level function to write byte to LCD controller |
111 | Input: data byte to write to LCD | 106 | Input: data byte to write to LCD |
112 | rs 1: write data | 107 | rs 1: write data |
113 | 0: write instruction | 108 | 0: write instruction |
114 | Returns: none | 109 | Returns: none |
115 | *************************************************************************/ | 110 | *************************************************************************/ |
116 | #if LCD_IO_MODE | 111 | #if LCD_IO_MODE |
117 | static void lcd_write(uint8_t data,uint8_t rs) | 112 | static void lcd_write(uint8_t data, uint8_t rs) { |
118 | { | 113 | unsigned char dataBits; |
119 | unsigned char dataBits ; | ||
120 | |||
121 | 114 | ||
122 | if (rs) { /* write data (RS=1, RW=0) */ | 115 | if (rs) { /* write data (RS=1, RW=0) */ |
123 | lcd_rs_high(); | 116 | lcd_rs_high(); |
124 | } else { /* write instruction (RS=0, RW=0) */ | 117 | } else { /* write instruction (RS=0, RW=0) */ |
125 | lcd_rs_low(); | 118 | lcd_rs_low(); |
126 | } | 119 | } |
127 | lcd_rw_low(); /* RW=0 write mode */ | 120 | lcd_rw_low(); /* RW=0 write mode */ |
128 | 121 | ||
129 | if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT ) | 122 | if ((&LCD_DATA0_PORT == &LCD_DATA1_PORT) && (&LCD_DATA1_PORT == &LCD_DATA2_PORT) && (&LCD_DATA2_PORT == &LCD_DATA3_PORT) && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3)) { |
130 | && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) ) | ||
131 | { | ||
132 | /* configure data pins as output */ | 123 | /* configure data pins as output */ |
133 | DDR(LCD_DATA0_PORT) |= 0x0F; | 124 | DDR(LCD_DATA0_PORT) |= 0x0F; |
134 | 125 | ||
135 | /* output high nibble first */ | 126 | /* output high nibble first */ |
136 | dataBits = LCD_DATA0_PORT & 0xF0; | 127 | dataBits = LCD_DATA0_PORT & 0xF0; |
137 | LCD_DATA0_PORT = dataBits |((data>>4)&0x0F); | 128 | LCD_DATA0_PORT = dataBits | ((data >> 4) & 0x0F); |
138 | lcd_e_toggle(); | 129 | lcd_e_toggle(); |
139 | 130 | ||
140 | /* output low nibble */ | 131 | /* output low nibble */ |
141 | LCD_DATA0_PORT = dataBits | (data&0x0F); | 132 | LCD_DATA0_PORT = dataBits | (data & 0x0F); |
142 | lcd_e_toggle(); | 133 | lcd_e_toggle(); |
143 | 134 | ||
144 | /* all data pins high (inactive) */ | 135 | /* all data pins high (inactive) */ |
145 | LCD_DATA0_PORT = dataBits | 0x0F; | 136 | LCD_DATA0_PORT = dataBits | 0x0F; |
146 | } | 137 | } else { |
147 | else | ||
148 | { | ||
149 | /* configure data pins as output */ | 138 | /* configure data pins as output */ |
150 | DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN); | 139 | DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN); |
151 | DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN); | 140 | DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN); |
152 | DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN); | 141 | DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN); |
153 | DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN); | 142 | DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN); |
154 | 143 | ||
155 | /* output high nibble first */ | 144 | /* output high nibble first */ |
156 | LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); | 145 | LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); |
157 | LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); | 146 | LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); |
158 | LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); | 147 | LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); |
159 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); | 148 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); |
160 | if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); | 149 | if (data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); |
161 | if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); | 150 | if (data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); |
162 | if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); | 151 | if (data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); |
163 | if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); | 152 | if (data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); |
164 | lcd_e_toggle(); | 153 | lcd_e_toggle(); |
165 | 154 | ||
166 | /* output low nibble */ | 155 | /* output low nibble */ |
167 | LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); | 156 | LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN); |
168 | LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); | 157 | LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN); |
169 | LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); | 158 | LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN); |
170 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); | 159 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); |
171 | if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); | 160 | if (data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN); |
172 | if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); | 161 | if (data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN); |
173 | if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); | 162 | if (data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); |
174 | if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); | 163 | if (data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); |
175 | lcd_e_toggle(); | 164 | lcd_e_toggle(); |
176 | 165 | ||
177 | /* all data pins high (inactive) */ | 166 | /* all data pins high (inactive) */ |
178 | LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); | 167 | LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); |
179 | LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); | 168 | LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); |
@@ -182,85 +171,81 @@ static void lcd_write(uint8_t data,uint8_t rs) | |||
182 | } | 171 | } |
183 | } | 172 | } |
184 | #else | 173 | #else |
185 | #define lcd_write(d,rs) if (rs) *(volatile uint8_t*)(LCD_IO_DATA) = d; else *(volatile uint8_t*)(LCD_IO_FUNCTION) = d; | 174 | # define lcd_write(d, rs) \ |
175 | if (rs) \ | ||
176 | *(volatile uint8_t *)(LCD_IO_DATA) = d; \ | ||
177 | else \ | ||
178 | *(volatile uint8_t *)(LCD_IO_FUNCTION) = d; | ||
186 | /* rs==0 -> write instruction to LCD_IO_FUNCTION */ | 179 | /* rs==0 -> write instruction to LCD_IO_FUNCTION */ |
187 | /* rs==1 -> write data to LCD_IO_DATA */ | 180 | /* rs==1 -> write data to LCD_IO_DATA */ |
188 | #endif | 181 | #endif |
189 | 182 | ||
190 | |||
191 | /************************************************************************* | 183 | /************************************************************************* |
192 | Low-level function to read byte from LCD controller | 184 | Low-level function to read byte from LCD controller |
193 | Input: rs 1: read data | 185 | Input: rs 1: read data |
194 | 0: read busy flag / address counter | 186 | 0: read busy flag / address counter |
195 | Returns: byte read from LCD controller | 187 | Returns: byte read from LCD controller |
196 | *************************************************************************/ | 188 | *************************************************************************/ |
197 | #if LCD_IO_MODE | 189 | #if LCD_IO_MODE |
198 | static uint8_t lcd_read(uint8_t rs) | 190 | static uint8_t lcd_read(uint8_t rs) { |
199 | { | ||
200 | uint8_t data; | 191 | uint8_t data; |
201 | 192 | ||
202 | |||
203 | if (rs) | 193 | if (rs) |
204 | lcd_rs_high(); /* RS=1: read data */ | 194 | lcd_rs_high(); /* RS=1: read data */ |
205 | else | 195 | else |
206 | lcd_rs_low(); /* RS=0: read busy flag */ | 196 | lcd_rs_low(); /* RS=0: read busy flag */ |
207 | lcd_rw_high(); /* RW=1 read mode */ | 197 | lcd_rw_high(); /* RW=1 read mode */ |
208 | 198 | ||
209 | if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT ) | 199 | if ((&LCD_DATA0_PORT == &LCD_DATA1_PORT) && (&LCD_DATA1_PORT == &LCD_DATA2_PORT) && (&LCD_DATA2_PORT == &LCD_DATA3_PORT) && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3)) { |
210 | && ( LCD_DATA0_PIN == 0 )&& (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) ) | 200 | DDR(LCD_DATA0_PORT) &= 0xF0; /* configure data pins as input */ |
211 | { | 201 | |
212 | DDR(LCD_DATA0_PORT) &= 0xF0; /* configure data pins as input */ | ||
213 | |||
214 | lcd_e_high(); | 202 | lcd_e_high(); |
215 | lcd_e_delay(); | 203 | lcd_e_delay(); |
216 | data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */ | 204 | data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */ |
217 | lcd_e_low(); | 205 | lcd_e_low(); |
218 | 206 | ||
219 | lcd_e_delay(); /* Enable 500ns low */ | 207 | lcd_e_delay(); /* Enable 500ns low */ |
220 | 208 | ||
221 | lcd_e_high(); | 209 | lcd_e_high(); |
222 | lcd_e_delay(); | 210 | lcd_e_delay(); |
223 | data |= PIN(LCD_DATA0_PORT)&0x0F; /* read low nibble */ | 211 | data |= PIN(LCD_DATA0_PORT) & 0x0F; /* read low nibble */ |
224 | lcd_e_low(); | 212 | lcd_e_low(); |
225 | } | 213 | } else { |
226 | else | ||
227 | { | ||
228 | /* configure data pins as input */ | 214 | /* configure data pins as input */ |
229 | DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN); | 215 | DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN); |
230 | DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN); | 216 | DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN); |
231 | DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN); | 217 | DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN); |
232 | DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN); | 218 | DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN); |
233 | 219 | ||
234 | /* read high nibble first */ | 220 | /* read high nibble first */ |
235 | lcd_e_high(); | 221 | lcd_e_high(); |
236 | lcd_e_delay(); | 222 | lcd_e_delay(); |
237 | data = 0; | 223 | data = 0; |
238 | if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x10; | 224 | if (PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN)) data |= 0x10; |
239 | if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x20; | 225 | if (PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN)) data |= 0x20; |
240 | if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x40; | 226 | if (PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN)) data |= 0x40; |
241 | if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x80; | 227 | if (PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN)) data |= 0x80; |
242 | lcd_e_low(); | 228 | lcd_e_low(); |
243 | 229 | ||
244 | lcd_e_delay(); /* Enable 500ns low */ | 230 | lcd_e_delay(); /* Enable 500ns low */ |
245 | 231 | ||
246 | /* read low nibble */ | 232 | /* read low nibble */ |
247 | lcd_e_high(); | 233 | lcd_e_high(); |
248 | lcd_e_delay(); | 234 | lcd_e_delay(); |
249 | if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x01; | 235 | if (PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN)) data |= 0x01; |
250 | if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x02; | 236 | if (PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN)) data |= 0x02; |
251 | if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x04; | 237 | if (PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN)) data |= 0x04; |
252 | if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x08; | 238 | if (PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN)) data |= 0x08; |
253 | lcd_e_low(); | 239 | lcd_e_low(); |
254 | } | 240 | } |
255 | return data; | 241 | return data; |
256 | } | 242 | } |
257 | #else | 243 | #else |
258 | #define lcd_read(rs) (rs) ? *(volatile uint8_t*)(LCD_IO_DATA+LCD_IO_READ) : *(volatile uint8_t*)(LCD_IO_FUNCTION+LCD_IO_READ) | 244 | # define lcd_read(rs) (rs) ? *(volatile uint8_t *)(LCD_IO_DATA + LCD_IO_READ) : *(volatile uint8_t *)(LCD_IO_FUNCTION + LCD_IO_READ) |
259 | /* rs==0 -> read instruction from LCD_IO_FUNCTION */ | 245 | /* rs==0 -> read instruction from LCD_IO_FUNCTION */ |
260 | /* rs==1 -> read data from LCD_IO_DATA */ | 246 | /* rs==1 -> read data from LCD_IO_DATA */ |
261 | #endif | 247 | #endif |
262 | 248 | ||
263 | |||
264 | /************************************************************************* | 249 | /************************************************************************* |
265 | loops while lcd is busy, returns address counter | 250 | loops while lcd is busy, returns address counter |
266 | *************************************************************************/ | 251 | *************************************************************************/ |
@@ -268,65 +253,62 @@ static uint8_t lcd_waitbusy(void) | |||
268 | 253 | ||
269 | { | 254 | { |
270 | register uint8_t c; | 255 | register uint8_t c; |
271 | 256 | ||
272 | /* wait until busy flag is cleared */ | 257 | /* wait until busy flag is cleared */ |
273 | while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {} | 258 | while ((c = lcd_read(0)) & (1 << LCD_BUSY)) { |
274 | 259 | } | |
260 | |||
275 | /* the address counter is updated 4us after the busy flag is cleared */ | 261 | /* the address counter is updated 4us after the busy flag is cleared */ |
276 | delay(LCD_DELAY_BUSY_FLAG); | 262 | delay(LCD_DELAY_BUSY_FLAG); |
277 | 263 | ||
278 | /* now read the address counter */ | 264 | /* now read the address counter */ |
279 | return (lcd_read(0)); // return address counter | 265 | return (lcd_read(0)); // return address counter |
280 | |||
281 | }/* lcd_waitbusy */ | ||
282 | 266 | ||
267 | } /* lcd_waitbusy */ | ||
283 | 268 | ||
284 | /************************************************************************* | 269 | /************************************************************************* |
285 | Move cursor to the start of next line or to the first line if the cursor | 270 | Move cursor to the start of next line or to the first line if the cursor |
286 | is already on the last line. | 271 | is already on the last line. |
287 | *************************************************************************/ | 272 | *************************************************************************/ |
288 | static inline void lcd_newline(uint8_t pos) | 273 | static inline void lcd_newline(uint8_t pos) { |
289 | { | ||
290 | register uint8_t addressCounter; | 274 | register uint8_t addressCounter; |
291 | 275 | ||
292 | 276 | #if LCD_LINES == 1 | |
293 | #if LCD_LINES==1 | ||
294 | addressCounter = 0; | 277 | addressCounter = 0; |
295 | #endif | 278 | #endif |
296 | #if LCD_LINES==2 | 279 | #if LCD_LINES == 2 |
297 | if ( pos < (LCD_START_LINE2) ) | 280 | if (pos < (LCD_START_LINE2)) |
298 | addressCounter = LCD_START_LINE2; | 281 | addressCounter = LCD_START_LINE2; |
299 | else | 282 | else |
300 | addressCounter = LCD_START_LINE1; | 283 | addressCounter = LCD_START_LINE1; |
301 | #endif | 284 | #endif |
302 | #if LCD_LINES==4 | 285 | #if LCD_LINES == 4 |
303 | #if KS0073_4LINES_MODE | 286 | # if KS0073_4LINES_MODE |
304 | if ( pos < LCD_START_LINE2 ) | 287 | if (pos < LCD_START_LINE2) |
305 | addressCounter = LCD_START_LINE2; | 288 | addressCounter = LCD_START_LINE2; |
306 | else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3) ) | 289 | else if ((pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3)) |
307 | addressCounter = LCD_START_LINE3; | 290 | addressCounter = LCD_START_LINE3; |
308 | else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4) ) | 291 | else if ((pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4)) |
309 | addressCounter = LCD_START_LINE4; | 292 | addressCounter = LCD_START_LINE4; |
310 | else | 293 | else |
311 | addressCounter = LCD_START_LINE1; | 294 | addressCounter = LCD_START_LINE1; |
312 | #else | 295 | # else |
313 | if ( pos < LCD_START_LINE3 ) | 296 | if (pos < LCD_START_LINE3) |
314 | addressCounter = LCD_START_LINE2; | 297 | addressCounter = LCD_START_LINE2; |
315 | else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) ) | 298 | else if ((pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4)) |
316 | addressCounter = LCD_START_LINE3; | 299 | addressCounter = LCD_START_LINE3; |
317 | else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) ) | 300 | else if ((pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2)) |
318 | addressCounter = LCD_START_LINE4; | 301 | addressCounter = LCD_START_LINE4; |
319 | else | 302 | else |
320 | addressCounter = LCD_START_LINE1; | 303 | addressCounter = LCD_START_LINE1; |
304 | # endif | ||
321 | #endif | 305 | #endif |
322 | #endif | 306 | lcd_command((1 << LCD_DDRAM) + addressCounter); |
323 | lcd_command((1<<LCD_DDRAM)+addressCounter); | ||
324 | |||
325 | }/* lcd_newline */ | ||
326 | 307 | ||
308 | } /* lcd_newline */ | ||
327 | 309 | ||
328 | /* | 310 | /* |
329 | ** PUBLIC FUNCTIONS | 311 | ** PUBLIC FUNCTIONS |
330 | */ | 312 | */ |
331 | 313 | ||
332 | /************************************************************************* | 314 | /************************************************************************* |
@@ -334,132 +316,107 @@ Send LCD controller instruction command | |||
334 | Input: instruction to send to LCD controller, see HD44780 data sheet | 316 | Input: instruction to send to LCD controller, see HD44780 data sheet |
335 | Returns: none | 317 | Returns: none |
336 | *************************************************************************/ | 318 | *************************************************************************/ |
337 | void lcd_command(uint8_t cmd) | 319 | void lcd_command(uint8_t cmd) { |
338 | { | ||
339 | lcd_waitbusy(); | 320 | lcd_waitbusy(); |
340 | lcd_write(cmd,0); | 321 | lcd_write(cmd, 0); |
341 | } | 322 | } |
342 | 323 | ||
343 | |||
344 | /************************************************************************* | 324 | /************************************************************************* |
345 | Send data byte to LCD controller | 325 | Send data byte to LCD controller |
346 | Input: data to send to LCD controller, see HD44780 data sheet | 326 | Input: data to send to LCD controller, see HD44780 data sheet |
347 | Returns: none | 327 | Returns: none |
348 | *************************************************************************/ | 328 | *************************************************************************/ |
349 | void lcd_data(uint8_t data) | 329 | void lcd_data(uint8_t data) { |
350 | { | ||
351 | lcd_waitbusy(); | 330 | lcd_waitbusy(); |
352 | lcd_write(data,1); | 331 | lcd_write(data, 1); |
353 | } | 332 | } |
354 | 333 | ||
355 | |||
356 | |||
357 | /************************************************************************* | 334 | /************************************************************************* |
358 | Set cursor to specified position | 335 | Set cursor to specified position |
359 | Input: x horizontal position (0: left most position) | 336 | Input: x horizontal position (0: left most position) |
360 | y vertical position (0: first line) | 337 | y vertical position (0: first line) |
361 | Returns: none | 338 | Returns: none |
362 | *************************************************************************/ | 339 | *************************************************************************/ |
363 | void lcd_gotoxy(uint8_t x, uint8_t y) | 340 | void lcd_gotoxy(uint8_t x, uint8_t y) { |
364 | { | 341 | #if LCD_LINES == 1 |
365 | #if LCD_LINES==1 | 342 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x); |
366 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x); | ||
367 | #endif | 343 | #endif |
368 | #if LCD_LINES==2 | 344 | #if LCD_LINES == 2 |
369 | if ( y==0 ) | 345 | if (y == 0) |
370 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x); | 346 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x); |
371 | else | 347 | else |
372 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x); | 348 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x); |
373 | #endif | 349 | #endif |
374 | #if LCD_LINES==4 | 350 | #if LCD_LINES == 4 |
375 | if ( y==0 ) | 351 | if (y == 0) |
376 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x); | 352 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x); |
377 | else if ( y==1) | 353 | else if (y == 1) |
378 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x); | 354 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x); |
379 | else if ( y==2) | 355 | else if (y == 2) |
380 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x); | 356 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x); |
381 | else /* y==3 */ | 357 | else /* y==3 */ |
382 | lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x); | 358 | lcd_command((1 << LCD_DDRAM) + LCD_START_LINE4 + x); |
383 | #endif | 359 | #endif |
384 | 360 | ||
385 | }/* lcd_gotoxy */ | 361 | } /* lcd_gotoxy */ |
386 | |||
387 | 362 | ||
388 | /************************************************************************* | 363 | /************************************************************************* |
389 | *************************************************************************/ | 364 | *************************************************************************/ |
390 | int lcd_getxy(void) | 365 | int lcd_getxy(void) { return lcd_waitbusy(); } |
391 | { | ||
392 | return lcd_waitbusy(); | ||
393 | } | ||
394 | |||
395 | 366 | ||
396 | /************************************************************************* | 367 | /************************************************************************* |
397 | Clear display and set cursor to home position | 368 | Clear display and set cursor to home position |
398 | *************************************************************************/ | 369 | *************************************************************************/ |
399 | void lcd_clrscr(void) | 370 | void lcd_clrscr(void) { lcd_command(1 << LCD_CLR); } |
400 | { | ||
401 | lcd_command(1<<LCD_CLR); | ||
402 | } | ||
403 | |||
404 | 371 | ||
405 | /************************************************************************* | 372 | /************************************************************************* |
406 | Set cursor to home position | 373 | Set cursor to home position |
407 | *************************************************************************/ | 374 | *************************************************************************/ |
408 | void lcd_home(void) | 375 | void lcd_home(void) { lcd_command(1 << LCD_HOME); } |
409 | { | ||
410 | lcd_command(1<<LCD_HOME); | ||
411 | } | ||
412 | |||
413 | 376 | ||
414 | /************************************************************************* | 377 | /************************************************************************* |
415 | Display character at current cursor position | 378 | Display character at current cursor position |
416 | Input: character to be displayed | 379 | Input: character to be displayed |
417 | Returns: none | 380 | Returns: none |
418 | *************************************************************************/ | 381 | *************************************************************************/ |
419 | void lcd_putc(char c) | 382 | void lcd_putc(char c) { |
420 | { | ||
421 | uint8_t pos; | 383 | uint8_t pos; |
422 | 384 | ||
423 | 385 | pos = lcd_waitbusy(); // read busy-flag and address counter | |
424 | pos = lcd_waitbusy(); // read busy-flag and address counter | 386 | if (c == '\n') { |
425 | if (c=='\n') | ||
426 | { | ||
427 | lcd_newline(pos); | 387 | lcd_newline(pos); |
428 | } | 388 | } else { |
429 | else | 389 | #if LCD_WRAP_LINES == 1 |
430 | { | 390 | # if LCD_LINES == 1 |
431 | #if LCD_WRAP_LINES==1 | 391 | if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) { |
432 | #if LCD_LINES==1 | 392 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0); |
433 | if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) { | ||
434 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0); | ||
435 | } | 393 | } |
436 | #elif LCD_LINES==2 | 394 | # elif LCD_LINES == 2 |
437 | if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) { | 395 | if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) { |
438 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0); | 396 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0); |
439 | }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){ | 397 | } else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) { |
440 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0); | 398 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0); |
441 | } | 399 | } |
442 | #elif LCD_LINES==4 | 400 | # elif LCD_LINES == 4 |
443 | if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) { | 401 | if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) { |
444 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0); | 402 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0); |
445 | }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) { | 403 | } else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) { |
446 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0); | 404 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE3, 0); |
447 | }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) { | 405 | } else if (pos == LCD_START_LINE3 + LCD_DISP_LENGTH) { |
448 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0); | 406 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE4, 0); |
449 | }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) { | 407 | } else if (pos == LCD_START_LINE4 + LCD_DISP_LENGTH) { |
450 | lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0); | 408 | lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0); |
451 | } | 409 | } |
452 | #endif | 410 | # endif |
453 | lcd_waitbusy(); | 411 | lcd_waitbusy(); |
454 | #endif | 412 | #endif |
455 | lcd_write(c, 1); | 413 | lcd_write(c, 1); |
456 | } | 414 | } |
457 | 415 | ||
458 | }/* lcd_putc */ | 416 | } /* lcd_putc */ |
459 | |||
460 | 417 | ||
461 | /************************************************************************* | 418 | /************************************************************************* |
462 | Display string without auto linefeed | 419 | Display string without auto linefeed |
463 | Input: string to be displayed | 420 | Input: string to be displayed |
464 | Returns: none | 421 | Returns: none |
465 | *************************************************************************/ | 422 | *************************************************************************/ |
@@ -468,16 +425,15 @@ void lcd_puts(const char *s) | |||
468 | { | 425 | { |
469 | register char c; | 426 | register char c; |
470 | 427 | ||
471 | while ( (c = *s++) ) { | 428 | while ((c = *s++)) { |
472 | lcd_putc(c); | 429 | lcd_putc(c); |
473 | } | 430 | } |
474 | 431 | ||
475 | }/* lcd_puts */ | 432 | } /* lcd_puts */ |
476 | |||
477 | 433 | ||
478 | /************************************************************************* | 434 | /************************************************************************* |
479 | Display string from program memory without auto linefeed | 435 | Display string from program memory without auto linefeed |
480 | Input: string from program memory be be displayed | 436 | Input: string from program memory be be displayed |
481 | Returns: none | 437 | Returns: none |
482 | *************************************************************************/ | 438 | *************************************************************************/ |
483 | void lcd_puts_p(const char *progmem_s) | 439 | void lcd_puts_p(const char *progmem_s) |
@@ -485,108 +441,96 @@ void lcd_puts_p(const char *progmem_s) | |||
485 | { | 441 | { |
486 | register char c; | 442 | register char c; |
487 | 443 | ||
488 | while ( (c = pgm_read_byte(progmem_s++)) ) { | 444 | while ((c = pgm_read_byte(progmem_s++))) { |
489 | lcd_putc(c); | 445 | lcd_putc(c); |
490 | } | 446 | } |
491 | 447 | ||
492 | }/* lcd_puts_p */ | 448 | } /* lcd_puts_p */ |
493 | |||
494 | 449 | ||
495 | /************************************************************************* | 450 | /************************************************************************* |
496 | Initialize display and select type of cursor | 451 | Initialize display and select type of cursor |
497 | Input: dispAttr LCD_DISP_OFF display off | 452 | Input: dispAttr LCD_DISP_OFF display off |
498 | LCD_DISP_ON display on, cursor off | 453 | LCD_DISP_ON display on, cursor off |
499 | LCD_DISP_ON_CURSOR display on, cursor on | 454 | LCD_DISP_ON_CURSOR display on, cursor on |
500 | LCD_DISP_CURSOR_BLINK display on, cursor on flashing | 455 | LCD_DISP_CURSOR_BLINK display on, cursor on flashing |
501 | Returns: none | 456 | Returns: none |
502 | *************************************************************************/ | 457 | *************************************************************************/ |
503 | void lcd_init(uint8_t dispAttr) | 458 | void lcd_init(uint8_t dispAttr) { |
504 | { | ||
505 | #if LCD_IO_MODE | 459 | #if LCD_IO_MODE |
506 | /* | 460 | /* |
507 | * Initialize LCD to 4 bit I/O mode | 461 | * Initialize LCD to 4 bit I/O mode |
508 | */ | 462 | */ |
509 | 463 | ||
510 | if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT ) | 464 | if ((&LCD_DATA0_PORT == &LCD_DATA1_PORT) && (&LCD_DATA1_PORT == &LCD_DATA2_PORT) && (&LCD_DATA2_PORT == &LCD_DATA3_PORT) && (&LCD_RS_PORT == &LCD_DATA0_PORT) && (&LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT) && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) && (LCD_RS_PIN == 4) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6)) { |
511 | && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT) | ||
512 | && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) | ||
513 | && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) ) | ||
514 | { | ||
515 | /* configure all port bits as output (all LCD lines on same port) */ | 465 | /* configure all port bits as output (all LCD lines on same port) */ |
516 | DDR(LCD_DATA0_PORT) |= 0x7F; | 466 | DDR(LCD_DATA0_PORT) |= 0x7F; |
517 | } | 467 | } else if ((&LCD_DATA0_PORT == &LCD_DATA1_PORT) && (&LCD_DATA1_PORT == &LCD_DATA2_PORT) && (&LCD_DATA2_PORT == &LCD_DATA3_PORT) && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3)) { |
518 | else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT ) | ||
519 | && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) ) | ||
520 | { | ||
521 | /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */ | 468 | /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */ |
522 | DDR(LCD_DATA0_PORT) |= 0x0F; | 469 | DDR(LCD_DATA0_PORT) |= 0x0F; |
523 | DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN); | 470 | DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN); |
524 | DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN); | 471 | DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN); |
525 | DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); | 472 | DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); |
526 | } | 473 | } else { |
527 | else | ||
528 | { | ||
529 | /* configure all port bits as output (LCD data and control lines on different ports */ | 474 | /* configure all port bits as output (LCD data and control lines on different ports */ |
530 | DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN); | 475 | DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN); |
531 | DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN); | 476 | DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN); |
532 | DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); | 477 | DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); |
533 | DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN); | 478 | DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN); |
534 | DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN); | 479 | DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN); |
535 | DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN); | 480 | DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN); |
536 | DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN); | 481 | DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN); |
537 | } | 482 | } |
538 | delay(LCD_DELAY_BOOTUP); /* wait 16ms or more after power-on */ | 483 | delay(LCD_DELAY_BOOTUP); /* wait 16ms or more after power-on */ |
539 | 484 | ||
540 | /* initial write to lcd is 8bit */ | 485 | /* initial write to lcd is 8bit */ |
541 | LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4; | 486 | LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4; |
542 | LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4; | 487 | LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4; |
488 | lcd_e_toggle(); | ||
489 | delay(LCD_DELAY_INIT); /* delay, busy flag can't be checked here */ | ||
490 | |||
491 | /* repeat last command */ | ||
543 | lcd_e_toggle(); | 492 | lcd_e_toggle(); |
544 | delay(LCD_DELAY_INIT); /* delay, busy flag can't be checked here */ | 493 | delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */ |
545 | 494 | ||
546 | /* repeat last command */ | ||
547 | lcd_e_toggle(); | ||
548 | delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */ | ||
549 | |||
550 | /* repeat last command a third time */ | 495 | /* repeat last command a third time */ |
551 | lcd_e_toggle(); | 496 | lcd_e_toggle(); |
552 | delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */ | 497 | delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */ |
553 | 498 | ||
554 | /* now configure for 4bit mode */ | 499 | /* now configure for 4bit mode */ |
555 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4 | 500 | LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4 |
556 | lcd_e_toggle(); | 501 | lcd_e_toggle(); |
557 | delay(LCD_DELAY_INIT_4BIT); /* some displays need this additional delay */ | 502 | delay(LCD_DELAY_INIT_4BIT); /* some displays need this additional delay */ |
558 | 503 | ||
559 | /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */ | 504 | /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */ |
560 | #else | 505 | #else |
561 | /* | 506 | /* |
562 | * Initialize LCD to 8 bit memory mapped mode | 507 | * Initialize LCD to 8 bit memory mapped mode |
563 | */ | 508 | */ |
564 | 509 | ||
565 | /* enable external SRAM (memory mapped lcd) and one wait state */ | 510 | /* enable external SRAM (memory mapped lcd) and one wait state */ |
566 | MCUCR = _BV(SRE) | _BV(SRW); | 511 | MCUCR = _BV(SRE) | _BV(SRW); |
567 | 512 | ||
568 | /* reset LCD */ | 513 | /* reset LCD */ |
569 | delay(LCD_DELAY_BOOTUP); /* wait 16ms after power-on */ | 514 | delay(LCD_DELAY_BOOTUP); /* wait 16ms after power-on */ |
570 | lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */ | 515 | lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */ |
571 | delay(LCD_DELAY_INIT); /* wait 5ms */ | 516 | delay(LCD_DELAY_INIT); /* wait 5ms */ |
572 | lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */ | 517 | lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */ |
573 | delay(LCD_DELAY_INIT_REP); /* wait 64us */ | 518 | delay(LCD_DELAY_INIT_REP); /* wait 64us */ |
574 | lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */ | 519 | lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */ |
575 | delay(LCD_DELAY_INIT_REP); /* wait 64us */ | 520 | delay(LCD_DELAY_INIT_REP); /* wait 64us */ |
576 | #endif | 521 | #endif |
577 | 522 | ||
578 | #if KS0073_4LINES_MODE | 523 | #if KS0073_4LINES_MODE |
579 | /* Display with KS0073 controller requires special commands for enabling 4 line mode */ | 524 | /* Display with KS0073 controller requires special commands for enabling 4 line mode */ |
580 | lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON); | 525 | lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON); |
581 | lcd_command(KS0073_4LINES_MODE); | 526 | lcd_command(KS0073_4LINES_MODE); |
582 | lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF); | 527 | lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF); |
583 | #else | 528 | #else |
584 | lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */ | 529 | lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */ |
585 | #endif | 530 | #endif |
586 | lcd_command(LCD_DISP_OFF); /* display off */ | 531 | lcd_command(LCD_DISP_OFF); /* display off */ |
587 | lcd_clrscr(); /* display clear */ | 532 | lcd_clrscr(); /* display clear */ |
588 | lcd_command(LCD_MODE_DEFAULT); /* set entry mode */ | 533 | lcd_command(LCD_MODE_DEFAULT); /* set entry mode */ |
589 | lcd_command(dispAttr); /* display/cursor control */ | 534 | lcd_command(dispAttr); /* display/cursor control */ |
590 | |||
591 | }/* lcd_init */ | ||
592 | 535 | ||
536 | } /* lcd_init */ | ||
diff --git a/drivers/avr/hd44780.h b/drivers/avr/hd44780.h index 7421c8131..e60817e98 100644 --- a/drivers/avr/hd44780.h +++ b/drivers/avr/hd44780.h | |||
@@ -6,7 +6,7 @@ | |||
6 | License: GNU General Public License Version 3 | 6 | License: GNU General Public License Version 3 |
7 | File: $Id: lcd.h,v 1.14.2.4 2015/01/20 17:16:07 peter Exp $ | 7 | File: $Id: lcd.h,v 1.14.2.4 2015/01/20 17:16:07 peter Exp $ |
8 | Software: AVR-GCC 4.x | 8 | Software: AVR-GCC 4.x |
9 | Hardware: any AVR device, memory mapped mode only for AVR with | 9 | Hardware: any AVR device, memory mapped mode only for AVR with |
10 | memory mapped interface (AT90S8515/ATmega8515/ATmega128) | 10 | memory mapped interface (AT90S8515/ATmega8515/ATmega128) |
11 | ***************************************************************************/ | 11 | ***************************************************************************/ |
12 | 12 | ||
@@ -15,333 +15,315 @@ | |||
15 | Collection of libraries for AVR-GCC | 15 | Collection of libraries for AVR-GCC |
16 | @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury | 16 | @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury |
17 | @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 | 17 | @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 |
18 | 18 | ||
19 | @file | 19 | @file |
20 | @defgroup pfleury_lcd LCD library <lcd.h> | 20 | @defgroup pfleury_lcd LCD library <lcd.h> |
21 | @code #include <lcd.h> @endcode | 21 | @code #include <lcd.h> @endcode |
22 | 22 | ||
23 | @brief Basic routines for interfacing a HD44780U-based character LCD display | 23 | @brief Basic routines for interfacing a HD44780U-based character LCD display |
24 | 24 | ||
25 | LCD character displays can be found in many devices, like espresso machines, laser printers. | 25 | LCD character displays can be found in many devices, like espresso machines, laser printers. |
26 | The Hitachi HD44780 controller and its compatible controllers like Samsung KS0066U have become an industry standard for these types of displays. | 26 | The Hitachi HD44780 controller and its compatible controllers like Samsung KS0066U have become an industry standard for these types of displays. |
27 | 27 | ||
28 | This library allows easy interfacing with a HD44780 compatible display and can be | 28 | This library allows easy interfacing with a HD44780 compatible display and can be |
29 | operated in memory mapped mode (LCD_IO_MODE defined as 0 in the include file lcd.h.) or in | 29 | operated in memory mapped mode (LCD_IO_MODE defined as 0 in the include file lcd.h.) or in |
30 | 4-bit IO port mode (LCD_IO_MODE defined as 1). 8-bit IO port mode is not supported. | 30 | 4-bit IO port mode (LCD_IO_MODE defined as 1). 8-bit IO port mode is not supported. |
31 | 31 | ||
32 | Memory mapped mode is compatible with old Kanda STK200 starter kit, but also supports | 32 | Memory mapped mode is compatible with old Kanda STK200 starter kit, but also supports |
33 | generation of R/W signal through A8 address line. | 33 | generation of R/W signal through A8 address line. |
34 | 34 | ||
35 | @see The chapter <a href=" http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html" target="_blank">Interfacing a HD44780 Based LCD to an AVR</a> | 35 | @see The chapter <a href=" http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html" target="_blank">Interfacing a HD44780 Based LCD to an AVR</a> |
36 | on my home page, which shows example circuits how to connect an LCD to an AVR controller. | 36 | on my home page, which shows example circuits how to connect an LCD to an AVR controller. |
37 | 37 | ||
38 | @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury | 38 | @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury |
39 | 39 | ||
40 | @version 2.0 | 40 | @version 2.0 |
41 | 41 | ||
42 | @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 | 42 | @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 |
43 | 43 | ||
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <inttypes.h> | 46 | #include <inttypes.h> |
47 | #include <avr/pgmspace.h> | 47 | #include <avr/pgmspace.h> |
48 | 48 | ||
49 | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 405 | 49 | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 405 |
50 | #error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !" | 50 | # error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !" |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | |||
54 | /**@{*/ | 53 | /**@{*/ |
55 | 54 | ||
56 | /* | 55 | /* |
57 | * LCD and target specific definitions below can be defined in a separate include file with name lcd_definitions.h instead modifying this file | 56 | * LCD and target specific definitions below can be defined in a separate include file with name lcd_definitions.h instead modifying this file |
58 | * by adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile | 57 | * by adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile |
59 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h | 58 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h |
60 | */ | 59 | */ |
61 | #ifdef _LCD_DEFINITIONS_FILE | 60 | #ifdef _LCD_DEFINITIONS_FILE |
62 | #include "lcd_definitions.h" | 61 | # include "lcd_definitions.h" |
63 | #endif | 62 | #endif |
64 | 63 | ||
65 | |||
66 | /** | 64 | /** |
67 | * @name Definition for LCD controller type | 65 | * @name Definition for LCD controller type |
68 | * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller. | 66 | * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller. |
69 | */ | 67 | */ |
70 | #ifndef LCD_CONTROLLER_KS0073 | 68 | #ifndef LCD_CONTROLLER_KS0073 |
71 | #define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */ | 69 | # define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */ |
72 | #endif | 70 | #endif |
73 | 71 | ||
74 | /** | 72 | /** |
75 | * @name Definitions for Display Size | 73 | * @name Definitions for Display Size |
76 | * Change these definitions to adapt setting to your display | 74 | * Change these definitions to adapt setting to your display |
77 | * | 75 | * |
78 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by | 76 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by |
79 | * adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile. | 77 | * adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile. |
80 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h | 78 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h |
81 | * | 79 | * |
82 | */ | 80 | */ |
83 | #ifndef LCD_LINES | 81 | #ifndef LCD_LINES |
84 | #define LCD_LINES 2 /**< number of visible lines of the display */ | 82 | # define LCD_LINES 2 /**< number of visible lines of the display */ |
85 | #endif | 83 | #endif |
86 | #ifndef LCD_DISP_LENGTH | 84 | #ifndef LCD_DISP_LENGTH |
87 | #define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */ | 85 | # define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */ |
88 | #endif | 86 | #endif |
89 | #ifndef LCD_LINE_LENGTH | 87 | #ifndef LCD_LINE_LENGTH |
90 | #define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */ | 88 | # define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */ |
91 | #endif | 89 | #endif |
92 | #ifndef LCD_START_LINE1 | 90 | #ifndef LCD_START_LINE1 |
93 | #define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */ | 91 | # define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */ |
94 | #endif | 92 | #endif |
95 | #ifndef LCD_START_LINE2 | 93 | #ifndef LCD_START_LINE2 |
96 | #define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */ | 94 | # define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */ |
97 | #endif | 95 | #endif |
98 | #ifndef LCD_START_LINE3 | 96 | #ifndef LCD_START_LINE3 |
99 | #define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */ | 97 | # define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */ |
100 | #endif | 98 | #endif |
101 | #ifndef LCD_START_LINE4 | 99 | #ifndef LCD_START_LINE4 |
102 | #define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */ | 100 | # define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */ |
103 | #endif | 101 | #endif |
104 | #ifndef LCD_WRAP_LINES | 102 | #ifndef LCD_WRAP_LINES |
105 | #define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */ | 103 | # define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */ |
106 | #endif | 104 | #endif |
107 | 105 | ||
108 | |||
109 | /** | 106 | /** |
110 | * @name Definitions for 4-bit IO mode | 107 | * @name Definitions for 4-bit IO mode |
111 | * | 108 | * |
112 | * The four LCD data lines and the three control lines RS, RW, E can be on the | 109 | * The four LCD data lines and the three control lines RS, RW, E can be on the |
113 | * same port or on different ports. | 110 | * same port or on different ports. |
114 | * Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on | 111 | * Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on |
115 | * different ports. | 112 | * different ports. |
116 | * | 113 | * |
117 | * Normally the four data lines should be mapped to bit 0..3 on one port, but it | 114 | * Normally the four data lines should be mapped to bit 0..3 on one port, but it |
118 | * is possible to connect these data lines in different order or even on different | 115 | * is possible to connect these data lines in different order or even on different |
119 | * ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions. | 116 | * ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions. |
120 | * | 117 | * |
121 | * Adjust these definitions to your target.\n | 118 | * Adjust these definitions to your target.\n |
122 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by | 119 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by |
123 | * adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile. | 120 | * adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile. |
124 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h | 121 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h |
125 | * | 122 | * |
126 | */ | 123 | */ |
127 | #define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */ | 124 | #define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */ |
128 | 125 | ||
129 | #if LCD_IO_MODE | 126 | #if LCD_IO_MODE |
130 | 127 | ||
131 | #ifndef LCD_PORT | 128 | # ifndef LCD_PORT |
132 | #define LCD_PORT PORTA /**< port for the LCD lines */ | 129 | # define LCD_PORT PORTA /**< port for the LCD lines */ |
133 | #endif | 130 | # endif |
134 | #ifndef LCD_DATA0_PORT | 131 | # ifndef LCD_DATA0_PORT |
135 | #define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */ | 132 | # define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */ |
136 | #endif | 133 | # endif |
137 | #ifndef LCD_DATA1_PORT | 134 | # ifndef LCD_DATA1_PORT |
138 | #define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */ | 135 | # define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */ |
139 | #endif | 136 | # endif |
140 | #ifndef LCD_DATA2_PORT | 137 | # ifndef LCD_DATA2_PORT |
141 | #define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */ | 138 | # define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */ |
142 | #endif | 139 | # endif |
143 | #ifndef LCD_DATA3_PORT | 140 | # ifndef LCD_DATA3_PORT |
144 | #define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */ | 141 | # define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */ |
145 | #endif | 142 | # endif |
146 | #ifndef LCD_DATA0_PIN | 143 | # ifndef LCD_DATA0_PIN |
147 | #define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */ | 144 | # define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */ |
148 | #endif | 145 | # endif |
149 | #ifndef LCD_DATA1_PIN | 146 | # ifndef LCD_DATA1_PIN |
150 | #define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */ | 147 | # define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */ |
151 | #endif | 148 | # endif |
152 | #ifndef LCD_DATA2_PIN | 149 | # ifndef LCD_DATA2_PIN |
153 | #define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */ | 150 | # define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */ |
154 | #endif | 151 | # endif |
155 | #ifndef LCD_DATA3_PIN | 152 | # ifndef LCD_DATA3_PIN |
156 | #define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */ | 153 | # define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */ |
157 | #endif | 154 | # endif |
158 | #ifndef LCD_RS_PORT | 155 | # ifndef LCD_RS_PORT |
159 | #define LCD_RS_PORT LCD_PORT /**< port for RS line */ | 156 | # define LCD_RS_PORT LCD_PORT /**< port for RS line */ |
160 | #endif | 157 | # endif |
161 | #ifndef LCD_RS_PIN | 158 | # ifndef LCD_RS_PIN |
162 | #define LCD_RS_PIN 3 /**< pin for RS line */ | 159 | # define LCD_RS_PIN 3 /**< pin for RS line */ |
163 | #endif | 160 | # endif |
164 | #ifndef LCD_RW_PORT | 161 | # ifndef LCD_RW_PORT |
165 | #define LCD_RW_PORT LCD_PORT /**< port for RW line */ | 162 | # define LCD_RW_PORT LCD_PORT /**< port for RW line */ |
166 | #endif | 163 | # endif |
167 | #ifndef LCD_RW_PIN | 164 | # ifndef LCD_RW_PIN |
168 | #define LCD_RW_PIN 2 /**< pin for RW line */ | 165 | # define LCD_RW_PIN 2 /**< pin for RW line */ |
169 | #endif | 166 | # endif |
170 | #ifndef LCD_E_PORT | 167 | # ifndef LCD_E_PORT |
171 | #define LCD_E_PORT LCD_PORT /**< port for Enable line */ | 168 | # define LCD_E_PORT LCD_PORT /**< port for Enable line */ |
172 | #endif | 169 | # endif |
173 | #ifndef LCD_E_PIN | 170 | # ifndef LCD_E_PIN |
174 | #define LCD_E_PIN 1 /**< pin for Enable line */ | 171 | # define LCD_E_PIN 1 /**< pin for Enable line */ |
175 | #endif | 172 | # endif |
176 | 173 | ||
177 | #elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \ | 174 | #elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega103__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega161__) || defined(__AVR_ATmega162__) |
178 | defined(__AVR_ATmega8515__)|| defined(__AVR_ATmega103__) || defined(__AVR_ATmega128__) || \ | ||
179 | defined(__AVR_ATmega161__) || defined(__AVR_ATmega162__) | ||
180 | /* | 175 | /* |
181 | * memory mapped mode is only supported when the device has an external data memory interface | 176 | * memory mapped mode is only supported when the device has an external data memory interface |
182 | */ | 177 | */ |
183 | #define LCD_IO_DATA 0xC000 /* A15=E=1, A14=RS=1 */ | 178 | # define LCD_IO_DATA 0xC000 /* A15=E=1, A14=RS=1 */ |
184 | #define LCD_IO_FUNCTION 0x8000 /* A15=E=1, A14=RS=0 */ | 179 | # define LCD_IO_FUNCTION 0x8000 /* A15=E=1, A14=RS=0 */ |
185 | #define LCD_IO_READ 0x0100 /* A8 =R/W=1 (R/W: 1=Read, 0=Write */ | 180 | # define LCD_IO_READ 0x0100 /* A8 =R/W=1 (R/W: 1=Read, 0=Write */ |
186 | 181 | ||
187 | #else | 182 | #else |
188 | #error "external data memory interface not available for this device, use 4-bit IO port mode" | 183 | # error "external data memory interface not available for this device, use 4-bit IO port mode" |
189 | 184 | ||
190 | #endif | 185 | #endif |
191 | 186 | ||
192 | |||
193 | /** | 187 | /** |
194 | * @name Definitions of delays | 188 | * @name Definitions of delays |
195 | * Used to calculate delay timers. | 189 | * Used to calculate delay timers. |
196 | * Adapt the F_CPU define in the Makefile to the clock frequency in Hz of your target | 190 | * Adapt the F_CPU define in the Makefile to the clock frequency in Hz of your target |
197 | * | 191 | * |
198 | * These delay times can be adjusted, if some displays require different delays.\n | 192 | * These delay times can be adjusted, if some displays require different delays.\n |
199 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by | 193 | * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by |
200 | * adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile. | 194 | * adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile. |
201 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h | 195 | * All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h |
202 | */ | 196 | */ |
203 | #ifndef LCD_DELAY_BOOTUP | 197 | #ifndef LCD_DELAY_BOOTUP |
204 | #define LCD_DELAY_BOOTUP 16000 /**< delay in micro seconds after power-on */ | 198 | # define LCD_DELAY_BOOTUP 16000 /**< delay in micro seconds after power-on */ |
205 | #endif | 199 | #endif |
206 | #ifndef LCD_DELAY_INIT | 200 | #ifndef LCD_DELAY_INIT |
207 | #define LCD_DELAY_INIT 5000 /**< delay in micro seconds after initialization command sent */ | 201 | # define LCD_DELAY_INIT 5000 /**< delay in micro seconds after initialization command sent */ |
208 | #endif | 202 | #endif |
209 | #ifndef LCD_DELAY_INIT_REP | 203 | #ifndef LCD_DELAY_INIT_REP |
210 | #define LCD_DELAY_INIT_REP 64 /**< delay in micro seconds after initialization command repeated */ | 204 | # define LCD_DELAY_INIT_REP 64 /**< delay in micro seconds after initialization command repeated */ |
211 | #endif | 205 | #endif |
212 | #ifndef LCD_DELAY_INIT_4BIT | 206 | #ifndef LCD_DELAY_INIT_4BIT |
213 | #define LCD_DELAY_INIT_4BIT 64 /**< delay in micro seconds after setting 4-bit mode */ | 207 | # define LCD_DELAY_INIT_4BIT 64 /**< delay in micro seconds after setting 4-bit mode */ |
214 | #endif | 208 | #endif |
215 | #ifndef LCD_DELAY_BUSY_FLAG | 209 | #ifndef LCD_DELAY_BUSY_FLAG |
216 | #define LCD_DELAY_BUSY_FLAG 4 /**< time in micro seconds the address counter is updated after busy flag is cleared */ | 210 | # define LCD_DELAY_BUSY_FLAG 4 /**< time in micro seconds the address counter is updated after busy flag is cleared */ |
217 | #endif | 211 | #endif |
218 | #ifndef LCD_DELAY_ENABLE_PULSE | 212 | #ifndef LCD_DELAY_ENABLE_PULSE |
219 | #define LCD_DELAY_ENABLE_PULSE 1 /**< enable signal pulse width in micro seconds */ | 213 | # define LCD_DELAY_ENABLE_PULSE 1 /**< enable signal pulse width in micro seconds */ |
220 | #endif | 214 | #endif |
221 | 215 | ||
222 | |||
223 | /** | 216 | /** |
224 | * @name Definitions for LCD command instructions | 217 | * @name Definitions for LCD command instructions |
225 | * The constants define the various LCD controller instructions which can be passed to the | 218 | * The constants define the various LCD controller instructions which can be passed to the |
226 | * function lcd_command(), see HD44780 data sheet for a complete description. | 219 | * function lcd_command(), see HD44780 data sheet for a complete description. |
227 | */ | 220 | */ |
228 | 221 | ||
229 | /* instruction register bit positions, see HD44780U data sheet */ | 222 | /* instruction register bit positions, see HD44780U data sheet */ |
230 | #define LCD_CLR 0 /* DB0: clear display */ | 223 | #define LCD_CLR 0 /* DB0: clear display */ |
231 | #define LCD_HOME 1 /* DB1: return to home position */ | 224 | #define LCD_HOME 1 /* DB1: return to home position */ |
232 | #define LCD_ENTRY_MODE 2 /* DB2: set entry mode */ | 225 | #define LCD_ENTRY_MODE 2 /* DB2: set entry mode */ |
233 | #define LCD_ENTRY_INC 1 /* DB1: 1=increment, 0=decrement */ | 226 | #define LCD_ENTRY_INC 1 /* DB1: 1=increment, 0=decrement */ |
234 | #define LCD_ENTRY_SHIFT 0 /* DB2: 1=display shift on */ | 227 | #define LCD_ENTRY_SHIFT 0 /* DB2: 1=display shift on */ |
235 | #define LCD_ON 3 /* DB3: turn lcd/cursor on */ | 228 | #define LCD_ON 3 /* DB3: turn lcd/cursor on */ |
236 | #define LCD_ON_DISPLAY 2 /* DB2: turn display on */ | 229 | #define LCD_ON_DISPLAY 2 /* DB2: turn display on */ |
237 | #define LCD_ON_CURSOR 1 /* DB1: turn cursor on */ | 230 | #define LCD_ON_CURSOR 1 /* DB1: turn cursor on */ |
238 | #define LCD_ON_BLINK 0 /* DB0: blinking cursor ? */ | 231 | #define LCD_ON_BLINK 0 /* DB0: blinking cursor ? */ |
239 | #define LCD_MOVE 4 /* DB4: move cursor/display */ | 232 | #define LCD_MOVE 4 /* DB4: move cursor/display */ |
240 | #define LCD_MOVE_DISP 3 /* DB3: move display (0-> cursor) ? */ | 233 | #define LCD_MOVE_DISP 3 /* DB3: move display (0-> cursor) ? */ |
241 | #define LCD_MOVE_RIGHT 2 /* DB2: move right (0-> left) ? */ | 234 | #define LCD_MOVE_RIGHT 2 /* DB2: move right (0-> left) ? */ |
242 | #define LCD_FUNCTION 5 /* DB5: function set */ | 235 | #define LCD_FUNCTION 5 /* DB5: function set */ |
243 | #define LCD_FUNCTION_8BIT 4 /* DB4: set 8BIT mode (0->4BIT mode) */ | 236 | #define LCD_FUNCTION_8BIT 4 /* DB4: set 8BIT mode (0->4BIT mode) */ |
244 | #define LCD_FUNCTION_2LINES 3 /* DB3: two lines (0->one line) */ | 237 | #define LCD_FUNCTION_2LINES 3 /* DB3: two lines (0->one line) */ |
245 | #define LCD_FUNCTION_10DOTS 2 /* DB2: 5x10 font (0->5x7 font) */ | 238 | #define LCD_FUNCTION_10DOTS 2 /* DB2: 5x10 font (0->5x7 font) */ |
246 | #define LCD_CGRAM 6 /* DB6: set CG RAM address */ | 239 | #define LCD_CGRAM 6 /* DB6: set CG RAM address */ |
247 | #define LCD_DDRAM 7 /* DB7: set DD RAM address */ | 240 | #define LCD_DDRAM 7 /* DB7: set DD RAM address */ |
248 | #define LCD_BUSY 7 /* DB7: LCD is busy */ | 241 | #define LCD_BUSY 7 /* DB7: LCD is busy */ |
249 | 242 | ||
250 | /* set entry mode: display shift on/off, dec/inc cursor move direction */ | 243 | /* set entry mode: display shift on/off, dec/inc cursor move direction */ |
251 | #define LCD_ENTRY_DEC 0x04 /* display shift off, dec cursor move dir */ | 244 | #define LCD_ENTRY_DEC 0x04 /* display shift off, dec cursor move dir */ |
252 | #define LCD_ENTRY_DEC_SHIFT 0x05 /* display shift on, dec cursor move dir */ | 245 | #define LCD_ENTRY_DEC_SHIFT 0x05 /* display shift on, dec cursor move dir */ |
253 | #define LCD_ENTRY_INC_ 0x06 /* display shift off, inc cursor move dir */ | 246 | #define LCD_ENTRY_INC_ 0x06 /* display shift off, inc cursor move dir */ |
254 | #define LCD_ENTRY_INC_SHIFT 0x07 /* display shift on, inc cursor move dir */ | 247 | #define LCD_ENTRY_INC_SHIFT 0x07 /* display shift on, inc cursor move dir */ |
255 | 248 | ||
256 | /* display on/off, cursor on/off, blinking char at cursor position */ | 249 | /* display on/off, cursor on/off, blinking char at cursor position */ |
257 | #define LCD_DISP_OFF 0x08 /* display off */ | 250 | #define LCD_DISP_OFF 0x08 /* display off */ |
258 | #define LCD_DISP_ON 0x0C /* display on, cursor off */ | 251 | #define LCD_DISP_ON 0x0C /* display on, cursor off */ |
259 | #define LCD_DISP_ON_BLINK 0x0D /* display on, cursor off, blink char */ | 252 | #define LCD_DISP_ON_BLINK 0x0D /* display on, cursor off, blink char */ |
260 | #define LCD_DISP_ON_CURSOR 0x0E /* display on, cursor on */ | 253 | #define LCD_DISP_ON_CURSOR 0x0E /* display on, cursor on */ |
261 | #define LCD_DISP_ON_CURSOR_BLINK 0x0F /* display on, cursor on, blink char */ | 254 | #define LCD_DISP_ON_CURSOR_BLINK 0x0F /* display on, cursor on, blink char */ |
262 | 255 | ||
263 | /* move cursor/shift display */ | 256 | /* move cursor/shift display */ |
264 | #define LCD_MOVE_CURSOR_LEFT 0x10 /* move cursor left (decrement) */ | 257 | #define LCD_MOVE_CURSOR_LEFT 0x10 /* move cursor left (decrement) */ |
265 | #define LCD_MOVE_CURSOR_RIGHT 0x14 /* move cursor right (increment) */ | 258 | #define LCD_MOVE_CURSOR_RIGHT 0x14 /* move cursor right (increment) */ |
266 | #define LCD_MOVE_DISP_LEFT 0x18 /* shift display left */ | 259 | #define LCD_MOVE_DISP_LEFT 0x18 /* shift display left */ |
267 | #define LCD_MOVE_DISP_RIGHT 0x1C /* shift display right */ | 260 | #define LCD_MOVE_DISP_RIGHT 0x1C /* shift display right */ |
268 | 261 | ||
269 | /* function set: set interface data length and number of display lines */ | 262 | /* function set: set interface data length and number of display lines */ |
270 | #define LCD_FUNCTION_4BIT_1LINE 0x20 /* 4-bit interface, single line, 5x7 dots */ | 263 | #define LCD_FUNCTION_4BIT_1LINE 0x20 /* 4-bit interface, single line, 5x7 dots */ |
271 | #define LCD_FUNCTION_4BIT_2LINES 0x28 /* 4-bit interface, dual line, 5x7 dots */ | 264 | #define LCD_FUNCTION_4BIT_2LINES 0x28 /* 4-bit interface, dual line, 5x7 dots */ |
272 | #define LCD_FUNCTION_8BIT_1LINE 0x30 /* 8-bit interface, single line, 5x7 dots */ | 265 | #define LCD_FUNCTION_8BIT_1LINE 0x30 /* 8-bit interface, single line, 5x7 dots */ |
273 | #define LCD_FUNCTION_8BIT_2LINES 0x38 /* 8-bit interface, dual line, 5x7 dots */ | 266 | #define LCD_FUNCTION_8BIT_2LINES 0x38 /* 8-bit interface, dual line, 5x7 dots */ |
274 | 267 | ||
268 | #define LCD_MODE_DEFAULT ((1 << LCD_ENTRY_MODE) | (1 << LCD_ENTRY_INC)) | ||
275 | 269 | ||
276 | #define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) ) | 270 | /** |
277 | |||
278 | |||
279 | |||
280 | /** | ||
281 | * @name Functions | 271 | * @name Functions |
282 | */ | 272 | */ |
283 | 273 | ||
284 | |||
285 | /** | 274 | /** |
286 | @brief Initialize display and select type of cursor | 275 | @brief Initialize display and select type of cursor |
287 | @param dispAttr \b LCD_DISP_OFF display off\n | 276 | @param dispAttr \b LCD_DISP_OFF display off\n |
288 | \b LCD_DISP_ON display on, cursor off\n | 277 | \b LCD_DISP_ON display on, cursor off\n |
289 | \b LCD_DISP_ON_CURSOR display on, cursor on\n | 278 | \b LCD_DISP_ON_CURSOR display on, cursor on\n |
290 | \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing | 279 | \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing |
291 | @return none | 280 | @return none |
292 | */ | 281 | */ |
293 | extern void lcd_init(uint8_t dispAttr); | 282 | extern void lcd_init(uint8_t dispAttr); |
294 | 283 | ||
295 | |||
296 | /** | 284 | /** |
297 | @brief Clear display and set cursor to home position | 285 | @brief Clear display and set cursor to home position |
298 | @return none | 286 | @return none |
299 | */ | 287 | */ |
300 | extern void lcd_clrscr(void); | 288 | extern void lcd_clrscr(void); |
301 | 289 | ||
302 | |||
303 | /** | 290 | /** |
304 | @brief Set cursor to home position | 291 | @brief Set cursor to home position |
305 | @return none | 292 | @return none |
306 | */ | 293 | */ |
307 | extern void lcd_home(void); | 294 | extern void lcd_home(void); |
308 | 295 | ||
309 | |||
310 | /** | 296 | /** |
311 | @brief Set cursor to specified position | 297 | @brief Set cursor to specified position |
312 | 298 | ||
313 | @param x horizontal position\n (0: left most position) | 299 | @param x horizontal position\n (0: left most position) |
314 | @param y vertical position\n (0: first line) | 300 | @param y vertical position\n (0: first line) |
315 | @return none | 301 | @return none |
316 | */ | 302 | */ |
317 | extern void lcd_gotoxy(uint8_t x, uint8_t y); | 303 | extern void lcd_gotoxy(uint8_t x, uint8_t y); |
318 | 304 | ||
319 | |||
320 | /** | 305 | /** |
321 | @brief Display character at current cursor position | 306 | @brief Display character at current cursor position |
322 | @param c character to be displayed | 307 | @param c character to be displayed |
323 | @return none | 308 | @return none |
324 | */ | 309 | */ |
325 | extern void lcd_putc(char c); | 310 | extern void lcd_putc(char c); |
326 | 311 | ||
327 | |||
328 | /** | 312 | /** |
329 | @brief Display string without auto linefeed | 313 | @brief Display string without auto linefeed |
330 | @param s string to be displayed | 314 | @param s string to be displayed |
331 | @return none | 315 | @return none |
332 | */ | 316 | */ |
333 | extern void lcd_puts(const char *s); | 317 | extern void lcd_puts(const char *s); |
334 | 318 | ||
335 | |||
336 | /** | 319 | /** |
337 | @brief Display string from program memory without auto linefeed | 320 | @brief Display string from program memory without auto linefeed |
338 | @param progmem_s string from program memory be be displayed | 321 | @param progmem_s string from program memory be be displayed |
339 | @return none | 322 | @return none |
340 | @see lcd_puts_P | 323 | @see lcd_puts_P |
341 | */ | 324 | */ |
342 | extern void lcd_puts_p(const char *progmem_s); | 325 | extern void lcd_puts_p(const char *progmem_s); |
343 | 326 | ||
344 | |||
345 | /** | 327 | /** |
346 | @brief Send LCD controller instruction command | 328 | @brief Send LCD controller instruction command |
347 | @param cmd instruction to send to LCD controller, see HD44780 data sheet | 329 | @param cmd instruction to send to LCD controller, see HD44780 data sheet |
@@ -349,23 +331,20 @@ extern void lcd_puts_p(const char *progmem_s); | |||
349 | */ | 331 | */ |
350 | extern void lcd_command(uint8_t cmd); | 332 | extern void lcd_command(uint8_t cmd); |
351 | 333 | ||
352 | |||
353 | /** | 334 | /** |
354 | @brief Send data byte to LCD controller | 335 | @brief Send data byte to LCD controller |
355 | 336 | ||
356 | Similar to lcd_putc(), but without interpreting LF | 337 | Similar to lcd_putc(), but without interpreting LF |
357 | @param data byte to send to LCD controller, see HD44780 data sheet | 338 | @param data byte to send to LCD controller, see HD44780 data sheet |
358 | @return none | 339 | @return none |
359 | */ | 340 | */ |
360 | extern void lcd_data(uint8_t data); | 341 | extern void lcd_data(uint8_t data); |
361 | 342 | ||
362 | |||
363 | /** | 343 | /** |
364 | @brief macros for automatically storing string constant in program memory | 344 | @brief macros for automatically storing string constant in program memory |
365 | */ | 345 | */ |
366 | #define lcd_puts_P(__s) lcd_puts_p(PSTR(__s)) | 346 | #define lcd_puts_P(__s) lcd_puts_p(PSTR(__s)) |
367 | 347 | ||
368 | /**@}*/ | 348 | /**@}*/ |
369 | 349 | ||
370 | #endif //LCD_H | 350 | #endif // LCD_H |
371 | |||
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c index 0acc24642..52924437e 100755..100644 --- a/drivers/avr/i2c_master.c +++ b/drivers/avr/i2c_master.c | |||
@@ -25,200 +25,200 @@ | |||
25 | #include "wait.h" | 25 | #include "wait.h" |
26 | 26 | ||
27 | #ifndef F_SCL | 27 | #ifndef F_SCL |
28 | # define F_SCL 400000UL // SCL frequency | 28 | # define F_SCL 400000UL // SCL frequency |
29 | #endif | 29 | #endif |
30 | #define Prescaler 1 | 30 | #define Prescaler 1 |
31 | #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16) / 2) | 31 | #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16) / 2) |
32 | 32 | ||
33 | void i2c_init(void) { | 33 | void i2c_init(void) { |
34 | TWSR = 0; /* no prescaler */ | 34 | TWSR = 0; /* no prescaler */ |
35 | TWBR = (uint8_t)TWBR_val; | 35 | TWBR = (uint8_t)TWBR_val; |
36 | 36 | ||
37 | #ifdef __AVR_ATmega32A__ | 37 | #ifdef __AVR_ATmega32A__ |
38 | // set pull-up resistors on I2C bus pins | 38 | // set pull-up resistors on I2C bus pins |
39 | PORTC |= 0b11; | 39 | PORTC |= 0b11; |
40 | 40 | ||
41 | // enable TWI (two-wire interface) | 41 | // enable TWI (two-wire interface) |
42 | TWCR |= (1 << TWEN); | 42 | TWCR |= (1 << TWEN); |
43 | 43 | ||
44 | // enable TWI interrupt and slave address ACK | 44 | // enable TWI interrupt and slave address ACK |
45 | TWCR |= (1 << TWIE); | 45 | TWCR |= (1 << TWIE); |
46 | TWCR |= (1 << TWEA); | 46 | TWCR |= (1 << TWEA); |
47 | #endif | 47 | #endif |
48 | } | 48 | } |
49 | 49 | ||
50 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { | 50 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { |
51 | // reset TWI control register | 51 | // reset TWI control register |
52 | TWCR = 0; | 52 | TWCR = 0; |
53 | // transmit START condition | 53 | // transmit START condition |
54 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); | 54 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); |
55 | 55 | ||
56 | uint16_t timeout_timer = timer_read(); | 56 | uint16_t timeout_timer = timer_read(); |
57 | while (!(TWCR & (1 << TWINT))) { | 57 | while (!(TWCR & (1 << TWINT))) { |
58 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 58 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
59 | return I2C_STATUS_TIMEOUT; | 59 | return I2C_STATUS_TIMEOUT; |
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | // check if the start condition was successfully transmitted | 63 | // check if the start condition was successfully transmitted |
64 | if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) { | 64 | if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) { |
65 | return I2C_STATUS_ERROR; | 65 | return I2C_STATUS_ERROR; |
66 | } | 66 | } |
67 | 67 | ||
68 | // load slave address into data register | 68 | // load slave address into data register |
69 | TWDR = address; | 69 | TWDR = address; |
70 | // start transmission of address | 70 | // start transmission of address |
71 | TWCR = (1 << TWINT) | (1 << TWEN); | 71 | TWCR = (1 << TWINT) | (1 << TWEN); |
72 | 72 | ||
73 | timeout_timer = timer_read(); | 73 | timeout_timer = timer_read(); |
74 | while (!(TWCR & (1 << TWINT))) { | 74 | while (!(TWCR & (1 << TWINT))) { |
75 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 75 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
76 | return I2C_STATUS_TIMEOUT; | 76 | return I2C_STATUS_TIMEOUT; |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | // check if the device has acknowledged the READ / WRITE mode | 80 | // check if the device has acknowledged the READ / WRITE mode |
81 | uint8_t twst = TW_STATUS & 0xF8; | 81 | uint8_t twst = TW_STATUS & 0xF8; |
82 | if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { | 82 | if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { |
83 | return I2C_STATUS_ERROR; | 83 | return I2C_STATUS_ERROR; |
84 | } | 84 | } |
85 | 85 | ||
86 | return I2C_STATUS_SUCCESS; | 86 | return I2C_STATUS_SUCCESS; |
87 | } | 87 | } |
88 | 88 | ||
89 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { | 89 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { |
90 | // load data into data register | 90 | // load data into data register |
91 | TWDR = data; | 91 | TWDR = data; |
92 | // start transmission of data | 92 | // start transmission of data |
93 | TWCR = (1 << TWINT) | (1 << TWEN); | 93 | TWCR = (1 << TWINT) | (1 << TWEN); |
94 | 94 | ||
95 | uint16_t timeout_timer = timer_read(); | 95 | uint16_t timeout_timer = timer_read(); |
96 | while (!(TWCR & (1 << TWINT))) { | 96 | while (!(TWCR & (1 << TWINT))) { |
97 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 97 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
98 | return I2C_STATUS_TIMEOUT; | 98 | return I2C_STATUS_TIMEOUT; |
99 | } | ||
99 | } | 100 | } |
100 | } | ||
101 | 101 | ||
102 | if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) { | 102 | if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) { |
103 | return I2C_STATUS_ERROR; | 103 | return I2C_STATUS_ERROR; |
104 | } | 104 | } |
105 | 105 | ||
106 | return I2C_STATUS_SUCCESS; | 106 | return I2C_STATUS_SUCCESS; |
107 | } | 107 | } |
108 | 108 | ||
109 | int16_t i2c_read_ack(uint16_t timeout) { | 109 | int16_t i2c_read_ack(uint16_t timeout) { |
110 | // start TWI module and acknowledge data after reception | 110 | // start TWI module and acknowledge data after reception |
111 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); | 111 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); |
112 | 112 | ||
113 | uint16_t timeout_timer = timer_read(); | 113 | uint16_t timeout_timer = timer_read(); |
114 | while (!(TWCR & (1 << TWINT))) { | 114 | while (!(TWCR & (1 << TWINT))) { |
115 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 115 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
116 | return I2C_STATUS_TIMEOUT; | 116 | return I2C_STATUS_TIMEOUT; |
117 | } | ||
117 | } | 118 | } |
118 | } | ||
119 | 119 | ||
120 | // return received data from TWDR | 120 | // return received data from TWDR |
121 | return TWDR; | 121 | return TWDR; |
122 | } | 122 | } |
123 | 123 | ||
124 | int16_t i2c_read_nack(uint16_t timeout) { | 124 | int16_t i2c_read_nack(uint16_t timeout) { |
125 | // start receiving without acknowledging reception | 125 | // start receiving without acknowledging reception |
126 | TWCR = (1 << TWINT) | (1 << TWEN); | 126 | TWCR = (1 << TWINT) | (1 << TWEN); |
127 | 127 | ||
128 | uint16_t timeout_timer = timer_read(); | 128 | uint16_t timeout_timer = timer_read(); |
129 | while (!(TWCR & (1 << TWINT))) { | 129 | while (!(TWCR & (1 << TWINT))) { |
130 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 130 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
131 | return I2C_STATUS_TIMEOUT; | 131 | return I2C_STATUS_TIMEOUT; |
132 | } | ||
132 | } | 133 | } |
133 | } | ||
134 | 134 | ||
135 | // return received data from TWDR | 135 | // return received data from TWDR |
136 | return TWDR; | 136 | return TWDR; |
137 | } | 137 | } |
138 | 138 | ||
139 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { | 139 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { |
140 | i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); | 140 | i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); |
141 | 141 | ||
142 | for (uint16_t i = 0; i < length && status >= 0; i++) { | 142 | for (uint16_t i = 0; i < length && status >= 0; i++) { |
143 | status = i2c_write(data[i], timeout); | 143 | status = i2c_write(data[i], timeout); |
144 | } | 144 | } |
145 | 145 | ||
146 | i2c_stop(); | 146 | i2c_stop(); |
147 | 147 | ||
148 | return status; | 148 | return status; |
149 | } | 149 | } |
150 | 150 | ||
151 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { | 151 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { |
152 | i2c_status_t status = i2c_start(address | I2C_READ, timeout); | 152 | i2c_status_t status = i2c_start(address | I2C_READ, timeout); |
153 | 153 | ||
154 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { | 154 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { |
155 | status = i2c_read_ack(timeout); | 155 | status = i2c_read_ack(timeout); |
156 | if (status >= 0) { | 156 | if (status >= 0) { |
157 | data[i] = status; | 157 | data[i] = status; |
158 | } | ||
158 | } | 159 | } |
159 | } | ||
160 | 160 | ||
161 | if (status >= 0) { | ||
162 | status = i2c_read_nack(timeout); | ||
163 | if (status >= 0) { | 161 | if (status >= 0) { |
164 | data[(length - 1)] = status; | 162 | status = i2c_read_nack(timeout); |
163 | if (status >= 0) { | ||
164 | data[(length - 1)] = status; | ||
165 | } | ||
165 | } | 166 | } |
166 | } | ||
167 | 167 | ||
168 | i2c_stop(); | 168 | i2c_stop(); |
169 | 169 | ||
170 | return (status < 0) ? status : I2C_STATUS_SUCCESS; | 170 | return (status < 0) ? status : I2C_STATUS_SUCCESS; |
171 | } | 171 | } |
172 | 172 | ||
173 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { | 173 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { |
174 | i2c_status_t status = i2c_start(devaddr | 0x00, timeout); | 174 | i2c_status_t status = i2c_start(devaddr | 0x00, timeout); |
175 | if (status >= 0) { | 175 | if (status >= 0) { |
176 | status = i2c_write(regaddr, timeout); | 176 | status = i2c_write(regaddr, timeout); |
177 | 177 | ||
178 | for (uint16_t i = 0; i < length && status >= 0; i++) { | 178 | for (uint16_t i = 0; i < length && status >= 0; i++) { |
179 | status = i2c_write(data[i], timeout); | 179 | status = i2c_write(data[i], timeout); |
180 | } | ||
180 | } | 181 | } |
181 | } | ||
182 | 182 | ||
183 | i2c_stop(); | 183 | i2c_stop(); |
184 | 184 | ||
185 | return status; | 185 | return status; |
186 | } | 186 | } |
187 | 187 | ||
188 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { | 188 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { |
189 | i2c_status_t status = i2c_start(devaddr, timeout); | 189 | i2c_status_t status = i2c_start(devaddr, timeout); |
190 | if (status < 0) { | 190 | if (status < 0) { |
191 | goto error; | 191 | goto error; |
192 | } | 192 | } |
193 | 193 | ||
194 | status = i2c_write(regaddr, timeout); | 194 | status = i2c_write(regaddr, timeout); |
195 | if (status < 0) { | 195 | if (status < 0) { |
196 | goto error; | 196 | goto error; |
197 | } | 197 | } |
198 | 198 | ||
199 | status = i2c_start(devaddr | 0x01, timeout); | 199 | status = i2c_start(devaddr | 0x01, timeout); |
200 | 200 | ||
201 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { | 201 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { |
202 | status = i2c_read_ack(timeout); | 202 | status = i2c_read_ack(timeout); |
203 | if (status >= 0) { | 203 | if (status >= 0) { |
204 | data[i] = status; | 204 | data[i] = status; |
205 | } | ||
205 | } | 206 | } |
206 | } | ||
207 | 207 | ||
208 | if (status >= 0) { | ||
209 | status = i2c_read_nack(timeout); | ||
210 | if (status >= 0) { | 208 | if (status >= 0) { |
211 | data[(length - 1)] = status; | 209 | status = i2c_read_nack(timeout); |
210 | if (status >= 0) { | ||
211 | data[(length - 1)] = status; | ||
212 | } | ||
212 | } | 213 | } |
213 | } | ||
214 | 214 | ||
215 | error: | 215 | error: |
216 | i2c_stop(); | 216 | i2c_stop(); |
217 | 217 | ||
218 | return (status < 0) ? status : I2C_STATUS_SUCCESS; | 218 | return (status < 0) ? status : I2C_STATUS_SUCCESS; |
219 | } | 219 | } |
220 | 220 | ||
221 | void i2c_stop(void) { | 221 | void i2c_stop(void) { |
222 | // transmit STOP condition | 222 | // transmit STOP condition |
223 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); | 223 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); |
224 | } | 224 | } |
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h index d68142430..0a3b6c508 100755..100644 --- a/drivers/avr/i2c_master.h +++ b/drivers/avr/i2c_master.h | |||
@@ -26,21 +26,21 @@ | |||
26 | typedef int16_t i2c_status_t; | 26 | typedef int16_t i2c_status_t; |
27 | 27 | ||
28 | #define I2C_STATUS_SUCCESS (0) | 28 | #define I2C_STATUS_SUCCESS (0) |
29 | #define I2C_STATUS_ERROR (-1) | 29 | #define I2C_STATUS_ERROR (-1) |
30 | #define I2C_STATUS_TIMEOUT (-2) | 30 | #define I2C_STATUS_TIMEOUT (-2) |
31 | 31 | ||
32 | #define I2C_TIMEOUT_IMMEDIATE (0) | 32 | #define I2C_TIMEOUT_IMMEDIATE (0) |
33 | #define I2C_TIMEOUT_INFINITE (0xFFFF) | 33 | #define I2C_TIMEOUT_INFINITE (0xFFFF) |
34 | 34 | ||
35 | void i2c_init(void); | 35 | void i2c_init(void); |
36 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout); | 36 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout); |
37 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout); | 37 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout); |
38 | int16_t i2c_read_ack(uint16_t timeout); | 38 | int16_t i2c_read_ack(uint16_t timeout); |
39 | int16_t i2c_read_nack(uint16_t timeout); | 39 | int16_t i2c_read_nack(uint16_t timeout); |
40 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); | 40 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); |
41 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); | 41 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); |
42 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); | 42 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); |
43 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 43 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
44 | void i2c_stop(void); | 44 | void i2c_stop(void); |
45 | 45 | ||
46 | #endif // I2C_MASTER_H | 46 | #endif // I2C_MASTER_H |
diff --git a/drivers/avr/i2c_slave.c b/drivers/avr/i2c_slave.c index 4958a0f8e..3fb684f70 100755..100644 --- a/drivers/avr/i2c_slave.c +++ b/drivers/avr/i2c_slave.c | |||
@@ -27,24 +27,24 @@ | |||
27 | volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; | 27 | volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; |
28 | 28 | ||
29 | static volatile uint8_t buffer_address; | 29 | static volatile uint8_t buffer_address; |
30 | static volatile bool slave_has_register_set = false; | 30 | static volatile bool slave_has_register_set = false; |
31 | 31 | ||
32 | void i2c_slave_init(uint8_t address){ | 32 | void i2c_slave_init(uint8_t address) { |
33 | // load address into TWI address register | 33 | // load address into TWI address register |
34 | TWAR = address; | 34 | TWAR = address; |
35 | // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt | 35 | // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt |
36 | TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN); | 36 | TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN); |
37 | } | 37 | } |
38 | 38 | ||
39 | void i2c_slave_stop(void){ | 39 | void i2c_slave_stop(void) { |
40 | // clear acknowledge and enable bits | 40 | // clear acknowledge and enable bits |
41 | TWCR &= ~((1 << TWEA) | (1 << TWEN)); | 41 | TWCR &= ~((1 << TWEA) | (1 << TWEN)); |
42 | } | 42 | } |
43 | 43 | ||
44 | ISR(TWI_vect){ | 44 | ISR(TWI_vect) { |
45 | uint8_t ack = 1; | 45 | uint8_t ack = 1; |
46 | 46 | ||
47 | switch(TW_STATUS){ | 47 | switch (TW_STATUS) { |
48 | case TW_SR_SLA_ACK: | 48 | case TW_SR_SLA_ACK: |
49 | // The device is now a slave receiver | 49 | // The device is now a slave receiver |
50 | slave_has_register_set = false; | 50 | slave_has_register_set = false; |
@@ -53,14 +53,14 @@ ISR(TWI_vect){ | |||
53 | case TW_SR_DATA_ACK: | 53 | case TW_SR_DATA_ACK: |
54 | // This device is a slave receiver and has received data | 54 | // This device is a slave receiver and has received data |
55 | // First byte is the location then the bytes will be writen in buffer with auto-incriment | 55 | // First byte is the location then the bytes will be writen in buffer with auto-incriment |
56 | if(!slave_has_register_set){ | 56 | if (!slave_has_register_set) { |
57 | buffer_address = TWDR; | 57 | buffer_address = TWDR; |
58 | 58 | ||
59 | if (buffer_address >= I2C_SLAVE_REG_COUNT) { // address out of bounds dont ack | 59 | if (buffer_address >= I2C_SLAVE_REG_COUNT) { // address out of bounds dont ack |
60 | ack = 0; | 60 | ack = 0; |
61 | buffer_address = 0; | 61 | buffer_address = 0; |
62 | } | 62 | } |
63 | slave_has_register_set = true; // address has been receaved now fill in buffer | 63 | slave_has_register_set = true; // address has been receaved now fill in buffer |
64 | } else { | 64 | } else { |
65 | i2c_slave_reg[buffer_address] = TWDR; | 65 | i2c_slave_reg[buffer_address] = TWDR; |
66 | buffer_address++; | 66 | buffer_address++; |
diff --git a/drivers/avr/i2c_slave.h b/drivers/avr/i2c_slave.h index 2f4589e9c..5ed0b11a8 100755..100644 --- a/drivers/avr/i2c_slave.h +++ b/drivers/avr/i2c_slave.h | |||
@@ -30,4 +30,4 @@ extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; | |||
30 | void i2c_slave_init(uint8_t address); | 30 | void i2c_slave_init(uint8_t address); |
31 | void i2c_slave_stop(void); | 31 | void i2c_slave_stop(void); |
32 | 32 | ||
33 | #endif // I2C_SLAVE_H | 33 | #endif // I2C_SLAVE_H |
diff --git a/drivers/avr/pro_micro.h b/drivers/avr/pro_micro.h index f9e7ed75d..762a99a05 100644 --- a/drivers/avr/pro_micro.h +++ b/drivers/avr/pro_micro.h | |||
@@ -90,14 +90,14 @@ | |||
90 | #undef OCR2_6 | 90 | #undef OCR2_6 |
91 | #undef OCR2_7 | 91 | #undef OCR2_7 |
92 | 92 | ||
93 | #define NUM_DIGITAL_PINS 30 | 93 | #define NUM_DIGITAL_PINS 30 |
94 | #define NUM_ANALOG_INPUTS 12 | 94 | #define NUM_ANALOG_INPUTS 12 |
95 | 95 | ||
96 | #define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0) | 96 | #define TX_RX_LED_INIT DDRD |= (1 << 5), DDRB |= (1 << 0) |
97 | #define TXLED0 PORTD |= (1<<5) | 97 | #define TXLED0 PORTD |= (1 << 5) |
98 | #define TXLED1 PORTD &= ~(1<<5) | 98 | #define TXLED1 PORTD &= ~(1 << 5) |
99 | #define RXLED0 PORTB |= (1<<0) | 99 | #define RXLED0 PORTB |= (1 << 0) |
100 | #define RXLED1 PORTB &= ~(1<<0) | 100 | #define RXLED1 PORTB &= ~(1 << 0) |
101 | 101 | ||
102 | static const uint8_t SDA = 2; | 102 | static const uint8_t SDA = 2; |
103 | static const uint8_t SCL = 3; | 103 | static const uint8_t SCL = 3; |
@@ -111,27 +111,27 @@ static const uint8_t SCK = 15; | |||
111 | 111 | ||
112 | // Mapping of analog pins as digital I/O | 112 | // Mapping of analog pins as digital I/O |
113 | // A6-A11 share with digital pins | 113 | // A6-A11 share with digital pins |
114 | static const uint8_t ADC0 = 18; | 114 | static const uint8_t ADC0 = 18; |
115 | static const uint8_t ADC1 = 19; | 115 | static const uint8_t ADC1 = 19; |
116 | static const uint8_t ADC2 = 20; | 116 | static const uint8_t ADC2 = 20; |
117 | static const uint8_t ADC3 = 21; | 117 | static const uint8_t ADC3 = 21; |
118 | static const uint8_t ADC4 = 22; | 118 | static const uint8_t ADC4 = 22; |
119 | static const uint8_t ADC5 = 23; | 119 | static const uint8_t ADC5 = 23; |
120 | static const uint8_t ADC6 = 24; // D4 | 120 | static const uint8_t ADC6 = 24; // D4 |
121 | static const uint8_t ADC7 = 25; // D6 | 121 | static const uint8_t ADC7 = 25; // D6 |
122 | static const uint8_t ADC8 = 26; // D8 | 122 | static const uint8_t ADC8 = 26; // D8 |
123 | static const uint8_t ADC9 = 27; // D9 | 123 | static const uint8_t ADC9 = 27; // D9 |
124 | static const uint8_t ADC10 = 28; // D10 | 124 | static const uint8_t ADC10 = 28; // D10 |
125 | static const uint8_t ADC11 = 29; // D12 | 125 | static const uint8_t ADC11 = 29; // D12 |
126 | 126 | ||
127 | #define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0)) | 127 | #define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0)) |
128 | #define digitalPinToPCICRbit(p) 0 | 128 | #define digitalPinToPCICRbit(p) 0 |
129 | #define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0)) | 129 | #define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0)) |
130 | #define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) | 130 | #define digitalPinToPCMSKbit(p) (((p) >= 8 && (p) <= 11) ? (p)-4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) |
131 | 131 | ||
132 | // __AVR_ATmega32U4__ has an unusual mapping of pins to channels | 132 | // __AVR_ATmega32U4__ has an unusual mapping of pins to channels |
133 | extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; | 133 | extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; |
134 | #define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) | 134 | #define analogPinToChannel(P) (pgm_read_byte(analog_pin_to_channel_PGM + (P))) |
135 | 135 | ||
136 | #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) | 136 | #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) |
137 | 137 | ||
@@ -182,159 +182,121 @@ extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; | |||
182 | // appropriate addresses for various functions (e.g. reading | 182 | // appropriate addresses for various functions (e.g. reading |
183 | // and writing) | 183 | // and writing) |
184 | const uint16_t PROGMEM port_to_mode_PGM[] = { | 184 | const uint16_t PROGMEM port_to_mode_PGM[] = { |
185 | NOT_A_PORT, | 185 | NOT_A_PORT, NOT_A_PORT, (uint16_t)&DDRB, (uint16_t)&DDRC, (uint16_t)&DDRD, (uint16_t)&DDRE, (uint16_t)&DDRF, |
186 | NOT_A_PORT, | ||
187 | (uint16_t) &DDRB, | ||
188 | (uint16_t) &DDRC, | ||
189 | (uint16_t) &DDRD, | ||
190 | (uint16_t) &DDRE, | ||
191 | (uint16_t) &DDRF, | ||
192 | }; | 186 | }; |
193 | 187 | ||
194 | const uint16_t PROGMEM port_to_output_PGM[] = { | 188 | const uint16_t PROGMEM port_to_output_PGM[] = { |
195 | NOT_A_PORT, | 189 | NOT_A_PORT, NOT_A_PORT, (uint16_t)&PORTB, (uint16_t)&PORTC, (uint16_t)&PORTD, (uint16_t)&PORTE, (uint16_t)&PORTF, |
196 | NOT_A_PORT, | ||
197 | (uint16_t) &PORTB, | ||
198 | (uint16_t) &PORTC, | ||
199 | (uint16_t) &PORTD, | ||
200 | (uint16_t) &PORTE, | ||
201 | (uint16_t) &PORTF, | ||
202 | }; | 190 | }; |
203 | 191 | ||
204 | const uint16_t PROGMEM port_to_input_PGM[] = { | 192 | const uint16_t PROGMEM port_to_input_PGM[] = { |
205 | NOT_A_PORT, | 193 | NOT_A_PORT, NOT_A_PORT, (uint16_t)&PINB, (uint16_t)&PINC, (uint16_t)&PIND, (uint16_t)&PINE, (uint16_t)&PINF, |
206 | NOT_A_PORT, | ||
207 | (uint16_t) &PINB, | ||
208 | (uint16_t) &PINC, | ||
209 | (uint16_t) &PIND, | ||
210 | (uint16_t) &PINE, | ||
211 | (uint16_t) &PINF, | ||
212 | }; | 194 | }; |
213 | 195 | ||
214 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { | 196 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { |
215 | PD, // D0 - PD2 | 197 | PD, // D0 - PD2 |
216 | PD, // D1 - PD3 | 198 | PD, // D1 - PD3 |
217 | PD, // D2 - PD1 | 199 | PD, // D2 - PD1 |
218 | PD, // D3 - PD0 | 200 | PD, // D3 - PD0 |
219 | PD, // D4 - PD4 | 201 | PD, // D4 - PD4 |
220 | PC, // D5 - PC6 | 202 | PC, // D5 - PC6 |
221 | PD, // D6 - PD7 | 203 | PD, // D6 - PD7 |
222 | PE, // D7 - PE6 | 204 | PE, // D7 - PE6 |
223 | 205 | ||
224 | PB, // D8 - PB4 | 206 | PB, // D8 - PB4 |
225 | PB, // D9 - PB5 | 207 | PB, // D9 - PB5 |
226 | PB, // D10 - PB6 | 208 | PB, // D10 - PB6 |
227 | PB, // D11 - PB7 | 209 | PB, // D11 - PB7 |
228 | PD, // D12 - PD6 | 210 | PD, // D12 - PD6 |
229 | PC, // D13 - PC7 | 211 | PC, // D13 - PC7 |
230 | 212 | ||
231 | PB, // D14 - MISO - PB3 | 213 | PB, // D14 - MISO - PB3 |
232 | PB, // D15 - SCK - PB1 | 214 | PB, // D15 - SCK - PB1 |
233 | PB, // D16 - MOSI - PB2 | 215 | PB, // D16 - MOSI - PB2 |
234 | PB, // D17 - SS - PB0 | 216 | PB, // D17 - SS - PB0 |
235 | 217 | ||
236 | PF, // D18 - A0 - PF7 | 218 | PF, // D18 - A0 - PF7 |
237 | PF, // D19 - A1 - PF6 | 219 | PF, // D19 - A1 - PF6 |
238 | PF, // D20 - A2 - PF5 | 220 | PF, // D20 - A2 - PF5 |
239 | PF, // D21 - A3 - PF4 | 221 | PF, // D21 - A3 - PF4 |
240 | PF, // D22 - A4 - PF1 | 222 | PF, // D22 - A4 - PF1 |
241 | PF, // D23 - A5 - PF0 | 223 | PF, // D23 - A5 - PF0 |
242 | 224 | ||
243 | PD, // D24 - PD5 | 225 | PD, // D24 - PD5 |
244 | PD, // D25 / D6 - A7 - PD7 | 226 | PD, // D25 / D6 - A7 - PD7 |
245 | PB, // D26 / D8 - A8 - PB4 | 227 | PB, // D26 / D8 - A8 - PB4 |
246 | PB, // D27 / D9 - A9 - PB5 | 228 | PB, // D27 / D9 - A9 - PB5 |
247 | PB, // D28 / D10 - A10 - PB6 | 229 | PB, // D28 / D10 - A10 - PB6 |
248 | PD, // D29 / D12 - A11 - PD6 | 230 | PD, // D29 / D12 - A11 - PD6 |
249 | }; | 231 | }; |
250 | 232 | ||
251 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { | 233 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { |
252 | _BV(2), // D0 - PD2 | 234 | _BV(2), // D0 - PD2 |
253 | _BV(3), // D1 - PD3 | 235 | _BV(3), // D1 - PD3 |
254 | _BV(1), // D2 - PD1 | 236 | _BV(1), // D2 - PD1 |
255 | _BV(0), // D3 - PD0 | 237 | _BV(0), // D3 - PD0 |
256 | _BV(4), // D4 - PD4 | 238 | _BV(4), // D4 - PD4 |
257 | _BV(6), // D5 - PC6 | 239 | _BV(6), // D5 - PC6 |
258 | _BV(7), // D6 - PD7 | 240 | _BV(7), // D6 - PD7 |
259 | _BV(6), // D7 - PE6 | 241 | _BV(6), // D7 - PE6 |
260 | 242 | ||
261 | _BV(4), // D8 - PB4 | 243 | _BV(4), // D8 - PB4 |
262 | _BV(5), // D9 - PB5 | 244 | _BV(5), // D9 - PB5 |
263 | _BV(6), // D10 - PB6 | 245 | _BV(6), // D10 - PB6 |
264 | _BV(7), // D11 - PB7 | 246 | _BV(7), // D11 - PB7 |
265 | _BV(6), // D12 - PD6 | 247 | _BV(6), // D12 - PD6 |
266 | _BV(7), // D13 - PC7 | 248 | _BV(7), // D13 - PC7 |
267 | 249 | ||
268 | _BV(3), // D14 - MISO - PB3 | 250 | _BV(3), // D14 - MISO - PB3 |
269 | _BV(1), // D15 - SCK - PB1 | 251 | _BV(1), // D15 - SCK - PB1 |
270 | _BV(2), // D16 - MOSI - PB2 | 252 | _BV(2), // D16 - MOSI - PB2 |
271 | _BV(0), // D17 - SS - PB0 | 253 | _BV(0), // D17 - SS - PB0 |
272 | 254 | ||
273 | _BV(7), // D18 - A0 - PF7 | 255 | _BV(7), // D18 - A0 - PF7 |
274 | _BV(6), // D19 - A1 - PF6 | 256 | _BV(6), // D19 - A1 - PF6 |
275 | _BV(5), // D20 - A2 - PF5 | 257 | _BV(5), // D20 - A2 - PF5 |
276 | _BV(4), // D21 - A3 - PF4 | 258 | _BV(4), // D21 - A3 - PF4 |
277 | _BV(1), // D22 - A4 - PF1 | 259 | _BV(1), // D22 - A4 - PF1 |
278 | _BV(0), // D23 - A5 - PF0 | 260 | _BV(0), // D23 - A5 - PF0 |
279 | 261 | ||
280 | _BV(5), // D24 - PD5 | 262 | _BV(5), // D24 - PD5 |
281 | _BV(7), // D25 / D6 - A7 - PD7 | 263 | _BV(7), // D25 / D6 - A7 - PD7 |
282 | _BV(4), // D26 / D8 - A8 - PB4 | 264 | _BV(4), // D26 / D8 - A8 - PB4 |
283 | _BV(5), // D27 / D9 - A9 - PB5 | 265 | _BV(5), // D27 / D9 - A9 - PB5 |
284 | _BV(6), // D28 / D10 - A10 - PB6 | 266 | _BV(6), // D28 / D10 - A10 - PB6 |
285 | _BV(6), // D29 / D12 - A11 - PD6 | 267 | _BV(6), // D29 / D12 - A11 - PD6 |
286 | }; | 268 | }; |
287 | 269 | ||
288 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { | 270 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { |
289 | NOT_ON_TIMER, | 271 | NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, TIMER0B, /* 3 */ |
290 | NOT_ON_TIMER, | 272 | NOT_ON_TIMER, TIMER3A, /* 5 */ |
291 | NOT_ON_TIMER, | 273 | TIMER4D, /* 6 */ |
292 | TIMER0B, /* 3 */ | ||
293 | NOT_ON_TIMER, | ||
294 | TIMER3A, /* 5 */ | ||
295 | TIMER4D, /* 6 */ | ||
296 | NOT_ON_TIMER, | 274 | NOT_ON_TIMER, |
297 | 275 | ||
298 | NOT_ON_TIMER, | 276 | NOT_ON_TIMER, TIMER1A, /* 9 */ |
299 | TIMER1A, /* 9 */ | 277 | TIMER1B, /* 10 */ |
300 | TIMER1B, /* 10 */ | 278 | TIMER0A, /* 11 */ |
301 | TIMER0A, /* 11 */ | ||
302 | 279 | ||
303 | NOT_ON_TIMER, | 280 | NOT_ON_TIMER, TIMER4A, /* 13 */ |
304 | TIMER4A, /* 13 */ | ||
305 | 281 | ||
306 | NOT_ON_TIMER, | 282 | NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, |
307 | NOT_ON_TIMER, | ||
308 | NOT_ON_TIMER, | ||
309 | NOT_ON_TIMER, | ||
310 | NOT_ON_TIMER, | ||
311 | NOT_ON_TIMER, | ||
312 | 283 | ||
313 | NOT_ON_TIMER, | 284 | NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, |
314 | NOT_ON_TIMER, | ||
315 | NOT_ON_TIMER, | ||
316 | NOT_ON_TIMER, | ||
317 | NOT_ON_TIMER, | ||
318 | NOT_ON_TIMER, | ||
319 | NOT_ON_TIMER, | ||
320 | NOT_ON_TIMER, | ||
321 | NOT_ON_TIMER, | ||
322 | NOT_ON_TIMER, | ||
323 | }; | 285 | }; |
324 | 286 | ||
325 | const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { | 287 | const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { |
326 | 7, // A0 PF7 ADC7 | 288 | 7, // A0 PF7 ADC7 |
327 | 6, // A1 PF6 ADC6 | 289 | 6, // A1 PF6 ADC6 |
328 | 5, // A2 PF5 ADC5 | 290 | 5, // A2 PF5 ADC5 |
329 | 4, // A3 PF4 ADC4 | 291 | 4, // A3 PF4 ADC4 |
330 | 1, // A4 PF1 ADC1 | 292 | 1, // A4 PF1 ADC1 |
331 | 0, // A5 PF0 ADC0 | 293 | 0, // A5 PF0 ADC0 |
332 | 8, // A6 D4 PD4 ADC8 | 294 | 8, // A6 D4 PD4 ADC8 |
333 | 10, // A7 D6 PD7 ADC10 | 295 | 10, // A7 D6 PD7 ADC10 |
334 | 11, // A8 D8 PB4 ADC11 | 296 | 11, // A8 D8 PB4 ADC11 |
335 | 12, // A9 D9 PB5 ADC12 | 297 | 12, // A9 D9 PB5 ADC12 |
336 | 13, // A10 D10 PB6 ADC13 | 298 | 13, // A10 D10 PB6 ADC13 |
337 | 9 // A11 D12 PD6 ADC9 | 299 | 9 // A11 D12 PD6 ADC9 |
338 | }; | 300 | }; |
339 | 301 | ||
340 | #endif /* ARDUINO_MAIN */ | 302 | #endif /* ARDUINO_MAIN */ |
@@ -354,9 +316,9 @@ const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { | |||
354 | // | 316 | // |
355 | // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX | 317 | // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX |
356 | // pins are NOT connected to anything by default. | 318 | // pins are NOT connected to anything by default. |
357 | #define SERIAL_PORT_MONITOR Serial | 319 | #define SERIAL_PORT_MONITOR Serial |
358 | #define SERIAL_PORT_USBVIRTUAL Serial | 320 | #define SERIAL_PORT_USBVIRTUAL Serial |
359 | #define SERIAL_PORT_HARDWARE Serial1 | 321 | #define SERIAL_PORT_HARDWARE Serial1 |
360 | #define SERIAL_PORT_HARDWARE_OPEN Serial1 | 322 | #define SERIAL_PORT_HARDWARE_OPEN Serial1 |
361 | 323 | ||
362 | #endif /* Pins_Arduino_h */ | 324 | #endif /* Pins_Arduino_h */ |
diff --git a/drivers/avr/ssd1306.c b/drivers/avr/ssd1306.c index bb8938bba..61d7a9953 100644 --- a/drivers/avr/ssd1306.c +++ b/drivers/avr/ssd1306.c | |||
@@ -1,325 +1,320 @@ | |||
1 | #ifdef SSD1306OLED | 1 | #ifdef SSD1306OLED |
2 | 2 | ||
3 | #include "ssd1306.h" | 3 | # include "ssd1306.h" |
4 | #include "i2c.h" | 4 | # include "i2c.h" |
5 | #include <string.h> | 5 | # include <string.h> |
6 | #include "print.h" | 6 | # include "print.h" |
7 | #include "glcdfont.c" | 7 | # include "glcdfont.c" |
8 | #ifdef ADAFRUIT_BLE_ENABLE | 8 | # ifdef ADAFRUIT_BLE_ENABLE |
9 | #include "adafruit_ble.h" | 9 | # include "adafruit_ble.h" |
10 | #endif | 10 | # endif |
11 | #ifdef PROTOCOL_LUFA | 11 | # ifdef PROTOCOL_LUFA |
12 | #include "lufa.h" | 12 | # include "lufa.h" |
13 | #endif | 13 | # endif |
14 | #include "sendchar.h" | 14 | # include "sendchar.h" |
15 | #include "timer.h" | 15 | # include "timer.h" |
16 | 16 | ||
17 | // Set this to 1 to help diagnose early startup problems | 17 | // Set this to 1 to help diagnose early startup problems |
18 | // when testing power-on with ble. Turn it off otherwise, | 18 | // when testing power-on with ble. Turn it off otherwise, |
19 | // as the latency of printing most of the debug info messes | 19 | // as the latency of printing most of the debug info messes |
20 | // with the matrix scan, causing keys to drop. | 20 | // with the matrix scan, causing keys to drop. |
21 | #define DEBUG_TO_SCREEN 0 | 21 | # define DEBUG_TO_SCREEN 0 |
22 | 22 | ||
23 | //static uint16_t last_battery_update; | 23 | // static uint16_t last_battery_update; |
24 | //static uint32_t vbat; | 24 | // static uint32_t vbat; |
25 | //#define BatteryUpdateInterval 10000 /* milliseconds */ | 25 | //#define BatteryUpdateInterval 10000 /* milliseconds */ |
26 | #define ScreenOffInterval 300000 /* milliseconds */ | 26 | # define ScreenOffInterval 300000 /* milliseconds */ |
27 | #if DEBUG_TO_SCREEN | 27 | # if DEBUG_TO_SCREEN |
28 | static uint8_t displaying; | 28 | static uint8_t displaying; |
29 | #endif | 29 | # endif |
30 | static uint16_t last_flush; | 30 | static uint16_t last_flush; |
31 | 31 | ||
32 | // Write command sequence. | 32 | // Write command sequence. |
33 | // Returns true on success. | 33 | // Returns true on success. |
34 | static inline bool _send_cmd1(uint8_t cmd) { | 34 | static inline bool _send_cmd1(uint8_t cmd) { |
35 | bool res = false; | 35 | bool res = false; |
36 | 36 | ||
37 | if (i2c_start_write(SSD1306_ADDRESS)) { | 37 | if (i2c_start_write(SSD1306_ADDRESS)) { |
38 | xprintf("failed to start write to %d\n", SSD1306_ADDRESS); | 38 | xprintf("failed to start write to %d\n", SSD1306_ADDRESS); |
39 | goto done; | 39 | goto done; |
40 | } | 40 | } |
41 | 41 | ||
42 | if (i2c_master_write(0x0 /* command byte follows */)) { | 42 | if (i2c_master_write(0x0 /* command byte follows */)) { |
43 | print("failed to write control byte\n"); | 43 | print("failed to write control byte\n"); |
44 | 44 | ||
45 | goto done; | 45 | goto done; |
46 | } | 46 | } |
47 | 47 | ||
48 | if (i2c_master_write(cmd)) { | 48 | if (i2c_master_write(cmd)) { |
49 | xprintf("failed to write command %d\n", cmd); | 49 | xprintf("failed to write command %d\n", cmd); |
50 | goto done; | 50 | goto done; |
51 | } | 51 | } |
52 | res = true; | 52 | res = true; |
53 | done: | 53 | done: |
54 | i2c_master_stop(); | 54 | i2c_master_stop(); |
55 | return res; | 55 | return res; |
56 | } | 56 | } |
57 | 57 | ||
58 | // Write 2-byte command sequence. | 58 | // Write 2-byte command sequence. |
59 | // Returns true on success | 59 | // Returns true on success |
60 | static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { | 60 | static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { |
61 | if (!_send_cmd1(cmd)) { | 61 | if (!_send_cmd1(cmd)) { |
62 | return false; | 62 | return false; |
63 | } | 63 | } |
64 | return _send_cmd1(opr); | 64 | return _send_cmd1(opr); |
65 | } | 65 | } |
66 | 66 | ||
67 | // Write 3-byte command sequence. | 67 | // Write 3-byte command sequence. |
68 | // Returns true on success | 68 | // Returns true on success |
69 | static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { | 69 | static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { |
70 | if (!_send_cmd1(cmd)) { | 70 | if (!_send_cmd1(cmd)) { |
71 | return false; | 71 | return false; |
72 | } | 72 | } |
73 | if (!_send_cmd1(opr1)) { | 73 | if (!_send_cmd1(opr1)) { |
74 | return false; | 74 | return false; |
75 | } | 75 | } |
76 | return _send_cmd1(opr2); | 76 | return _send_cmd1(opr2); |
77 | } | 77 | } |
78 | 78 | ||
79 | #define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} | 79 | # define send_cmd1(c) \ |
80 | #define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} | 80 | if (!_send_cmd1(c)) { \ |
81 | #define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} | 81 | goto done; \ |
82 | } | ||
83 | # define send_cmd2(c, o) \ | ||
84 | if (!_send_cmd2(c, o)) { \ | ||
85 | goto done; \ | ||
86 | } | ||
87 | # define send_cmd3(c, o1, o2) \ | ||
88 | if (!_send_cmd3(c, o1, o2)) { \ | ||
89 | goto done; \ | ||
90 | } | ||
82 | 91 | ||
83 | static void clear_display(void) { | 92 | static void clear_display(void) { |
84 | matrix_clear(&display); | 93 | matrix_clear(&display); |
85 | 94 | ||
86 | // Clear all of the display bits (there can be random noise | 95 | // Clear all of the display bits (there can be random noise |
87 | // in the RAM on startup) | 96 | // in the RAM on startup) |
88 | send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); | 97 | send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); |
89 | send_cmd3(ColumnAddr, 0, DisplayWidth - 1); | 98 | send_cmd3(ColumnAddr, 0, DisplayWidth - 1); |
90 | 99 | ||
91 | if (i2c_start_write(SSD1306_ADDRESS)) { | 100 | if (i2c_start_write(SSD1306_ADDRESS)) { |
92 | goto done; | 101 | goto done; |
93 | } | 102 | } |
94 | if (i2c_master_write(0x40)) { | 103 | if (i2c_master_write(0x40)) { |
95 | // Data mode | 104 | // Data mode |
96 | goto done; | 105 | goto done; |
97 | } | 106 | } |
98 | for (uint8_t row = 0; row < MatrixRows; ++row) { | 107 | for (uint8_t row = 0; row < MatrixRows; ++row) { |
99 | for (uint8_t col = 0; col < DisplayWidth; ++col) { | 108 | for (uint8_t col = 0; col < DisplayWidth; ++col) { |
100 | i2c_master_write(0); | 109 | i2c_master_write(0); |
110 | } | ||
101 | } | 111 | } |
102 | } | ||
103 | 112 | ||
104 | display.dirty = false; | 113 | display.dirty = false; |
105 | 114 | ||
106 | done: | 115 | done: |
107 | i2c_master_stop(); | 116 | i2c_master_stop(); |
108 | } | 117 | } |
109 | 118 | ||
110 | #if DEBUG_TO_SCREEN | 119 | # if DEBUG_TO_SCREEN |
111 | #undef sendchar | 120 | # undef sendchar |
112 | static int8_t capture_sendchar(uint8_t c) { | 121 | static int8_t capture_sendchar(uint8_t c) { |
113 | sendchar(c); | 122 | sendchar(c); |
114 | iota_gfx_write_char(c); | 123 | iota_gfx_write_char(c); |
115 | 124 | ||
116 | if (!displaying) { | 125 | if (!displaying) { |
117 | iota_gfx_flush(); | 126 | iota_gfx_flush(); |
118 | } | 127 | } |
119 | return 0; | 128 | return 0; |
120 | } | 129 | } |
121 | #endif | 130 | # endif |
122 | 131 | ||
123 | bool iota_gfx_init(void) { | 132 | bool iota_gfx_init(void) { |
124 | bool success = false; | 133 | bool success = false; |
125 | 134 | ||
126 | send_cmd1(DisplayOff); | 135 | send_cmd1(DisplayOff); |
127 | send_cmd2(SetDisplayClockDiv, 0x80); | 136 | send_cmd2(SetDisplayClockDiv, 0x80); |
128 | send_cmd2(SetMultiPlex, DisplayHeight - 1); | 137 | send_cmd2(SetMultiPlex, DisplayHeight - 1); |
129 | 138 | ||
130 | send_cmd2(SetDisplayOffset, 0); | 139 | send_cmd2(SetDisplayOffset, 0); |
131 | 140 | ||
141 | send_cmd1(SetStartLine | 0x0); | ||
142 | send_cmd2(SetChargePump, 0x14 /* Enable */); | ||
143 | send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); | ||
132 | 144 | ||
133 | send_cmd1(SetStartLine | 0x0); | 145 | # ifdef OLED_ROTATE180 |
134 | send_cmd2(SetChargePump, 0x14 /* Enable */); | 146 | // the following Flip the display orientation 180 degrees |
135 | send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); | 147 | send_cmd1(SegRemap); |
148 | send_cmd1(ComScanInc); | ||
149 | # endif | ||
150 | # ifndef OLED_ROTATE180 | ||
151 | // Flips the display orientation 0 degrees | ||
152 | send_cmd1(SegRemap | 0x1); | ||
153 | send_cmd1(ComScanDec); | ||
154 | # endif | ||
136 | 155 | ||
137 | #ifdef OLED_ROTATE180 | 156 | send_cmd2(SetComPins, 0x2); |
138 | // the following Flip the display orientation 180 degrees | 157 | send_cmd2(SetContrast, 0x8f); |
139 | send_cmd1(SegRemap); | 158 | send_cmd2(SetPreCharge, 0xf1); |
140 | send_cmd1(ComScanInc); | 159 | send_cmd2(SetVComDetect, 0x40); |
141 | #endif | 160 | send_cmd1(DisplayAllOnResume); |
142 | #ifndef OLED_ROTATE180 | 161 | send_cmd1(NormalDisplay); |
143 | // Flips the display orientation 0 degrees | 162 | send_cmd1(DeActivateScroll); |
144 | send_cmd1(SegRemap | 0x1); | 163 | send_cmd1(DisplayOn); |
145 | send_cmd1(ComScanDec); | ||
146 | #endif | ||
147 | |||
148 | send_cmd2(SetComPins, 0x2); | ||
149 | send_cmd2(SetContrast, 0x8f); | ||
150 | send_cmd2(SetPreCharge, 0xf1); | ||
151 | send_cmd2(SetVComDetect, 0x40); | ||
152 | send_cmd1(DisplayAllOnResume); | ||
153 | send_cmd1(NormalDisplay); | ||
154 | send_cmd1(DeActivateScroll); | ||
155 | send_cmd1(DisplayOn); | ||
156 | 164 | ||
157 | send_cmd2(SetContrast, 0); // Dim | 165 | send_cmd2(SetContrast, 0); // Dim |
158 | 166 | ||
159 | clear_display(); | 167 | clear_display(); |
160 | 168 | ||
161 | success = true; | 169 | success = true; |
162 | 170 | ||
163 | iota_gfx_flush(); | 171 | iota_gfx_flush(); |
164 | 172 | ||
165 | #if DEBUG_TO_SCREEN | 173 | # if DEBUG_TO_SCREEN |
166 | print_set_sendchar(capture_sendchar); | 174 | print_set_sendchar(capture_sendchar); |
167 | #endif | 175 | # endif |
168 | 176 | ||
169 | done: | 177 | done: |
170 | return success; | 178 | return success; |
171 | } | 179 | } |
172 | 180 | ||
173 | bool iota_gfx_off(void) { | 181 | bool iota_gfx_off(void) { |
174 | bool success = false; | 182 | bool success = false; |
175 | 183 | ||
176 | send_cmd1(DisplayOff); | 184 | send_cmd1(DisplayOff); |
177 | success = true; | 185 | success = true; |
178 | 186 | ||
179 | done: | 187 | done: |
180 | return success; | 188 | return success; |
181 | } | 189 | } |
182 | 190 | ||
183 | bool iota_gfx_on(void) { | 191 | bool iota_gfx_on(void) { |
184 | bool success = false; | 192 | bool success = false; |
185 | 193 | ||
186 | send_cmd1(DisplayOn); | 194 | send_cmd1(DisplayOn); |
187 | success = true; | 195 | success = true; |
188 | 196 | ||
189 | done: | 197 | done: |
190 | return success; | 198 | return success; |
191 | } | 199 | } |
192 | 200 | ||
193 | void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { | 201 | void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { |
194 | *matrix->cursor = c; | 202 | *matrix->cursor = c; |
195 | ++matrix->cursor; | 203 | ++matrix->cursor; |
196 | 204 | ||
197 | if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { | 205 | if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { |
198 | // We went off the end; scroll the display upwards by one line | 206 | // We went off the end; scroll the display upwards by one line |
199 | memmove(&matrix->display[0], &matrix->display[1], | 207 | memmove(&matrix->display[0], &matrix->display[1], MatrixCols * (MatrixRows - 1)); |
200 | MatrixCols * (MatrixRows - 1)); | 208 | matrix->cursor = &matrix->display[MatrixRows - 1][0]; |
201 | matrix->cursor = &matrix->display[MatrixRows - 1][0]; | 209 | memset(matrix->cursor, ' ', MatrixCols); |
202 | memset(matrix->cursor, ' ', MatrixCols); | 210 | } |
203 | } | ||
204 | } | 211 | } |
205 | 212 | ||
206 | void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { | 213 | void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { |
207 | matrix->dirty = true; | 214 | matrix->dirty = true; |
208 | 215 | ||
209 | if (c == '\n') { | 216 | if (c == '\n') { |
210 | // Clear to end of line from the cursor and then move to the | 217 | // Clear to end of line from the cursor and then move to the |
211 | // start of the next line | 218 | // start of the next line |
212 | uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; | 219 | uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; |
213 | 220 | ||
214 | while (cursor_col++ < MatrixCols) { | 221 | while (cursor_col++ < MatrixCols) { |
215 | matrix_write_char_inner(matrix, ' '); | 222 | matrix_write_char_inner(matrix, ' '); |
223 | } | ||
224 | return; | ||
216 | } | 225 | } |
217 | return; | ||
218 | } | ||
219 | 226 | ||
220 | matrix_write_char_inner(matrix, c); | 227 | matrix_write_char_inner(matrix, c); |
221 | } | 228 | } |
222 | 229 | ||
223 | void iota_gfx_write_char(uint8_t c) { | 230 | void iota_gfx_write_char(uint8_t c) { matrix_write_char(&display, c); } |
224 | matrix_write_char(&display, c); | ||
225 | } | ||
226 | 231 | ||
227 | void matrix_write(struct CharacterMatrix *matrix, const char *data) { | 232 | void matrix_write(struct CharacterMatrix *matrix, const char *data) { |
228 | const char *end = data + strlen(data); | 233 | const char *end = data + strlen(data); |
229 | while (data < end) { | 234 | while (data < end) { |
230 | matrix_write_char(matrix, *data); | 235 | matrix_write_char(matrix, *data); |
231 | ++data; | 236 | ++data; |
232 | } | 237 | } |
233 | } | 238 | } |
234 | 239 | ||
235 | void iota_gfx_write(const char *data) { | 240 | void iota_gfx_write(const char *data) { matrix_write(&display, data); } |
236 | matrix_write(&display, data); | ||
237 | } | ||
238 | 241 | ||
239 | void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { | 242 | void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { |
240 | while (true) { | 243 | while (true) { |
241 | uint8_t c = pgm_read_byte(data); | 244 | uint8_t c = pgm_read_byte(data); |
242 | if (c == 0) { | 245 | if (c == 0) { |
243 | return; | 246 | return; |
247 | } | ||
248 | matrix_write_char(matrix, c); | ||
249 | ++data; | ||
244 | } | 250 | } |
245 | matrix_write_char(matrix, c); | ||
246 | ++data; | ||
247 | } | ||
248 | } | 251 | } |
249 | 252 | ||
250 | void iota_gfx_write_P(const char *data) { | 253 | void iota_gfx_write_P(const char *data) { matrix_write_P(&display, data); } |
251 | matrix_write_P(&display, data); | ||
252 | } | ||
253 | 254 | ||
254 | void matrix_clear(struct CharacterMatrix *matrix) { | 255 | void matrix_clear(struct CharacterMatrix *matrix) { |
255 | memset(matrix->display, ' ', sizeof(matrix->display)); | 256 | memset(matrix->display, ' ', sizeof(matrix->display)); |
256 | matrix->cursor = &matrix->display[0][0]; | 257 | matrix->cursor = &matrix->display[0][0]; |
257 | matrix->dirty = true; | 258 | matrix->dirty = true; |
258 | } | 259 | } |
259 | 260 | ||
260 | void iota_gfx_clear_screen(void) { | 261 | void iota_gfx_clear_screen(void) { matrix_clear(&display); } |
261 | matrix_clear(&display); | ||
262 | } | ||
263 | 262 | ||
264 | void matrix_render(struct CharacterMatrix *matrix) { | 263 | void matrix_render(struct CharacterMatrix *matrix) { |
265 | last_flush = timer_read(); | 264 | last_flush = timer_read(); |
266 | iota_gfx_on(); | 265 | iota_gfx_on(); |
267 | #if DEBUG_TO_SCREEN | 266 | # if DEBUG_TO_SCREEN |
268 | ++displaying; | 267 | ++displaying; |
269 | #endif | 268 | # endif |
269 | |||
270 | // Move to the home position | ||
271 | send_cmd3(PageAddr, 0, MatrixRows - 1); | ||
272 | send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); | ||
273 | |||
274 | if (i2c_start_write(SSD1306_ADDRESS)) { | ||
275 | goto done; | ||
276 | } | ||
277 | if (i2c_master_write(0x40)) { | ||
278 | // Data mode | ||
279 | goto done; | ||
280 | } | ||
281 | |||
282 | for (uint8_t row = 0; row < MatrixRows; ++row) { | ||
283 | for (uint8_t col = 0; col < MatrixCols; ++col) { | ||
284 | const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1)); | ||
285 | |||
286 | for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) { | ||
287 | uint8_t colBits = pgm_read_byte(glyph + glyphCol); | ||
288 | i2c_master_write(colBits); | ||
289 | } | ||
270 | 290 | ||
271 | // Move to the home position | 291 | // 1 column of space between chars (it's not included in the glyph) |
272 | send_cmd3(PageAddr, 0, MatrixRows - 1); | 292 | i2c_master_write(0); |
273 | send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); | 293 | } |
274 | |||
275 | if (i2c_start_write(SSD1306_ADDRESS)) { | ||
276 | goto done; | ||
277 | } | ||
278 | if (i2c_master_write(0x40)) { | ||
279 | // Data mode | ||
280 | goto done; | ||
281 | } | ||
282 | |||
283 | for (uint8_t row = 0; row < MatrixRows; ++row) { | ||
284 | for (uint8_t col = 0; col < MatrixCols; ++col) { | ||
285 | const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1)); | ||
286 | |||
287 | for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) { | ||
288 | uint8_t colBits = pgm_read_byte(glyph + glyphCol); | ||
289 | i2c_master_write(colBits); | ||
290 | } | ||
291 | |||
292 | // 1 column of space between chars (it's not included in the glyph) | ||
293 | i2c_master_write(0); | ||
294 | } | 294 | } |
295 | } | ||
296 | 295 | ||
297 | matrix->dirty = false; | 296 | matrix->dirty = false; |
298 | 297 | ||
299 | done: | 298 | done: |
300 | i2c_master_stop(); | 299 | i2c_master_stop(); |
301 | #if DEBUG_TO_SCREEN | 300 | # if DEBUG_TO_SCREEN |
302 | --displaying; | 301 | --displaying; |
303 | #endif | 302 | # endif |
304 | } | 303 | } |
305 | 304 | ||
306 | void iota_gfx_flush(void) { | 305 | void iota_gfx_flush(void) { matrix_render(&display); } |
307 | matrix_render(&display); | ||
308 | } | ||
309 | 306 | ||
310 | __attribute__ ((weak)) | 307 | __attribute__((weak)) void iota_gfx_task_user(void) {} |
311 | void iota_gfx_task_user(void) { | ||
312 | } | ||
313 | 308 | ||
314 | void iota_gfx_task(void) { | 309 | void iota_gfx_task(void) { |
315 | iota_gfx_task_user(); | 310 | iota_gfx_task_user(); |
316 | 311 | ||
317 | if (display.dirty) { | 312 | if (display.dirty) { |
318 | iota_gfx_flush(); | 313 | iota_gfx_flush(); |
319 | } | 314 | } |
320 | 315 | ||
321 | if (timer_elapsed(last_flush) > ScreenOffInterval) { | 316 | if (timer_elapsed(last_flush) > ScreenOffInterval) { |
322 | iota_gfx_off(); | 317 | iota_gfx_off(); |
323 | } | 318 | } |
324 | } | 319 | } |
325 | #endif | 320 | #endif |
diff --git a/drivers/avr/ssd1306.h b/drivers/avr/ssd1306.h index df6a75359..825b0d7d5 100644 --- a/drivers/avr/ssd1306.h +++ b/drivers/avr/ssd1306.h | |||
@@ -7,49 +7,49 @@ | |||
7 | #include "config.h" | 7 | #include "config.h" |
8 | 8 | ||
9 | enum ssd1306_cmds { | 9 | enum ssd1306_cmds { |
10 | DisplayOff = 0xAE, | 10 | DisplayOff = 0xAE, |
11 | DisplayOn = 0xAF, | 11 | DisplayOn = 0xAF, |
12 | 12 | ||
13 | SetContrast = 0x81, | 13 | SetContrast = 0x81, |
14 | DisplayAllOnResume = 0xA4, | 14 | DisplayAllOnResume = 0xA4, |
15 | 15 | ||
16 | DisplayAllOn = 0xA5, | 16 | DisplayAllOn = 0xA5, |
17 | NormalDisplay = 0xA6, | 17 | NormalDisplay = 0xA6, |
18 | InvertDisplay = 0xA7, | 18 | InvertDisplay = 0xA7, |
19 | SetDisplayOffset = 0xD3, | 19 | SetDisplayOffset = 0xD3, |
20 | SetComPins = 0xda, | 20 | SetComPins = 0xda, |
21 | SetVComDetect = 0xdb, | 21 | SetVComDetect = 0xdb, |
22 | SetDisplayClockDiv = 0xD5, | 22 | SetDisplayClockDiv = 0xD5, |
23 | SetPreCharge = 0xd9, | 23 | SetPreCharge = 0xd9, |
24 | SetMultiPlex = 0xa8, | 24 | SetMultiPlex = 0xa8, |
25 | SetLowColumn = 0x00, | 25 | SetLowColumn = 0x00, |
26 | SetHighColumn = 0x10, | 26 | SetHighColumn = 0x10, |
27 | SetStartLine = 0x40, | 27 | SetStartLine = 0x40, |
28 | 28 | ||
29 | SetMemoryMode = 0x20, | 29 | SetMemoryMode = 0x20, |
30 | ColumnAddr = 0x21, | 30 | ColumnAddr = 0x21, |
31 | PageAddr = 0x22, | 31 | PageAddr = 0x22, |
32 | 32 | ||
33 | ComScanInc = 0xc0, | 33 | ComScanInc = 0xc0, |
34 | ComScanDec = 0xc8, | 34 | ComScanDec = 0xc8, |
35 | SegRemap = 0xa0, | 35 | SegRemap = 0xa0, |
36 | SetChargePump = 0x8d, | 36 | SetChargePump = 0x8d, |
37 | ExternalVcc = 0x01, | 37 | ExternalVcc = 0x01, |
38 | SwitchCapVcc = 0x02, | 38 | SwitchCapVcc = 0x02, |
39 | 39 | ||
40 | ActivateScroll = 0x2f, | 40 | ActivateScroll = 0x2f, |
41 | DeActivateScroll = 0x2e, | 41 | DeActivateScroll = 0x2e, |
42 | SetVerticalScrollArea = 0xa3, | 42 | SetVerticalScrollArea = 0xa3, |
43 | RightHorizontalScroll = 0x26, | 43 | RightHorizontalScroll = 0x26, |
44 | LeftHorizontalScroll = 0x27, | 44 | LeftHorizontalScroll = 0x27, |
45 | VerticalAndRightHorizontalScroll = 0x29, | 45 | VerticalAndRightHorizontalScroll = 0x29, |
46 | VerticalAndLeftHorizontalScroll = 0x2a, | 46 | VerticalAndLeftHorizontalScroll = 0x2a, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | // Controls the SSD1306 128x32 OLED display via i2c | 49 | // Controls the SSD1306 128x32 OLED display via i2c |
50 | 50 | ||
51 | #ifndef SSD1306_ADDRESS | 51 | #ifndef SSD1306_ADDRESS |
52 | #define SSD1306_ADDRESS 0x3C | 52 | # define SSD1306_ADDRESS 0x3C |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #define DisplayHeight 32 | 55 | #define DisplayHeight 32 |
@@ -62,9 +62,9 @@ enum ssd1306_cmds { | |||
62 | #define MatrixCols (DisplayWidth / FontWidth) | 62 | #define MatrixCols (DisplayWidth / FontWidth) |
63 | 63 | ||
64 | struct CharacterMatrix { | 64 | struct CharacterMatrix { |
65 | uint8_t display[MatrixRows][MatrixCols]; | 65 | uint8_t display[MatrixRows][MatrixCols]; |
66 | uint8_t *cursor; | 66 | uint8_t *cursor; |
67 | bool dirty; | 67 | bool dirty; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct CharacterMatrix display; | 70 | struct CharacterMatrix display; |
@@ -88,6 +88,4 @@ void matrix_write(struct CharacterMatrix *matrix, const char *data); | |||
88 | void matrix_write_P(struct CharacterMatrix *matrix, const char *data); | 88 | void matrix_write_P(struct CharacterMatrix *matrix, const char *data); |
89 | void matrix_render(struct CharacterMatrix *matrix); | 89 | void matrix_render(struct CharacterMatrix *matrix); |
90 | 90 | ||
91 | |||
92 | |||
93 | #endif | 91 | #endif |
diff --git a/drivers/avr/ws2812.c b/drivers/avr/ws2812.c index 7c3cb5174..0a02c6f7f 100644 --- a/drivers/avr/ws2812.c +++ b/drivers/avr/ws2812.c | |||
@@ -1,25 +1,25 @@ | |||
1 | /* | 1 | /* |
2 | * light weight WS2812 lib V2.0b | 2 | * light weight WS2812 lib V2.0b |
3 | * | 3 | * |
4 | * Controls WS2811/WS2812/WS2812B RGB-LEDs | 4 | * Controls WS2811/WS2812/WS2812B RGB-LEDs |
5 | * Author: Tim (cpldcpu@gmail.com) | 5 | * Author: Tim (cpldcpu@gmail.com) |
6 | * | 6 | * |
7 | * Jan 18th, 2014 v2.0b Initial Version | 7 | * Jan 18th, 2014 v2.0b Initial Version |
8 | * Nov 29th, 2015 v2.3 Added SK6812RGBW support | 8 | * Nov 29th, 2015 v2.3 Added SK6812RGBW support |
9 | * | 9 | * |
10 | * This program is free software: you can redistribute it and/or modify | 10 | * This program is free software: you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation, either version 2 of the License, or | 12 | * the Free Software Foundation, either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "ws2812.h" | 24 | #include "ws2812.h" |
25 | #include <avr/interrupt.h> | 25 | #include <avr/interrupt.h> |
@@ -30,44 +30,40 @@ | |||
30 | #if !defined(LED_ARRAY) && defined(RGB_MATRIX_ENABLE) | 30 | #if !defined(LED_ARRAY) && defined(RGB_MATRIX_ENABLE) |
31 | // LED color buffer | 31 | // LED color buffer |
32 | LED_TYPE led[DRIVER_LED_TOTAL]; | 32 | LED_TYPE led[DRIVER_LED_TOTAL]; |
33 | #define LED_ARRAY led | 33 | # define LED_ARRAY led |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #ifdef RGBW_BB_TWI | 36 | #ifdef RGBW_BB_TWI |
37 | 37 | ||
38 | // Port for the I2C | 38 | // Port for the I2C |
39 | #define I2C_DDR DDRD | 39 | # define I2C_DDR DDRD |
40 | #define I2C_PIN PIND | 40 | # define I2C_PIN PIND |
41 | #define I2C_PORT PORTD | 41 | # define I2C_PORT PORTD |
42 | 42 | ||
43 | // Pins to be used in the bit banging | 43 | // Pins to be used in the bit banging |
44 | #define I2C_CLK 0 | 44 | # define I2C_CLK 0 |
45 | #define I2C_DAT 1 | 45 | # define I2C_DAT 1 |
46 | 46 | ||
47 | #define I2C_DATA_HI()\ | 47 | # define I2C_DATA_HI() \ |
48 | I2C_DDR &= ~ (1 << I2C_DAT);\ | 48 | I2C_DDR &= ~(1 << I2C_DAT); \ |
49 | I2C_PORT |= (1 << I2C_DAT); | 49 | I2C_PORT |= (1 << I2C_DAT); |
50 | #define I2C_DATA_LO()\ | 50 | # define I2C_DATA_LO() \ |
51 | I2C_DDR |= (1 << I2C_DAT);\ | 51 | I2C_DDR |= (1 << I2C_DAT); \ |
52 | I2C_PORT &= ~ (1 << I2C_DAT); | 52 | I2C_PORT &= ~(1 << I2C_DAT); |
53 | 53 | ||
54 | #define I2C_CLOCK_HI()\ | 54 | # define I2C_CLOCK_HI() \ |
55 | I2C_DDR &= ~ (1 << I2C_CLK);\ | 55 | I2C_DDR &= ~(1 << I2C_CLK); \ |
56 | I2C_PORT |= (1 << I2C_CLK); | 56 | I2C_PORT |= (1 << I2C_CLK); |
57 | #define I2C_CLOCK_LO()\ | 57 | # define I2C_CLOCK_LO() \ |
58 | I2C_DDR |= (1 << I2C_CLK);\ | 58 | I2C_DDR |= (1 << I2C_CLK); \ |
59 | I2C_PORT &= ~ (1 << I2C_CLK); | 59 | I2C_PORT &= ~(1 << I2C_CLK); |
60 | 60 | ||
61 | #define I2C_DELAY 1 | 61 | # define I2C_DELAY 1 |
62 | 62 | ||
63 | void I2C_WriteBit(unsigned char c) | 63 | void I2C_WriteBit(unsigned char c) { |
64 | { | 64 | if (c > 0) { |
65 | if (c > 0) | ||
66 | { | ||
67 | I2C_DATA_HI(); | 65 | I2C_DATA_HI(); |
68 | } | 66 | } else { |
69 | else | ||
70 | { | ||
71 | I2C_DATA_LO(); | 67 | I2C_DATA_LO(); |
72 | } | 68 | } |
73 | 69 | ||
@@ -77,8 +73,7 @@ void I2C_WriteBit(unsigned char c) | |||
77 | I2C_CLOCK_LO(); | 73 | I2C_CLOCK_LO(); |
78 | _delay_us(I2C_DELAY); | 74 | _delay_us(I2C_DELAY); |
79 | 75 | ||
80 | if (c > 0) | 76 | if (c > 0) { |
81 | { | ||
82 | I2C_DATA_LO(); | 77 | I2C_DATA_LO(); |
83 | } | 78 | } |
84 | 79 | ||
@@ -87,9 +82,8 @@ void I2C_WriteBit(unsigned char c) | |||
87 | 82 | ||
88 | // Inits bitbanging port, must be called before using the functions below | 83 | // Inits bitbanging port, must be called before using the functions below |
89 | // | 84 | // |
90 | void I2C_Init(void) | 85 | void I2C_Init(void) { |
91 | { | 86 | I2C_PORT &= ~((1 << I2C_DAT) | (1 << I2C_CLK)); |
92 | I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); | ||
93 | 87 | ||
94 | I2C_CLOCK_HI(); | 88 | I2C_CLOCK_HI(); |
95 | I2C_DATA_HI(); | 89 | I2C_DATA_HI(); |
@@ -99,10 +93,9 @@ void I2C_Init(void) | |||
99 | 93 | ||
100 | // Send a START Condition | 94 | // Send a START Condition |
101 | // | 95 | // |
102 | void I2C_Start(void) | 96 | void I2C_Start(void) { |
103 | { | ||
104 | // set both to high at the same time | 97 | // set both to high at the same time |
105 | I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); | 98 | I2C_DDR &= ~((1 << I2C_DAT) | (1 << I2C_CLK)); |
106 | _delay_us(I2C_DELAY); | 99 | _delay_us(I2C_DELAY); |
107 | 100 | ||
108 | I2C_DATA_LO(); | 101 | I2C_DATA_LO(); |
@@ -114,8 +107,7 @@ void I2C_Start(void) | |||
114 | 107 | ||
115 | // Send a STOP Condition | 108 | // Send a STOP Condition |
116 | // | 109 | // |
117 | void I2C_Stop(void) | 110 | void I2C_Stop(void) { |
118 | { | ||
119 | I2C_CLOCK_HI(); | 111 | I2C_CLOCK_HI(); |
120 | _delay_us(I2C_DELAY); | 112 | _delay_us(I2C_DELAY); |
121 | 113 | ||
@@ -125,106 +117,91 @@ void I2C_Stop(void) | |||
125 | 117 | ||
126 | // write a byte to the I2C slave device | 118 | // write a byte to the I2C slave device |
127 | // | 119 | // |
128 | unsigned char I2C_Write(unsigned char c) | 120 | unsigned char I2C_Write(unsigned char c) { |
129 | { | 121 | for (char i = 0; i < 8; i++) { |
130 | for (char i = 0; i < 8; i++) | ||
131 | { | ||
132 | I2C_WriteBit(c & 128); | 122 | I2C_WriteBit(c & 128); |
133 | 123 | ||
134 | c <<= 1; | 124 | c <<= 1; |
135 | } | 125 | } |
136 | 126 | ||
137 | |||
138 | I2C_WriteBit(0); | 127 | I2C_WriteBit(0); |
139 | _delay_us(I2C_DELAY); | 128 | _delay_us(I2C_DELAY); |
140 | _delay_us(I2C_DELAY); | 129 | _delay_us(I2C_DELAY); |
141 | 130 | ||
142 | // _delay_us(I2C_DELAY); | 131 | // _delay_us(I2C_DELAY); |
143 | //return I2C_ReadBit(); | 132 | // return I2C_ReadBit(); |
144 | return 0; | 133 | return 0; |
145 | } | 134 | } |
146 | 135 | ||
147 | |||
148 | #endif | 136 | #endif |
149 | 137 | ||
150 | #ifdef RGB_MATRIX_ENABLE | 138 | #ifdef RGB_MATRIX_ENABLE |
151 | // Set an led in the buffer to a color | 139 | // Set an led in the buffer to a color |
152 | void inline ws2812_setled(int i, uint8_t r, uint8_t g, uint8_t b) | 140 | void inline ws2812_setled(int i, uint8_t r, uint8_t g, uint8_t b) { |
153 | { | ||
154 | led[i].r = r; | 141 | led[i].r = r; |
155 | led[i].g = g; | 142 | led[i].g = g; |
156 | led[i].b = b; | 143 | led[i].b = b; |
157 | } | 144 | } |
158 | 145 | ||
159 | void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b) | 146 | void ws2812_setled_all(uint8_t r, uint8_t g, uint8_t b) { |
160 | { | 147 | for (int i = 0; i < sizeof(led) / sizeof(led[0]); i++) { |
161 | for (int i = 0; i < sizeof(led)/sizeof(led[0]); i++) { | 148 | led[i].r = r; |
162 | led[i].r = r; | 149 | led[i].g = g; |
163 | led[i].g = g; | 150 | led[i].b = b; |
164 | led[i].b = b; | 151 | } |
165 | } | ||
166 | } | 152 | } |
167 | #endif | 153 | #endif |
168 | 154 | ||
169 | // Setleds for standard RGB | 155 | // Setleds for standard RGB |
170 | void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) | 156 | void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { |
171 | { | 157 | // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); |
172 | // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); | 158 | ws2812_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF)); |
173 | ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); | ||
174 | } | 159 | } |
175 | 160 | ||
176 | void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) | 161 | void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) { |
177 | { | 162 | // ws2812_DDRREG |= pinmask; // Enable DDR |
178 | // ws2812_DDRREG |= pinmask; // Enable DDR | 163 | // new universal format (DDR) |
179 | // new universal format (DDR) | 164 | _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask; |
180 | _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask; | ||
181 | 165 | ||
182 | ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask); | 166 | ws2812_sendarray_mask((uint8_t *)ledarray, leds + leds + leds, pinmask); |
183 | _delay_us(50); | 167 | _delay_us(50); |
184 | } | 168 | } |
185 | 169 | ||
186 | // Setleds for SK6812RGBW | 170 | // Setleds for SK6812RGBW |
187 | void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) | 171 | void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) { |
188 | { | 172 | #ifdef RGBW_BB_TWI |
189 | |||
190 | #ifdef RGBW_BB_TWI | ||
191 | uint8_t sreg_prev, twcr_prev; | 173 | uint8_t sreg_prev, twcr_prev; |
192 | sreg_prev=SREG; | 174 | sreg_prev = SREG; |
193 | twcr_prev=TWCR; | 175 | twcr_prev = TWCR; |
194 | cli(); | 176 | cli(); |
195 | TWCR &= ~(1<<TWEN); | 177 | TWCR &= ~(1 << TWEN); |
196 | I2C_Init(); | 178 | I2C_Init(); |
197 | I2C_Start(); | 179 | I2C_Start(); |
198 | I2C_Write(0x84); | 180 | I2C_Write(0x84); |
199 | uint16_t datlen = leds<<2; | 181 | uint16_t datlen = leds << 2; |
200 | uint8_t curbyte; | 182 | uint8_t curbyte; |
201 | uint8_t * data = (uint8_t*)ledarray; | 183 | uint8_t *data = (uint8_t *)ledarray; |
202 | while (datlen--) { | 184 | while (datlen--) { |
203 | curbyte=*data++; | 185 | curbyte = *data++; |
204 | I2C_Write(curbyte); | 186 | I2C_Write(curbyte); |
205 | } | 187 | } |
206 | I2C_Stop(); | 188 | I2C_Stop(); |
207 | SREG=sreg_prev; | 189 | SREG = sreg_prev; |
208 | TWCR=twcr_prev; | 190 | TWCR = twcr_prev; |
209 | #endif | 191 | #endif |
210 | |||
211 | |||
212 | // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR | ||
213 | // new universal format (DDR) | ||
214 | _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); | ||
215 | 192 | ||
216 | ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); | 193 | // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR |
194 | // new universal format (DDR) | ||
195 | _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); | ||
217 | 196 | ||
197 | ws2812_sendarray_mask((uint8_t *)ledarray, leds << 2, _BV(RGB_DI_PIN & 0xF)); | ||
218 | 198 | ||
219 | #ifndef RGBW_BB_TWI | 199 | #ifndef RGBW_BB_TWI |
220 | _delay_us(80); | 200 | _delay_us(80); |
221 | #endif | 201 | #endif |
222 | } | 202 | } |
223 | 203 | ||
224 | void ws2812_sendarray(uint8_t *data,uint16_t datlen) | 204 | void ws2812_sendarray(uint8_t *data, uint16_t datlen) { ws2812_sendarray_mask(data, datlen, _BV(RGB_DI_PIN & 0xF)); } |
225 | { | ||
226 | ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF)); | ||
227 | } | ||
228 | 205 | ||
229 | /* | 206 | /* |
230 | This routine writes an array of bytes with RGB values to the Dataout pin | 207 | This routine writes an array of bytes with RGB values to the Dataout pin |
@@ -232,136 +209,133 @@ void ws2812_sendarray(uint8_t *data,uint16_t datlen) | |||
232 | */ | 209 | */ |
233 | 210 | ||
234 | // Timing in ns | 211 | // Timing in ns |
235 | #define w_zeropulse 350 | 212 | #define w_zeropulse 350 |
236 | #define w_onepulse 900 | 213 | #define w_onepulse 900 |
237 | #define w_totalperiod 1250 | 214 | #define w_totalperiod 1250 |
238 | 215 | ||
239 | // Fixed cycles used by the inner loop | 216 | // Fixed cycles used by the inner loop |
240 | #define w_fixedlow 2 | 217 | #define w_fixedlow 2 |
241 | #define w_fixedhigh 4 | 218 | #define w_fixedhigh 4 |
242 | #define w_fixedtotal 8 | 219 | #define w_fixedtotal 8 |
243 | 220 | ||
244 | // Insert NOPs to match the timing, if possible | 221 | // Insert NOPs to match the timing, if possible |
245 | #define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) | 222 | #define w_zerocycles (((F_CPU / 1000) * w_zeropulse) / 1000000) |
246 | #define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) | 223 | #define w_onecycles (((F_CPU / 1000) * w_onepulse + 500000) / 1000000) |
247 | #define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) | 224 | #define w_totalcycles (((F_CPU / 1000) * w_totalperiod + 500000) / 1000000) |
248 | 225 | ||
249 | // w1 - nops between rising edge and falling edge - low | 226 | // w1 - nops between rising edge and falling edge - low |
250 | #define w1 (w_zerocycles-w_fixedlow) | 227 | #define w1 (w_zerocycles - w_fixedlow) |
251 | // w2 nops between fe low and fe high | 228 | // w2 nops between fe low and fe high |
252 | #define w2 (w_onecycles-w_fixedhigh-w1) | 229 | #define w2 (w_onecycles - w_fixedhigh - w1) |
253 | // w3 nops to complete loop | 230 | // w3 nops to complete loop |
254 | #define w3 (w_totalcycles-w_fixedtotal-w1-w2) | 231 | #define w3 (w_totalcycles - w_fixedtotal - w1 - w2) |
255 | 232 | ||
256 | #if w1>0 | 233 | #if w1 > 0 |
257 | #define w1_nops w1 | 234 | # define w1_nops w1 |
258 | #else | 235 | #else |
259 | #define w1_nops 0 | 236 | # define w1_nops 0 |
260 | #endif | 237 | #endif |
261 | 238 | ||
262 | // The only critical timing parameter is the minimum pulse length of the "0" | 239 | // The only critical timing parameter is the minimum pulse length of the "0" |
263 | // Warn or throw error if this timing can not be met with current F_CPU settings. | 240 | // Warn or throw error if this timing can not be met with current F_CPU settings. |
264 | #define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) | 241 | #define w_lowtime ((w1_nops + w_fixedlow) * 1000000) / (F_CPU / 1000) |
265 | #if w_lowtime>550 | 242 | #if w_lowtime > 550 |
266 | #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" | 243 | # error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" |
267 | #elif w_lowtime>450 | 244 | #elif w_lowtime > 450 |
268 | #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." | 245 | # warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." |
269 | #warning "Please consider a higher clockspeed, if possible" | 246 | # warning "Please consider a higher clockspeed, if possible" |
270 | #endif | 247 | #endif |
271 | 248 | ||
272 | #if w2>0 | 249 | #if w2 > 0 |
273 | #define w2_nops w2 | 250 | # define w2_nops w2 |
274 | #else | 251 | #else |
275 | #define w2_nops 0 | 252 | # define w2_nops 0 |
276 | #endif | 253 | #endif |
277 | 254 | ||
278 | #if w3>0 | 255 | #if w3 > 0 |
279 | #define w3_nops w3 | 256 | # define w3_nops w3 |
280 | #else | 257 | #else |
281 | #define w3_nops 0 | 258 | # define w3_nops 0 |
282 | #endif | 259 | #endif |
283 | 260 | ||
284 | #define w_nop1 "nop \n\t" | 261 | #define w_nop1 "nop \n\t" |
285 | #define w_nop2 "rjmp .+0 \n\t" | 262 | #define w_nop2 "rjmp .+0 \n\t" |
286 | #define w_nop4 w_nop2 w_nop2 | 263 | #define w_nop4 w_nop2 w_nop2 |
287 | #define w_nop8 w_nop4 w_nop4 | 264 | #define w_nop8 w_nop4 w_nop4 |
288 | #define w_nop16 w_nop8 w_nop8 | 265 | #define w_nop16 w_nop8 w_nop8 |
289 | 266 | ||
290 | void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) | 267 | void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi) { |
291 | { | 268 | uint8_t curbyte, ctr, masklo; |
292 | uint8_t curbyte,ctr,masklo; | 269 | uint8_t sreg_prev; |
293 | uint8_t sreg_prev; | 270 | |
294 | 271 | // masklo =~maskhi&ws2812_PORTREG; | |
295 | // masklo =~maskhi&ws2812_PORTREG; | 272 | // maskhi |= ws2812_PORTREG; |
296 | // maskhi |= ws2812_PORTREG; | 273 | masklo = ~maskhi & _SFR_IO8((RGB_DI_PIN >> 4) + 2); |
297 | masklo =~maskhi&_SFR_IO8((RGB_DI_PIN >> 4) + 2); | 274 | maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2); |
298 | maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2); | 275 | sreg_prev = SREG; |
299 | sreg_prev=SREG; | 276 | cli(); |
300 | cli(); | 277 | |
301 | 278 | while (datlen--) { | |
302 | while (datlen--) { | 279 | curbyte = (*data++); |
303 | curbyte=(*data++); | 280 | |
304 | 281 | asm volatile(" ldi %0,8 \n\t" | |
305 | asm volatile( | 282 | "loop%=: \n\t" |
306 | " ldi %0,8 \n\t" | 283 | " out %2,%3 \n\t" // '1' [01] '0' [01] - re |
307 | "loop%=: \n\t" | 284 | #if (w1_nops & 1) |
308 | " out %2,%3 \n\t" // '1' [01] '0' [01] - re | 285 | w_nop1 |
309 | #if (w1_nops&1) | ||
310 | w_nop1 | ||
311 | #endif | 286 | #endif |
312 | #if (w1_nops&2) | 287 | #if (w1_nops & 2) |
313 | w_nop2 | 288 | w_nop2 |
314 | #endif | 289 | #endif |
315 | #if (w1_nops&4) | 290 | #if (w1_nops & 4) |
316 | w_nop4 | 291 | w_nop4 |
317 | #endif | 292 | #endif |
318 | #if (w1_nops&8) | 293 | #if (w1_nops & 8) |
319 | w_nop8 | 294 | w_nop8 |
320 | #endif | 295 | #endif |
321 | #if (w1_nops&16) | 296 | #if (w1_nops & 16) |
322 | w_nop16 | 297 | w_nop16 |
323 | #endif | 298 | #endif |
324 | " sbrs %1,7 \n\t" // '1' [03] '0' [02] | 299 | " sbrs %1,7 \n\t" // '1' [03] '0' [02] |
325 | " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low | 300 | " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low |
326 | " lsl %1 \n\t" // '1' [04] '0' [04] | 301 | " lsl %1 \n\t" // '1' [04] '0' [04] |
327 | #if (w2_nops&1) | 302 | #if (w2_nops & 1) |
328 | w_nop1 | 303 | w_nop1 |
329 | #endif | 304 | #endif |
330 | #if (w2_nops&2) | 305 | #if (w2_nops & 2) |
331 | w_nop2 | 306 | w_nop2 |
332 | #endif | 307 | #endif |
333 | #if (w2_nops&4) | 308 | #if (w2_nops & 4) |
334 | w_nop4 | 309 | w_nop4 |
335 | #endif | 310 | #endif |
336 | #if (w2_nops&8) | 311 | #if (w2_nops & 8) |
337 | w_nop8 | 312 | w_nop8 |
338 | #endif | 313 | #endif |
339 | #if (w2_nops&16) | 314 | #if (w2_nops & 16) |
340 | w_nop16 | 315 | w_nop16 |
341 | #endif | 316 | #endif |
342 | " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high | 317 | " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high |
343 | #if (w3_nops&1) | 318 | #if (w3_nops & 1) |
344 | w_nop1 | 319 | w_nop1 |
345 | #endif | 320 | #endif |
346 | #if (w3_nops&2) | 321 | #if (w3_nops & 2) |
347 | w_nop2 | 322 | w_nop2 |
348 | #endif | 323 | #endif |
349 | #if (w3_nops&4) | 324 | #if (w3_nops & 4) |
350 | w_nop4 | 325 | w_nop4 |
351 | #endif | 326 | #endif |
352 | #if (w3_nops&8) | 327 | #if (w3_nops & 8) |
353 | w_nop8 | 328 | w_nop8 |
354 | #endif | 329 | #endif |
355 | #if (w3_nops&16) | 330 | #if (w3_nops & 16) |
356 | w_nop16 | 331 | w_nop16 |
357 | #endif | 332 | #endif |
358 | 333 | ||
359 | " dec %0 \n\t" // '1' [+2] '0' [+2] | 334 | " dec %0 \n\t" // '1' [+2] '0' [+2] |
360 | " brne loop%=\n\t" // '1' [+3] '0' [+4] | 335 | " brne loop%=\n\t" // '1' [+3] '0' [+4] |
361 | : "=&d" (ctr) | 336 | : "=&d"(ctr) |
362 | : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo) | 337 | : "r"(curbyte), "I"(_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r"(maskhi), "r"(masklo)); |
363 | ); | 338 | } |
364 | } | ||
365 | 339 | ||
366 | SREG=sreg_prev; | 340 | SREG = sreg_prev; |
367 | } | 341 | } |
diff --git a/drivers/avr/ws2812.h b/drivers/avr/ws2812.h index 95f540b18..a9dd89718 100644 --- a/drivers/avr/ws2812.h +++ b/drivers/avr/ws2812.h | |||
@@ -43,12 +43,12 @@ | |||
43 | * - Wait 50�s to reset the LEDs | 43 | * - Wait 50�s to reset the LEDs |
44 | */ | 44 | */ |
45 | #ifdef RGB_MATRIX_ENABLE | 45 | #ifdef RGB_MATRIX_ENABLE |
46 | void ws2812_setled (int index, uint8_t r, uint8_t g, uint8_t b); | 46 | void ws2812_setled(int index, uint8_t r, uint8_t g, uint8_t b); |
47 | void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b); | 47 | void ws2812_setled_all(uint8_t r, uint8_t g, uint8_t b); |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds); | 50 | void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds); |
51 | void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask); | 51 | void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask); |
52 | void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); | 52 | void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); |
53 | 53 | ||
54 | /* | 54 | /* |
@@ -58,18 +58,17 @@ void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); | |||
58 | * The length is the number of bytes to send - three per LED. | 58 | * The length is the number of bytes to send - three per LED. |
59 | */ | 59 | */ |
60 | 60 | ||
61 | void ws2812_sendarray (uint8_t *array,uint16_t length); | 61 | void ws2812_sendarray(uint8_t *array, uint16_t length); |
62 | void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask); | 62 | void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask); |
63 | |||
64 | 63 | ||
65 | /* | 64 | /* |
66 | * Internal defines | 65 | * Internal defines |
67 | */ | 66 | */ |
68 | #ifndef CONCAT | 67 | #ifndef CONCAT |
69 | #define CONCAT(a, b) a ## b | 68 | # define CONCAT(a, b) a##b |
70 | #endif | 69 | #endif |
71 | #ifndef CONCAT_EXP | 70 | #ifndef CONCAT_EXP |
72 | #define CONCAT_EXP(a, b) CONCAT(a, b) | 71 | # define CONCAT_EXP(a, b) CONCAT(a, b) |
73 | #endif | 72 | #endif |
74 | 73 | ||
75 | #endif /* LIGHT_WS2812_H_ */ | 74 | #endif /* LIGHT_WS2812_H_ */ |