summaryrefslogtreecommitdiff
path: root/drivers/avr
diff options
context:
space:
mode:
authorWilliam Chang <william@factual.com>2019-11-20 22:17:07 -0800
committerWilliam Chang <william@factual.com>2019-11-20 22:17:07 -0800
commite7f4d56592b3975c38af329e77b4efd9108495e8 (patch)
tree0a416bccbf70bfdbdb9ffcdb3bf136b47378c014 /drivers/avr
parent71493b2f9bbd5f3d18373c518fa14ccafcbf48fc (diff)
parent8416a94ad27b3ff058576f09f35f0704a8b39ff3 (diff)
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'drivers/avr')
-rw-r--r--drivers/avr/analog.c53
-rw-r--r--drivers/avr/analog.h32
-rw-r--r--[-rwxr-xr-x]drivers/avr/apa102.c147
-rw-r--r--[-rwxr-xr-x]drivers/avr/apa102.h5
-rw-r--r--drivers/avr/glcdfont.c280
-rw-r--r--drivers/avr/hd44780.c510
-rw-r--r--drivers/avr/hd44780.h303
-rw-r--r--[-rwxr-xr-x]drivers/avr/i2c_master.c279
-rw-r--r--[-rwxr-xr-x]drivers/avr/i2c_master.h27
-rw-r--r--[-rwxr-xr-x]drivers/avr/i2c_slave.c35
-rw-r--r--[-rwxr-xr-x]drivers/avr/i2c_slave.h17
-rw-r--r--drivers/avr/pro_micro.h270
-rw-r--r--drivers/avr/ssd1306.c427
-rw-r--r--drivers/avr/ssd1306.h84
-rw-r--r--drivers/avr/ws2812.c422
-rw-r--r--drivers/avr/ws2812.h43
-rw-r--r--drivers/avr/ws2812_i2c.c27
17 files changed, 1233 insertions, 1728 deletions
diff --git a/drivers/avr/analog.c b/drivers/avr/analog.c
index 1ec38df75d..1a8da4261d 100644
--- a/drivers/avr/analog.c
+++ b/drivers/avr/analog.c
@@ -21,49 +21,38 @@
#include <stdint.h>
#include "analog.h"
+static uint8_t aref = (1 << REFS0); // default to AREF = Vcc
-static uint8_t aref = (1<<REFS0); // default to AREF = Vcc
-
-
-void analogReference(uint8_t mode)
-{
- aref = mode & 0xC0;
-}
-
+void analogReference(uint8_t mode) { aref = mode & 0xC0; }
// Arduino compatible pin input
-int16_t analogRead(uint8_t pin)
-{
+int16_t analogRead(uint8_t pin) {
#if defined(__AVR_ATmega32U4__)
- static const uint8_t PROGMEM pin_to_mux[] = {
- 0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
- 0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
- if (pin >= 12) return 0;
- return adc_read(pgm_read_byte(pin_to_mux + pin));
+ static const uint8_t PROGMEM pin_to_mux[] = {0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
+ if (pin >= 12) return 0;
+ return adc_read(pgm_read_byte(pin_to_mux + pin));
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
- if (pin >= 8) return 0;
- return adc_read(pin);
+ if (pin >= 8) return 0;
+ return adc_read(pin);
#else
- return 0;
+ return 0;
#endif
}
// Mux input
-int16_t adc_read(uint8_t mux)
-{
+int16_t adc_read(uint8_t mux) {
#if defined(__AVR_AT90USB162__)
- return 0;
+ return 0;
#else
- uint8_t low;
-
- ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
- ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
- ADMUX = aref | (mux & 0x1F); // configure mux input
- ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
- while (ADCSRA & (1<<ADSC)) ; // wait for result
- low = ADCL; // must read LSB first
- return (ADCH << 8) | low; // must read MSB only once!
+ uint8_t low;
+
+ ADCSRA = (1 << ADEN) | ADC_PRESCALER; // enable ADC
+ ADCSRB = (1 << ADHSM) | (mux & 0x20); // high speed mode
+ ADMUX = aref | (mux & 0x1F); // configure mux input
+ ADCSRA = (1 << ADEN) | ADC_PRESCALER | (1 << ADSC); // start the conversion
+ while (ADCSRA & (1 << ADSC))
+ ; // wait for result
+ low = ADCL; // must read LSB first
+ return (ADCH << 8) | low; // must read MSB only once!
#endif
}
-
-
diff --git a/drivers/avr/analog.h b/drivers/avr/analog.h
index 8d93de7dc2..1b773d82ce 100644
--- a/drivers/avr/analog.h
+++ b/drivers/avr/analog.h
@@ -19,34 +19,40 @@
#include <stdint.h>
-void analogReference(uint8_t mode);
+#ifdef __cplusplus
+extern "C" {
+#endif
+void analogReference(uint8_t mode);
int16_t analogRead(uint8_t pin);
int16_t adc_read(uint8_t mux);
+#ifdef __cplusplus
+}
+#endif
-#define ADC_REF_POWER (1<<REFS0)
-#define ADC_REF_INTERNAL ((1<<REFS1) | (1<<REFS0))
-#define ADC_REF_EXTERNAL (0)
+#define ADC_REF_POWER (1 << REFS0)
+#define ADC_REF_INTERNAL ((1 << REFS1) | (1 << REFS0))
+#define ADC_REF_EXTERNAL (0)
// These prescaler values are for high speed mode, ADHSM = 1
#if F_CPU == 16000000L
-#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS1))
+# define ADC_PRESCALER ((1 << ADPS2) | (1 << ADPS1))
#elif F_CPU == 8000000L
-#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS0))
+# define ADC_PRESCALER ((1 << ADPS2) | (1 << ADPS0))
#elif F_CPU == 4000000L
-#define ADC_PRESCALER ((1<<ADPS2))
+# define ADC_PRESCALER ((1 << ADPS2))
#elif F_CPU == 2000000L
-#define ADC_PRESCALER ((1<<ADPS1) | (1<<ADPS0))
+# define ADC_PRESCALER ((1 << ADPS1) | (1 << ADPS0))
#elif F_CPU == 1000000L
-#define ADC_PRESCALER ((1<<ADPS1))
+# define ADC_PRESCALER ((1 << ADPS1))
#else
-#define ADC_PRESCALER ((1<<ADPS0))
+# define ADC_PRESCALER ((1 << ADPS0))
#endif
// some avr-libc versions do not properly define ADHSM
#if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
-#if !defined(ADHSM)
-#define ADHSM (7)
-#endif
+# if !defined(ADHSM)
+# define ADHSM (7)
+# endif
#endif
#endif
diff --git a/drivers/avr/apa102.c b/drivers/avr/apa102.c
index 55a0d57778..f4d97a1589 100755..100644
--- a/drivers/avr/apa102.c
+++ b/drivers/avr/apa102.c
@@ -1,24 +1,24 @@
/*
-* APA102 lib V1.0a
-*
-* Controls APA102 RGB-LEDs
-* Author: Mikkel (Duckle29 on github)
-*
-* Dec 22th, 2017 v1.0a Initial Version
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ * APA102 lib V1.0a
+ *
+ * Controls APA102 RGB-LEDs
+ * Author: Mikkel (Duckle29 on github)
+ *
+ * Dec 22th, 2017 v1.0a Initial Version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include "apa102.h"
#include <avr/interrupt.h>
@@ -27,75 +27,70 @@
#include "debug.h"
// Setleds for standard RGB
-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));
-}
+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)); }
-void static inline apa102_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask_DI, uint8_t pinmask_CLK){
- pinMode(RGB_DI_PIN, PinDirectionOutput);
- pinMode(RGB_CLK_PIN, PinDirectionOutput);
+void static inline apa102_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask_DI, uint8_t pinmask_CLK) {
+ pinMode(RGB_DI_PIN, PinDirectionOutput);
+ pinMode(RGB_CLK_PIN, PinDirectionOutput);
- apa102_send_array((uint8_t*)ledarray,leds)
+ apa102_send_array((uint8_t *)ledarray, leds)
}
-void apa102_send_array(uint8_t *data, uint16_t leds){ // Data is struct of 3 bytes. RGB - leds is number of leds in data
- apa102_start_frame();
- while(leds--){
- apa102_send_frame(0xFF000000 | (data->b << 16) | (data->g << 8) | data->r);
- data++;
- }
- apa102_end_frame(leds);
+void apa102_send_array(uint8_t *data, uint16_t leds) { // Data is struct of 3 bytes. RGB - leds is number of leds in data
+ apa102_start_frame();
+ while (leds--) {
+ apa102_send_frame(0xFF000000 | (data->b << 16) | (data->g << 8) | data->r);
+ data++;
+ }
+ apa102_end_frame(leds);
}
-void apa102_send_frame(uint32_t frame){
- for(uint32_t i=0xFF; i>0;){
- apa102_send_byte(frame & i);
- i = i << 8;
- }
+void apa102_send_frame(uint32_t frame) {
+ for (uint32_t i = 0xFF; i > 0;) {
+ apa102_send_byte(frame & i);
+ i = i << 8;
+ }
}
-void apa102_start_frame(){
- apa102_send_frame(0);
-}
+void apa102_start_frame() { apa102_send_frame(0); }
-void apa102_end_frame(uint16_t leds)
-{
- // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h
- // and adapted. The code is MIT licensed. I think thats compatible?
+void apa102_end_frame(uint16_t leds) {
+ // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h
+ // and adapted. The code is MIT licensed. I think thats compatible?
- // We need to send some more bytes to ensure that all the LEDs in the
- // chain see their new color and start displaying it.
- //
- // The data stream seen by the last LED in the chain will be delayed by
- // (count - 1) clock edges, because each LED before it inverts the clock
- // line and delays the data by one clock edge. Therefore, to make sure
- // the last LED actually receives the data we wrote, the number of extra
- // edges we send at the end of the frame must be at least (count - 1).
- // For the APA102C, that is sufficient.
- //
- // The SK9822 only updates after it sees 32 zero bits followed by one more
- // rising edge. To avoid having the update time depend on the color of
- // the last LED, we send a dummy 0xFF byte. (Unfortunately, this means
- // that partial updates of the beginning of an LED strip are not possible;
- // the LED after the last one you are trying to update will be black.)
- // After that, to ensure that the last LED in the chain sees 32 zero bits
- // and a rising edge, we need to send at least 65 + (count - 1) edges. It
- // is sufficent and simpler to just send (5 + count/16) bytes of zeros.
- //
- // We are ignoring the specification for the end frame in the APA102/SK9822
- // datasheets because it does not actually ensure that all the LEDs will
- // start displaying their new colors right away.
+ // We need to send some more bytes to ensure that all the LEDs in the
+ // chain see their new color and start displaying it.
+ //
+ // The data stream seen by the last LED in the chain will be delayed by
+ // (count - 1) clock edges, because each LED before it inverts the clock
+ // line and delays the data by one clock edge. Therefore, to make sure
+ // the last LED actually receives the data we wrote, the number of extra
+ // edges we send at the end of the frame must be at least (count - 1).
+ // For the APA102C, that is sufficient.
+ //
+ // The SK9822 only updates after it sees 32 zero bits followed by one more
+ // rising edge. To avoid having the update time depend on the color of
+ // the last LED, we send a dummy 0xFF byte. (Unfortunately, this means
+ // that partial updates of the beginning of an LED strip are not possible;
+ // the LED after the last one you are trying to update will be black.)
+ // After that, to ensure that the last LED in the chain sees 32 zero bits
+ // and a rising edge, we need to send at least 65 + (count - 1) edges. It
+ // is sufficent and simpler to just send (5 + count/16) bytes of zeros.
+ //
+ // We are ignoring the specification for the end frame in the APA102/SK9822
+ // datasheets because it does not actually ensure that all the LEDs will
+ // start displaying their new colors right away.
- apa102_send_byte(0xFF);
- for (uint16_t i = 0; i < 5 + leds / 16; i++){
- apa102_send_byte(0);
- }
+ apa102_send_byte(0xFF);
+ for (uint16_t i = 0; i < 5 + leds / 16; i++) {
+ apa102_send_byte(0);
+ }
}
-void apa102_send_byte(uint8_t byte){
- uint8_t i;
- for (i = 0; i < 8; i++){
+void apa102_send_byte(uint8_t byte) {
+ uint8_t i;
+ for (i = 0; i < 8; i++) {
digitalWrite(RGB_DI_PIN, !!(byte & (1 << (7-i)));
digitalWrite(RGB_CLK_PIN, PinLevelHigh);
- }
+ }
}
diff --git a/drivers/avr/apa102.h b/drivers/avr/apa102.h
index 5d852e0673..d4c1e18ee1 100755..100644
--- a/drivers/avr/apa102.h
+++ b/drivers/avr/apa102.h
@@ -27,7 +27,6 @@
#include "color.h"
-
/* User Interface
*
* Input:
@@ -41,6 +40,6 @@
* - Wait 50�s to reset the LEDs
*/
-void apa102_setleds (LED_TYPE *ledarray, uint16_t number_of_leds);
-void apa102_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask);
+void apa102_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
+void apa102_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask);
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 6f88bd23a7..2c332ea6db 100644
--- a/drivers/avr/glcdfont.c
+++ b/drivers/avr/glcdfont.c
@@ -5,272 +5,30 @@
#define FONT5X7_H
#ifdef __AVR__
- #include <avr/io.h>
- #include <avr/pgmspace.h>
+# include <avr/io.h>
+# include <avr/pgmspace.h>
#elif defined(ESP8266)
- #include <pgmspace.h>
+# include <pgmspace.h>
#else
- #define PROGMEM
+# define PROGMEM
#endif
// Standard ASCII 5x7 font
static const unsigned char font[] PROGMEM = {
- 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,
- 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,
- 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,
- 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,
- 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
- 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
- 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
- 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
- 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
- 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
- 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
- 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,
- 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
- 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
+ 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,
+ 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,
+ 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,
+ 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,
+ 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
+ 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
+ 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
+ 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
+ 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
+ 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
+ 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
+ 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,
+ 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
+ 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
};
-#endif // FONT5X7_H
+#endif // FONT5X7_H
diff --git a/drivers/avr/hd44780.c b/drivers/avr/hd44780.c
index 51414d8f91..f71069dece 100644
--- a/drivers/avr/hd44780.c
+++ b/drivers/avr/hd44780.c
@@ -3,7 +3,7 @@
Author: Peter Fleury <pfleury@gmx.ch> http://tinyurl.com/peterfleury
License: GNU General Public License Version 3
File: $Id: lcd.c,v 1.15.2.2 2015/01/17 12:16:05 peter Exp $
- Software: AVR-GCC 3.3
+ Software: AVR-GCC 3.3
Target: any AVR device, memory mapped mode only for AT90S4414/8515/Mega
DESCRIPTION
@@ -13,15 +13,15 @@
changed lcd_init(), added additional constants for lcd_command(),
added 4-bit I/O mode, improved and optimized code.
- Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in
+ Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in
4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported.
-
+
Memory mapped mode compatible with Kanda STK200, but supports also
generation of R/W signal through A8 address line.
USAGE
See the C include lcd.h file for a description of each function
-
+
*****************************************************************************/
#include <inttypes.h>
#include <avr/io.h>
@@ -29,55 +29,54 @@
#include <util/delay.h>
#include "hd44780.h"
-/*
-** constants/macros
+/*
+** constants/macros
*/
-#define DDR(x) (*(&x - 1)) /* address of data direction register of port x */
+#define DDR(x) (*(&x - 1)) /* address of data direction register of port x */
#if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
- /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */
- #define PIN(x) ( &PORTF==&(x) ? _SFR_IO8(0x00) : (*(&x - 2)) )
+/* on ATmega64/128 PINF is on port 0x00 and not 0x60 */
+# define PIN(x) (&PORTF == &(x) ? _SFR_IO8(0x00) : (*(&x - 2)))
#else
- #define PIN(x) (*(&x - 2)) /* address of input register of port x */
+# define PIN(x) (*(&x - 2)) /* address of input register of port x */
#endif
-
#if LCD_IO_MODE
-#define lcd_e_delay() _delay_us(LCD_DELAY_ENABLE_PULSE)
-#define lcd_e_high() LCD_E_PORT |= _BV(LCD_E_PIN);
-#define lcd_e_low() LCD_E_PORT &= ~_BV(LCD_E_PIN);
-#define lcd_e_toggle() toggle_e()
-#define lcd_rw_high() LCD_RW_PORT |= _BV(LCD_RW_PIN)
-#define lcd_rw_low() LCD_RW_PORT &= ~_BV(LCD_RW_PIN)
-#define lcd_rs_high() LCD_RS_PORT |= _BV(LCD_RS_PIN)
-#define lcd_rs_low() LCD_RS_PORT &= ~_BV(LCD_RS_PIN)
+# define lcd_e_delay() _delay_us(LCD_DELAY_ENABLE_PULSE)
+# define lcd_e_high() LCD_E_PORT |= _BV(LCD_E_PIN);
+# define lcd_e_low() LCD_E_PORT &= ~_BV(LCD_E_PIN);
+# define lcd_e_toggle() toggle_e()
+# define lcd_rw_high() LCD_RW_PORT |= _BV(LCD_RW_PIN)
+# define lcd_rw_low() LCD_RW_PORT &= ~_BV(LCD_RW_PIN)
+# define lcd_rs_high() LCD_RS_PORT |= _BV(LCD_RS_PIN)
+# define lcd_rs_low() LCD_RS_PORT &= ~_BV(LCD_RS_PIN)
#endif
#if LCD_IO_MODE
-#if LCD_LINES==1
-#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE
+# if LCD_LINES == 1
+# define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE
+# else
+# define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES
+# endif
#else
-#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES
-#endif
-#else
-#if LCD_LINES==1
-#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_1LINE
-#else
-#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_2LINES
-#endif
+# if LCD_LINES == 1
+# define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_1LINE
+# else
+# define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_2LINES
+# endif
#endif
#if LCD_CONTROLLER_KS0073
-#if LCD_LINES==4
+# if LCD_LINES == 4
-#define KS0073_EXTENDED_FUNCTION_REGISTER_ON 0x2C /* |0|010|1100 4-bit mode, extension-bit RE = 1 */
-#define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x28 /* |0|010|1000 4-bit mode, extension-bit RE = 0 */
-#define KS0073_4LINES_MODE 0x09 /* |0|000|1001 4 lines mode */
+# define KS0073_EXTENDED_FUNCTION_REGISTER_ON 0x2C /* |0|010|1100 4-bit mode, extension-bit RE = 1 */
+# define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x28 /* |0|010|1000 4-bit mode, extension-bit RE = 0 */
+# define KS0073_4LINES_MODE 0x09 /* |0|000|1001 4 lines mode */
-#endif
+# endif
#endif
-/*
-** function prototypes
+/*
+** function prototypes
*/
#if LCD_IO_MODE
static void toggle_e(void);
@@ -87,93 +86,83 @@ static void toggle_e(void);
** local functions
*/
-
-/*************************************************************************
+/*************************************************************************
delay for a minimum of <us> microseconds
the number of loops is calculated at compile-time from MCU clock frequency
*************************************************************************/
-#define delay(us) _delay_us(us)
-
+#define delay(us) _delay_us(us)
#if LCD_IO_MODE
/* toggle Enable Pin to initiate write */
-static void toggle_e(void)
-{
+static void toggle_e(void) {
lcd_e_high();
lcd_e_delay();
lcd_e_low();
}
#endif
-
/*************************************************************************
Low-level function to write byte to LCD controller
Input: data byte to write to LCD
- rs 1: write data
+ rs 1: write data
0: write instruction
Returns: none
*************************************************************************/
#if LCD_IO_MODE
-static void lcd_write(uint8_t data,uint8_t rs)
-{
- unsigned char dataBits ;
-
+static void lcd_write(uint8_t data, uint8_t rs) {
+ unsigned char dataBits;
- if (rs) { /* write data (RS=1, RW=0) */
- lcd_rs_high();
- } else { /* write instruction (RS=0, RW=0) */
- lcd_rs_low();
+ if (rs) { /* write data (RS=1, RW=0) */
+ lcd_rs_high();
+ } else { /* write instruction (RS=0, RW=0) */
+ lcd_rs_low();
}
- lcd_rw_low(); /* RW=0 write mode */
+ lcd_rw_low(); /* RW=0 write mode */
- 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) )
- {
+ 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)) {
/* configure data pins as output */
DDR(LCD_DATA0_PORT) |= 0x0F;
/* output high nibble first */
- dataBits = LCD_DATA0_PORT & 0xF0;
- LCD_DATA0_PORT = dataBits |((data>>4)&0x0F);
+ dataBits = LCD_DATA0_PORT & 0xF0;
+ LCD_DATA0_PORT = dataBits | ((data >> 4) & 0x0F);
lcd_e_toggle();
/* output low nibble */
- LCD_DATA0_PORT = dataBits | (data&0x0F);
+ LCD_DATA0_PORT = dataBits | (data & 0x0F);
lcd_e_toggle();
/* all data pins high (inactive) */
LCD_DATA0_PORT = dataBits | 0x0F;
- }
- else
- {
+ } else {
/* configure data pins as output */
DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
-
+
/* output high nibble first */
LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
- if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
- if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
- if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
- if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
+ if (data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
+ if (data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
+ if (data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
+ if (data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
lcd_e_toggle();
-
+
/* output low nibble */
LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
- if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
- if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
- if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
- if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
- lcd_e_toggle();
-
+ if (data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
+ if (data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
+ if (data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
+ if (data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
+ lcd_e_toggle();
+
/* all data pins high (inactive) */
LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
@@ -182,85 +171,81 @@ static void lcd_write(uint8_t data,uint8_t rs)
}
}
#else
-#define lcd_write(d,rs) if (rs) *(volatile uint8_t*)(LCD_IO_DATA) = d; else *(volatile uint8_t*)(LCD_IO_FUNCTION) = d;
+# define lcd_write(d, rs) \
+ if (rs) \
+ *(volatile uint8_t *)(LCD_IO_DATA) = d; \
+ else \
+ *(volatile uint8_t *)(LCD_IO_FUNCTION) = d;
/* rs==0 -> write instruction to LCD_IO_FUNCTION */
/* rs==1 -> write data to LCD_IO_DATA */
#endif
-
/*************************************************************************
Low-level function to read byte from LCD controller
-Input: rs 1: read data
+Input: rs 1: read data
0: read busy flag / address counter
Returns: byte read from LCD controller
*************************************************************************/
#if LCD_IO_MODE
-static uint8_t lcd_read(uint8_t rs)
-{
+static uint8_t lcd_read(uint8_t rs) {
uint8_t data;
-
-
+
if (rs)
- lcd_rs_high(); /* RS=1: read data */
+ lcd_rs_high(); /* RS=1: read data */
else
- lcd_rs_low(); /* RS=0: read busy flag */
- lcd_rw_high(); /* RW=1 read mode */
-
- 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) )
- {
- DDR(LCD_DATA0_PORT) &= 0xF0; /* configure data pins as input */
-
+ lcd_rs_low(); /* RS=0: read busy flag */
+ lcd_rw_high(); /* RW=1 read mode */
+
+ 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)) {
+ DDR(LCD_DATA0_PORT) &= 0xF0; /* configure data pins as input */
+
lcd_e_high();
- lcd_e_delay();
- data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */
+ lcd_e_delay();
+ data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */
lcd_e_low();
-
- lcd_e_delay(); /* Enable 500ns low */
-
+
+ lcd_e_delay(); /* Enable 500ns low */
+
lcd_e_high();
lcd_e_delay();
- data |= PIN(LCD_DATA0_PORT)&0x0F; /* read low nibble */
+ data |= PIN(LCD_DATA0_PORT) & 0x0F; /* read low nibble */
lcd_e_low();
- }
- else
- {
+ } else {
/* configure data pins as input */
DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN);
DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN);
DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN);
DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN);
-
+
/* read high nibble first */
lcd_e_high();
- lcd_e_delay();
+ lcd_e_delay();
data = 0;
- if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x10;
- if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x20;
- if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x40;
- if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x80;
+ if (PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN)) data |= 0x10;
+ if (PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN)) data |= 0x20;
+ if (PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN)) data |= 0x40;
+ if (PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN)) data |= 0x80;
lcd_e_low();
- lcd_e_delay(); /* Enable 500ns low */
-
- /* read low nibble */
+ lcd_e_delay(); /* Enable 500ns low */
+
+ /* read low nibble */
lcd_e_high();
lcd_e_delay();
- if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x01;
- if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x02;
- if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x04;
- if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x08;
+ if (PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN)) data |= 0x01;
+ if (PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN)) data |= 0x02;
+ if (PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN)) data |= 0x04;
+ if (PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN)) data |= 0x08;
lcd_e_low();
}
return data;
}
#else
-#define lcd_read(rs) (rs) ? *(volatile uint8_t*)(LCD_IO_DATA+LCD_IO_READ) : *(volatile uint8_t*)(LCD_IO_FUNCTION+LCD_IO_READ)
+# define lcd_read(rs) (rs) ? *(volatile uint8_t *)(LCD_IO_DATA + LCD_IO_READ) : *(volatile uint8_t *)(LCD_IO_FUNCTION + LCD_IO_READ)
/* rs==0 -> read instruction from LCD_IO_FUNCTION */
/* rs==1 -> read data from LCD_IO_DATA */
#endif
-
/*************************************************************************
loops while lcd is busy, returns address counter
*************************************************************************/
@@ -268,65 +253,62 @@ static uint8_t lcd_waitbusy(void)
{
register uint8_t c;
-
+
/* wait until busy flag is cleared */
- while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}
-
+ while ((c = lcd_read(0)) & (1 << LCD_BUSY)) {
+ }
+
/* the address counter is updated 4us after the busy flag is cleared */
delay(LCD_DELAY_BUSY_FLAG);
/* now read the address counter */
return (lcd_read(0)); // return address counter
-
-}/* lcd_waitbusy */
+} /* lcd_waitbusy */
/*************************************************************************
-Move cursor to the start of next line or to the first line if the cursor
+Move cursor to the start of next line or to the first line if the cursor
is already on the last line.
*************************************************************************/
-static inline void lcd_newline(uint8_t pos)
-{
+static inline void lcd_newline(uint8_t pos) {
register uint8_t addressCounter;
-
-#if LCD_LINES==1
+#if LCD_LINES == 1
addressCounter = 0;
#endif
-#if LCD_LINES==2
- if ( pos < (LCD_START_LINE2) )
+#if LCD_LINES == 2
+ if (pos < (LCD_START_LINE2))
addressCounter = LCD_START_LINE2;
else
addressCounter = LCD_START_LINE1;
#endif
-#if LCD_LINES==4
-#if KS0073_4LINES_MODE
- if ( pos < LCD_START_LINE2 )
+#if LCD_LINES == 4
+# if KS0073_4LINES_MODE
+ if (pos < LCD_START_LINE2)
addressCounter = LCD_START_LINE2;
- else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3) )
+ else if ((pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3))
addressCounter = LCD_START_LINE3;
- else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4) )
+ else if ((pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4))
addressCounter = LCD_START_LINE4;
- else
+ else
addressCounter = LCD_START_LINE1;
-#else
- if ( pos < LCD_START_LINE3 )
+# else
+ if (pos < LCD_START_LINE3)
addressCounter = LCD_START_LINE2;
- else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) )
+ else if ((pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4))
addressCounter = LCD_START_LINE3;
- else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) )
+ else if ((pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2))
addressCounter = LCD_START_LINE4;
- else
+ else
addressCounter = LCD_START_LINE1;
+# endif
#endif
-#endif
- lcd_command((1<<LCD_DDRAM)+addressCounter);
-
-}/* lcd_newline */
+ lcd_command((1 << LCD_DDRAM) + addressCounter);
+} /* lcd_newline */
/*
-** PUBLIC FUNCTIONS
+** PUBLIC FUNCTIONS
*/
/*************************************************************************
@@ -334,132 +316,107 @@ Send LCD controller instruction command
Input: instruction to send to LCD controller, see HD44780 data sheet
Returns: none
*************************************************************************/
-void lcd_command(uint8_t cmd)
-{
+void lcd_command(uint8_t cmd) {
lcd_waitbusy();
- lcd_write(cmd,0);
+ lcd_write(cmd, 0);
}
-
/*************************************************************************
-Send data byte to LCD controller
+Send data byte to LCD controller
Input: data to send to LCD controller, see HD44780 data sheet
Returns: none
*************************************************************************/
-void lcd_data(uint8_t data)
-{
+void lcd_data(uint8_t data) {
lcd_waitbusy();
- lcd_write(data,1);
+ lcd_write(data, 1);
}
-
-
/*************************************************************************
Set cursor to specified position
Input: x horizontal position (0: left most position)
y vertical position (0: first line)
Returns: none
*************************************************************************/
-void lcd_gotoxy(uint8_t x, uint8_t y)
-{
-#if LCD_LINES==1
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
+void lcd_gotoxy(uint8_t x, uint8_t y) {
+#if LCD_LINES == 1
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
#endif
-#if LCD_LINES==2
- if ( y==0 )
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
+#if LCD_LINES == 2
+ if (y == 0)
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
else
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);
#endif
-#if LCD_LINES==4
- if ( y==0 )
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
- else if ( y==1)
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
- else if ( y==2)
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);
+#if LCD_LINES == 4
+ if (y == 0)
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
+ else if (y == 1)
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);
+ else if (y == 2)
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x);
else /* y==3 */
- lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x);
+ lcd_command((1 << LCD_DDRAM) + LCD_START_LINE4 + x);
#endif
-}/* lcd_gotoxy */
-
+} /* lcd_gotoxy */
/*************************************************************************
*************************************************************************/
-int lcd_getxy(void)
-{
- return lcd_waitbusy();
-}
-
+int lcd_getxy(void) { return lcd_waitbusy(); }
/*************************************************************************
Clear display and set cursor to home position
*************************************************************************/
-void lcd_clrscr(void)
-{
- lcd_command(1<<LCD_CLR);
-}
-
+void lcd_clrscr(void) { lcd_command(1 << LCD_CLR); }
/*************************************************************************
Set cursor to home position
*************************************************************************/
-void lcd_home(void)
-{
- lcd_command(1<<LCD_HOME);
-}
-
+void lcd_home(void) { lcd_command(1 << LCD_HOME); }
/*************************************************************************
-Display character at current cursor position
-Input: character to be displayed
+Display character at current cursor position
+Input: character to be displayed
Returns: none
*************************************************************************/
-void lcd_putc(char c)
-{
+void lcd_putc(char c) {
uint8_t pos;
-
- pos = lcd_waitbusy(); // read busy-flag and address counter
- if (c=='\n')
- {
+ pos = lcd_waitbusy(); // read busy-flag and address counter
+ if (c == '\n') {
lcd_newline(pos);
- }
- else
- {
-#if LCD_WRAP_LINES==1
-#if LCD_LINES==1
- if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
+ } else {
+#if LCD_WRAP_LINES == 1
+# if LCD_LINES == 1
+ if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
}
-#elif LCD_LINES==2
- if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);
- }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
+# elif LCD_LINES == 2
+ if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0);
+ } else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
}
-#elif LCD_LINES==4
- if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);
- }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0);
- }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0);
- }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) {
- lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
+# elif LCD_LINES == 4
+ if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0);
+ } else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE3, 0);
+ } else if (pos == LCD_START_LINE3 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE4, 0);
+ } else if (pos == LCD_START_LINE4 + LCD_DISP_LENGTH) {
+ lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
}
-#endif
+# endif
lcd_waitbusy();
#endif
lcd_write(c, 1);
}
-}/* lcd_putc */
-
+} /* lcd_putc */
/*************************************************************************
-Display string without auto linefeed
+Display string without auto linefeed
Input: string to be displayed
Returns: none
*************************************************************************/
@@ -468,16 +425,15 @@ void lcd_puts(const char *s)
{
register char c;
- while ( (c = *s++) ) {
+ while ((c = *s++)) {
lcd_putc(c);
}
-}/* lcd_puts */
-
+} /* lcd_puts */
/*************************************************************************
-Display string from program memory without auto linefeed
-Input: string from program memory be be displayed
+Display string from program memory without auto linefeed
+Input: string from program memory be be displayed
Returns: none
*************************************************************************/
void lcd_puts_p(const char *progmem_s)
@@ -485,108 +441,96 @@ void lcd_puts_p(const char *progmem_s)
{
register char c;
- while ( (c = pgm_read_byte(progmem_s++)) ) {
+ while ((c = pgm_read_byte(progmem_s++))) {
lcd_putc(c);
}
-}/* lcd_puts_p */
-
+} /* lcd_puts_p */
/*************************************************************************
-Initialize display and select type of cursor
+Initialize display and select type of cursor
Input: dispAttr LCD_DISP_OFF display off
LCD_DISP_ON display on, cursor off
LCD_DISP_ON_CURSOR display on, cursor on
LCD_DISP_CURSOR_BLINK display on, cursor on flashing
Returns: none
*************************************************************************/
-void lcd_init(uint8_t dispAttr)
-{
+void lcd_init(uint8_t dispAttr) {
#if LCD_IO_MODE
/*
* Initialize LCD to 4 bit I/O mode
*/
-
- 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 ) )
- {
+
+ 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)) {
/* configure all port bits as output (all LCD lines on same port) */
DDR(LCD_DATA0_PORT) |= 0x7F;
- }
- 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) )
- {
+ } 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)) {
/* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
DDR(LCD_DATA0_PORT) |= 0x0F;
- DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
- DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
- DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
- }
- else
- {
+ DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
+ DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
+ DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
+ } else {
/* configure all port bits as output (LCD data and control lines on different ports */
- DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
- DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
- DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
+ DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
+ DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
+ DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
}
- delay(LCD_DELAY_BOOTUP); /* wait 16ms or more after power-on */
-
+ delay(LCD_DELAY_BOOTUP); /* wait 16ms or more after power-on */
+
/* initial write to lcd is 8bit */
- LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4;
- LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4;
+ LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4;
+ LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4;
+ lcd_e_toggle();
+ delay(LCD_DELAY_INIT); /* delay, busy flag can't be checked here */
+
+ /* repeat last command */
lcd_e_toggle();
- delay(LCD_DELAY_INIT); /* delay, busy flag can't be checked here */
-
- /* repeat last command */
- lcd_e_toggle();
- delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */
-
+ delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */
+
/* repeat last command a third time */
- lcd_e_toggle();
- delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */
+ lcd_e_toggle();
+ delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */
/* now configure for 4bit mode */
- LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4
+ LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4
lcd_e_toggle();
- delay(LCD_DELAY_INIT_4BIT); /* some displays need this additional delay */
-
- /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */
+ delay(LCD_DELAY_INIT_4BIT); /* some displays need this additional delay */
+
+ /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */
#else
/*
* Initialize LCD to 8 bit memory mapped mode
*/
-
- /* enable external SRAM (memory mapped lcd) and one wait state */
+
+ /* enable external SRAM (memory mapped lcd) and one wait state */
MCUCR = _BV(SRE) | _BV(SRW);
/* reset LCD */
- delay(LCD_DELAY_BOOTUP); /* wait 16ms after power-on */
- lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
- delay(LCD_DELAY_INIT); /* wait 5ms */
- lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
- delay(LCD_DELAY_INIT_REP); /* wait 64us */
- lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
- delay(LCD_DELAY_INIT_REP); /* wait 64us */
+ delay(LCD_DELAY_BOOTUP); /* wait 16ms after power-on */
+ lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */
+ delay(LCD_DELAY_INIT); /* wait 5ms */
+ lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */
+ delay(LCD_DELAY_INIT_REP); /* wait 64us */
+ lcd_write(LCD_FUNCTION_8BIT_1LINE, 0); /* function set: 8bit interface */
+ delay(LCD_DELAY_INIT_REP); /* wait 64us */
#endif
#if KS0073_4LINES_MODE
/* Display with KS0073 controller requires special commands for enabling 4 line mode */
- lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
- lcd_command(KS0073_4LINES_MODE);
- lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
+ lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
+ lcd_command(KS0073_4LINES_MODE);
+ lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
#else
- lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */
+ lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */
#endif
- lcd_command(LCD_DISP_OFF); /* display off */
- lcd_clrscr(); /* display clear */
- lcd_command(LCD_MODE_DEFAULT); /* set entry mode */
- lcd_command(dispAttr); /* display/cursor control */
-
-}/* lcd_init */
+ lcd_command(LCD_DISP_OFF); /* display off */
+ lcd_clrscr(); /* display clear */
+ lcd_command(LCD_MODE_DEFAULT); /* set entry mode */
+ lcd_command(dispAttr); /* display/cursor control */
+} /* lcd_init */
diff --git a/drivers/avr/hd44780.h b/drivers/avr/hd44780.h
index 7421c8131f..e60817e989 100644
--- a/drivers/avr/hd44780.h
+++ b/drivers/avr/hd44780.h
@@ -6,7 +6,7 @@
License: GNU General Public License Version 3
File: $Id: lcd.h,v 1.14.2.4 2015/01/20 17:16:07 peter Exp $
Software: AVR-GCC 4.x
- Hardware: any AVR device, memory mapped mode only for AVR with
+ Hardware: any AVR device, memory mapped mode only for AVR with
memory mapped interface (AT90S8515/ATmega8515/ATmega128)
***************************************************************************/
@@ -15,333 +15,315 @@
Collection of libraries for AVR-GCC
@author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury
@copyright (C) 2015 Peter Fleury, GNU General Public License Version 3
-
+
@file
@defgroup pfleury_lcd LCD library <lcd.h>
@code #include <lcd.h> @endcode
-
+
@brief Basic routines for interfacing a HD44780U-based character LCD display
- LCD character displays can be found in many devices, like espresso machines, laser printers.
- The Hitachi HD44780 controller and its compatible controllers like Samsung KS0066U have become an industry standard for these types of displays.
-
+ LCD character displays can be found in many devices, like espresso machines, laser printers.
+ The Hitachi HD44780 controller and its compatible controllers like Samsung KS0066U have become an industry standard for these types of displays.
+
This library allows easy interfacing with a HD44780 compatible display and can be
- operated in memory mapped mode (LCD_IO_MODE defined as 0 in the include file lcd.h.) or in
+ operated in memory mapped mode (LCD_IO_MODE defined as 0 in the include file lcd.h.) or in
4-bit IO port mode (LCD_IO_MODE defined as 1). 8-bit IO port mode is not supported.
Memory mapped mode is compatible with old Kanda STK200 starter kit, but also supports
generation of R/W signal through A8 address line.
@see The chapter <a href=" http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html" target="_blank">Interfacing a HD44780 Based LCD to an AVR</a>
- on my home page, which shows example circuits how to connect an LCD to an AVR controller.
+ on my home page, which shows example circuits how to connect an LCD to an AVR controller.
@author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury
-
+
@version 2.0
-
+
@copyright (C) 2015 Peter Fleury, GNU General Public License Version 3
-
+
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 405
-#error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !"
+# error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !"
#endif
-
/**@{*/
/*
- * LCD and target specific definitions below can be defined in a separate include file with name lcd_definitions.h instead modifying this file
+ * LCD and target specific definitions below can be defined in a separate include file with name lcd_definitions.h instead modifying this file
* by adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile
* All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h
*/
#ifdef _LCD_DEFINITIONS_FILE
-#include "lcd_definitions.h"
+# include "lcd_definitions.h"
#endif
-
/**
* @name Definition for LCD controller type
* Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
*/
-#ifndef LCD_CONTROLLER_KS0073
-#define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */
+#ifndef LCD_CONTROLLER_KS0073
+# define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */
#endif
-/**
- * @name Definitions for Display Size
+/**
+ * @name Definitions for Display Size
* Change these definitions to adapt setting to your display
*
- * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
+ * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
* adding -D_LCD_DEFINITIONS_FILE to the CDEFS section in the Makefile.
* All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h
*
*/
#ifndef LCD_LINES
-#define LCD_LINES 2 /**< number of visible lines of the display */
+# define LCD_LINES 2 /**< number of visible lines of the display */
#endif
#ifndef LCD_DISP_LENGTH
-#define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */
+# define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */
#endif
#ifndef LCD_LINE_LENGTH
-#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
+# define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#endif
#ifndef LCD_START_LINE1
-#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
+# define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#endif
#ifndef LCD_START_LINE2
-#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
+# define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#endif
#ifndef LCD_START_LINE3
-#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
+# define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#endif
#ifndef LCD_START_LINE4
-#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
+# define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#endif
#ifndef LCD_WRAP_LINES
-#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */
+# define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */
#endif
-
/**
* @name Definitions for 4-bit IO mode
*
- * The four LCD data lines and the three control lines RS, RW, E can be on the
- * same port or on different ports.
+ * The four LCD data lines and the three control lines RS, RW, E can be on the
+ * same port or on different ports.
* Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
- * different ports.
+ * different ports.
*
* Normally the four data lines should be mapped to bit 0..3 on one port, but it
* is possible to connect these data lines in different order or even on different
* ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
*
- * Adjust these definitions to your target.\n
- * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
+ * Adjust these definitions to your target.\n
+ * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
* adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile.
* All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h
- *
+ *
*/
-#define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */
+#define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */
#if LCD_IO_MODE
-#ifndef LCD_PORT
-#define LCD_PORT PORTA /**< port for the LCD lines */
-#endif
-#ifndef LCD_DATA0_PORT
-#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
-#endif
-#ifndef LCD_DATA1_PORT
-#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
-#endif
-#ifndef LCD_DATA2_PORT
-#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
-#endif
-#ifndef LCD_DATA3_PORT
-#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
-#endif
-#ifndef LCD_DATA0_PIN
-#define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
-#endif
-#ifndef LCD_DATA1_PIN
-#define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */
-#endif
-#ifndef LCD_DATA2_PIN
-#define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */
-#endif
-#ifndef LCD_DATA3_PIN
-#define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */
-#endif
-#ifndef LCD_RS_PORT
-#define LCD_RS_PORT LCD_PORT /**< port for RS line */
-#endif
-#ifndef LCD_RS_PIN
-#define LCD_RS_PIN 3 /**< pin for RS line */
-#endif
-#ifndef LCD_RW_PORT
-#define LCD_RW_PORT LCD_PORT /**< port for RW line */
-#endif
-#ifndef LCD_RW_PIN
-#define LCD_RW_PIN 2 /**< pin for RW line */
-#endif
-#ifndef LCD_E_PORT
-#define LCD_E_PORT LCD_PORT /**< port for Enable line */
-#endif
-#ifndef LCD_E_PIN
-#define LCD_E_PIN 1 /**< pin for Enable line */
-#endif
-
-#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__)
+# ifndef LCD_PORT
+# define LCD_PORT PORTA /**< port for the LCD lines */
+# endif
+# ifndef LCD_DATA0_PORT
+# define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
+# endif
+# ifndef LCD_DATA1_PORT
+# define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
+# endif
+# ifndef LCD_DATA2_PORT
+# define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
+# endif
+# ifndef LCD_DATA3_PORT
+# define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
+# endif
+# ifndef LCD_DATA0_PIN
+# define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
+# endif
+# ifndef LCD_DATA1_PIN
+# define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */
+# endif
+# ifndef LCD_DATA2_PIN
+# define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */
+# endif
+# ifndef LCD_DATA3_PIN
+# define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */
+# endif
+# ifndef LCD_RS_PORT
+# define LCD_RS_PORT LCD_PORT /**< port for RS line */
+# endif
+# ifndef LCD_RS_PIN
+# define LCD_RS_PIN 3 /**< pin for RS line */
+# endif
+# ifndef LCD_RW_PORT
+# define LCD_RW_PORT LCD_PORT /**< port for RW line */
+# endif
+# ifndef LCD_RW_PIN
+# define LCD_RW_PIN 2 /**< pin for RW line */
+# endif
+# ifndef LCD_E_PORT
+# define LCD_E_PORT LCD_PORT /**< port for Enable line */
+# endif
+# ifndef LCD_E_PIN
+# define LCD_E_PIN 1 /**< pin for Enable line */
+# endif
+
+#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__)
/*
* memory mapped mode is only supported when the device has an external data memory interface
*/
-#define LCD_IO_DATA 0xC000 /* A15=E=1, A14=RS=1 */
-#define LCD_IO_FUNCTION 0x8000 /* A15=E=1, A14=RS=0 */
-#define LCD_IO_READ 0x0100 /* A8 =R/W=1 (R/W: 1=Read, 0=Write */
+# define LCD_IO_DATA 0xC000 /* A15=E=1, A14=RS=1 */
+# define LCD_IO_FUNCTION 0x8000 /* A15=E=1, A14=RS=0 */
+# define LCD_IO_READ 0x0100 /* A8 =R/W=1 (R/W: 1=Read, 0=Write */
#else
-#error "external data memory interface not available for this device, use 4-bit IO port mode"
+# error "external data memory interface not available for this device, use 4-bit IO port mode"
#endif
-
/**
* @name Definitions of delays
* Used to calculate delay timers.
* Adapt the F_CPU define in the Makefile to the clock frequency in Hz of your target
*
- * These delay times can be adjusted, if some displays require different delays.\n
- * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
+ * These delay times can be adjusted, if some displays require different delays.\n
+ * These definitions can be defined in a separate include file \b lcd_definitions.h instead modifying this file by
* adding \b -D_LCD_DEFINITIONS_FILE to the \b CDEFS section in the Makefile.
* All definitions added to the file lcd_definitions.h will override the default definitions from lcd.h
*/
#ifndef LCD_DELAY_BOOTUP
-#define LCD_DELAY_BOOTUP 16000 /**< delay in micro seconds after power-on */
+# define LCD_DELAY_BOOTUP 16000 /**< delay in micro seconds after power-on */
#endif
#ifndef LCD_DELAY_INIT
-#define LCD_DELAY_INIT 5000 /**< delay in micro seconds after initialization command sent */
+# define LCD_DELAY_INIT 5000 /**< delay in micro seconds after initialization command sent */
#endif
#ifndef LCD_DELAY_INIT_REP
-#define LCD_DELAY_INIT_REP 64 /**< delay in micro seconds after initialization command repeated */
+# define LCD_DELAY_INIT_REP 64 /**< delay in micro seconds after initialization command repeated */
#endif
#ifndef LCD_DELAY_INIT_4BIT
-#define LCD_DELAY_INIT_4BIT 64 /**< delay in micro seconds after setting 4-bit mode */
+# define LCD_DELAY_INIT_4BIT 64 /**< delay in micro seconds after setting 4-bit mode */
#endif
#ifndef LCD_DELAY_BUSY_FLAG
-#define LCD_DELAY_BUSY_FLAG 4 /**< time in micro seconds the address counter is updated after busy flag is cleared */
+# define LCD_DELAY_BUSY_FLAG 4 /**< time in micro seconds the address counter is updated after busy flag is cleared */
#endif
#ifndef LCD_DELAY_ENABLE_PULSE
-#define LCD_DELAY_ENABLE_PULSE 1 /**< enable signal pulse width in micro seconds */
+# define LCD_DELAY_ENABLE_PULSE 1 /**< enable signal pulse width in micro seconds */
#endif
-
/**
* @name Definitions for LCD command instructions
- * The constants define the various LCD controller instructions which can be passed to the
+ * The constants define the various LCD controller instructions which can be passed to the
* function lcd_command(), see HD44780 data sheet for a complete description.
*/
/* instruction register bit positions, see HD44780U data sheet */
-#define LCD_CLR 0 /* DB0: clear display */
-#define LCD_HOME 1 /* DB1: return to home position */
-#define LCD_ENTRY_MODE 2 /* DB2: set entry mode */
-#define LCD_ENTRY_INC 1 /* DB1: 1=increment, 0=decrement */
-#define LCD_ENTRY_SHIFT 0 /* DB2: 1=display shift on */
-#define LCD_ON 3 /* DB3: turn lcd/cursor on */
-#define LCD_ON_DISPLAY 2 /* DB2: turn display on */
-#define LCD_ON_CURSOR 1 /* DB1: turn cursor on */
-#define LCD_ON_BLINK 0 /* DB0: blinking cursor ? */
-#define LCD_MOVE 4 /* DB4: move cursor/display */
-#define LCD_MOVE_DISP 3 /* DB3: move display (0-> cursor) ? */
-#define LCD_MOVE_RIGHT 2 /* DB2: move right (0-> left) ? */
-#define LCD_FUNCTION 5 /* DB5: function set */
-#define LCD_FUNCTION_8BIT 4 /* DB4: set 8BIT mode (0->4BIT mode) */
-#define LCD_FUNCTION_2LINES 3 /* DB3: two lines (0->one line) */
-#define LCD_FUNCTION_10DOTS 2 /* DB2: 5x10 font (0->5x7 font) */
-#define LCD_CGRAM 6 /* DB6: set CG RAM address */
-#define LCD_DDRAM 7 /* DB7: set DD RAM address */
-#define LCD_BUSY 7 /* DB7: LCD is busy */
+#define LCD_CLR 0 /* DB0: clear display */
+#define LCD_HOME 1 /* DB1: return to home position */
+#define LCD_ENTRY_MODE 2 /* DB2: set entry mode */
+#define LCD_ENTRY_INC 1 /* DB1: 1=increment, 0=decrement */
+#define LCD_ENTRY_SHIFT 0 /* DB2: 1=display shift on */
+#define LCD_ON 3 /* DB3: turn lcd/cursor on */
+#define LCD_ON_DISPLAY 2 /* DB2: turn display on */
+#define LCD_ON_CURSOR 1 /* DB1: turn cursor on */
+#define LCD_ON_BLINK 0 /* DB0: blinking cursor ? */
+#define LCD_MOVE 4 /* DB4: move cursor/display */
+#define LCD_MOVE_DISP 3 /* DB3: move display (0-> cursor) ? */
+#define LCD_MOVE_RIGHT 2 /* DB2: move right (0-> left) ? */
+#define LCD_FUNCTION 5 /* DB5: function set */
+#define LCD_FUNCTION_8BIT 4 /* DB4: set 8BIT mode (0->4BIT mode) */
+#define LCD_FUNCTION_2LINES 3 /* DB3: two lines (0->one line) */
+#define LCD_FUNCTION_10DOTS 2 /* DB2: 5x10 font (0->5x7 font) */
+#define LCD_CGRAM 6 /* DB6: set CG RAM address */
+#define LCD_DDRAM 7 /* DB7: set DD RAM address */
+#define LCD_BUSY 7 /* DB7: LCD is busy */
/* set entry mode: display shift on/off, dec/inc cursor move direction */
-#define LCD_ENTRY_DEC 0x04 /* display shift off, dec cursor move dir */
-#define LCD_ENTRY_DEC_SHIFT 0x05 /* display shift on, dec cursor move dir */
-#define LCD_ENTRY_INC_ 0x06 /* display shift off, inc cursor move dir */
-#define LCD_ENTRY_INC_SHIFT 0x07 /* display shift on, inc cursor move dir */
+#define LCD_ENTRY_DEC 0x04 /* display shift off, dec cursor move dir */
+#define LCD_ENTRY_DEC_SHIFT 0x05 /* display shift on, dec cursor move dir */
+#define LCD_ENTRY_INC_ 0x06 /* display shift off, inc cursor move dir */
+#define LCD_ENTRY_INC_SHIFT 0x07 /* display shift on, inc cursor move dir */
/* display on/off, cursor on/off, blinking char at cursor position */
-#define LCD_DISP_OFF 0x08 /* display off */
-#define LCD_DISP_ON 0x0C /* display on, cursor off */
-#define LCD_DISP_ON_BLINK 0x0D /* display on, cursor off, blink char */
-#define LCD_DISP_ON_CURSOR 0x0E /* display on, cursor on */
-#define LCD_DISP_ON_CURSOR_BLINK 0x0F /* display on, cursor on, blink char */
+#define LCD_DISP_OFF 0x08 /* display off */
+#define LCD_DISP_ON 0x0C /* display on, cursor off */
+#define LCD_DISP_ON_BLINK 0x0D /* display on, cursor off, blink char */
+#define LCD_DISP_ON_CURSOR 0x0E /* display on, cursor on */
+#define LCD_DISP_ON_CURSOR_BLINK 0x0F /* display on, cursor on, blink char */
/* move cursor/shift display */
-#define LCD_MOVE_CURSOR_LEFT 0x10 /* move cursor left (decrement) */
-#define LCD_MOVE_CURSOR_RIGHT 0x14 /* move cursor right (increment) */
-#define LCD_MOVE_DISP_LEFT 0x18 /* shift display left */
-#define LCD_MOVE_DISP_RIGHT 0x1C /* shift display right */
+#define LCD_MOVE_CURSOR_LEFT 0x10 /* move cursor left (decrement) */
+#define LCD_MOVE_CURSOR_RIGHT 0x14 /* move cursor right (increment) */
+#define LCD_MOVE_DISP_LEFT 0x18 /* shift display left */
+#define LCD_MOVE_DISP_RIGHT 0x1C /* shift display right */
/* function set: set interface data length and number of display lines */
-#define LCD_FUNCTION_4BIT_1LINE 0x20 /* 4-bit interface, single line, 5x7 dots */
-#define LCD_FUNCTION_4BIT_2LINES 0x28 /* 4-bit interface, dual line, 5x7 dots */
-#define LCD_FUNCTION_8BIT_1LINE 0x30 /* 8-bit interface, single line, 5x7 dots */
-#define LCD_FUNCTION_8BIT_2LINES 0x38 /* 8-bit interface, dual line, 5x7 dots */
+#define LCD_FUNCTION_4BIT_1LINE 0x20 /* 4-bit interface, single line, 5x7 dots */
+#define LCD_FUNCTION_4BIT_2LINES 0x28 /* 4-bit interface, dual line, 5x7 dots */
+#define LCD_FUNCTION_8BIT_1LINE 0x30 /* 8-bit interface, single line, 5x7 dots */
+#define LCD_FUNCTION_8BIT_2LINES 0x38 /* 8-bit interface, dual line, 5x7 dots */
+#define LCD_MODE_DEFAULT ((1 << LCD_ENTRY_MODE) | (1 << LCD_ENTRY_INC))
-#define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )
-
-
-
-/**
+/**
* @name Functions
*/
-
/**
@brief Initialize display and select type of cursor
@param dispAttr \b LCD_DISP_OFF display off\n
\b LCD_DISP_ON display on, cursor off\n
\b LCD_DISP_ON_CURSOR display on, cursor on\n
- \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing
+ \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing
@return none
*/
extern void lcd_init(uint8_t dispAttr);
-
/**
@brief Clear display and set cursor to home position
@return none
*/
extern void lcd_clrscr(void);
-
/**
@brief Set cursor to home position
@return none
*/
extern void lcd_home(void);
-
/**
@brief Set cursor to specified position
-
+
@param x horizontal position\n (0: left most position)
@param y vertical position\n (0: first line)
@return none
*/
extern void lcd_gotoxy(uint8_t x, uint8_t y);
-
/**
@brief Display character at current cursor position
- @param c character to be displayed
+ @param c character to be displayed
@return none
*/
extern void lcd_putc(char c);
-
/**
@brief Display string without auto linefeed
- @param s string to be displayed
+ @param s string to be displayed
@return none
*/
extern void lcd_puts(const char *s);
-
/**
@brief Display string from program memory without auto linefeed
- @param progmem_s string from program memory be be displayed
+ @param progmem_s string from program memory be be displayed
@return none
@see lcd_puts_P
*/
extern void lcd_puts_p(const char *progmem_s);
-
/**
@brief Send LCD controller instruction command
@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);
*/
extern void lcd_command(uint8_t cmd);
-
/**
- @brief Send data byte to LCD controller
-
+ @brief Send data byte to LCD controller
+
Similar to lcd_putc(), but without interpreting LF
@param data byte to send to LCD controller, see HD44780 data sheet
@return none
*/
extern void lcd_data(uint8_t data);
-
/**
@brief macros for automatically storing string constant in program memory
*/
-#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))
+#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))
/**@}*/
-#endif //LCD_H
-
+#endif // LCD_H
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index a7364bae08..c084d5754f 100755..100644
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -1,3 +1,18 @@
+/* Copyright (C) 2019 Elia Ritterbusch
+ +
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
/* Library made by: g4lvanix
* Github repository: https://github.com/g4lvanix/I2C-master-lib
*/
@@ -10,200 +25,200 @@
#include "wait.h"
#ifndef F_SCL
-# define F_SCL 400000UL // SCL frequency
+# define F_SCL 400000UL // SCL frequency
#endif
-#define Prescaler 1
-#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16) / 2)
+
+#define TWBR_val (((F_CPU / F_SCL) - 16) / 2)
void i2c_init(void) {
- TWSR = 0; /* no prescaler */
- TWBR = (uint8_t)TWBR_val;
+ TWSR = 0; /* no prescaler */
+ TWBR = (uint8_t)TWBR_val;
- #ifdef __AVR_ATmega32A__
- // set pull-up resistors on I2C bus pins
- PORTC |= 0b11;
+#ifdef __AVR_ATmega32A__
+ // set pull-up resistors on I2C bus pins
+ PORTC |= 0b11;
- // enable TWI (two-wire interface)
- TWCR |= (1 << TWEN);
+ // enable TWI (two-wire interface)
+ TWCR |= (1 << TWEN);
- // enable TWI interrupt and slave address ACK
- TWCR |= (1 << TWIE);
- TWCR |= (1 << TWEA);
- #endif
+ // enable TWI interrupt and slave address ACK
+ TWCR |= (1 << TWIE);
+ TWCR |= (1 << TWEA);
+#endif
}
i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
- // reset TWI control register
- TWCR = 0;
- // transmit START condition
- TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
-
- uint16_t timeout_timer = timer_read();
- while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
- return I2C_STATUS_TIMEOUT;
- }
- }
-
- // check if the start condition was successfully transmitted
- if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) {
- return I2C_STATUS_ERROR;
- }
-
- // load slave address into data register
- TWDR = address;
- // start transmission of address
- TWCR = (1 << TWINT) | (1 << TWEN);
-
- timeout_timer = timer_read();
- while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
- return I2C_STATUS_TIMEOUT;
- }
- }
-
- // check if the device has acknowledged the READ / WRITE mode
- uint8_t twst = TW_STATUS & 0xF8;
- if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) {
- return I2C_STATUS_ERROR;
- }
-
- return I2C_STATUS_SUCCESS;
+ // reset TWI control register
+ TWCR = 0;
+ // transmit START condition
+ TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
+
+ uint16_t timeout_timer = timer_read();
+ while (!(TWCR & (1 << TWINT))) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ return I2C_STATUS_TIMEOUT;
+ }
+ }
+
+ // check if the start condition was successfully transmitted
+ if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) {
+ return I2C_STATUS_ERROR;
+ }
+
+ // load slave address into data register
+ TWDR = address;
+ // start transmission of address
+ TWCR = (1 << TWINT) | (1 << TWEN);
+
+ timeout_timer = timer_read();
+ while (!(TWCR & (1 << TWINT))) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ return I2C_STATUS_TIMEOUT;
+ }
+ }
+
+ // check if the device has acknowledged the READ / WRITE mode
+ uint8_t twst = TW_STATUS & 0xF8;
+ if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) {
+ return I2C_STATUS_ERROR;
+ }
+
+ return I2C_STATUS_SUCCESS;
}
i2c_status_t i2c_write(uint8_t data, uint16_t timeout) {
- // load data into data register
- TWDR = data;
- // start transmission of data
- TWCR = (1 << TWINT) | (1 << TWEN);
-
- uint16_t timeout_timer = timer_read();
- while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
- return I2C_STATUS_TIMEOUT;
+ // load data into data register
+ TWDR = data;
+ // start transmission of data
+ TWCR = (1 << TWINT) | (1 << TWEN);
+
+ uint16_t timeout_timer = timer_read();
+ while (!(TWCR & (1 << TWINT))) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ return I2C_STATUS_TIMEOUT;
+ }
}
- }
- if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) {
- return I2C_STATUS_ERROR;
- }
+ if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) {
+ return I2C_STATUS_ERROR;
+ }
- return I2C_STATUS_SUCCESS;
+ return I2C_STATUS_SUCCESS;
}
int16_t i2c_read_ack(uint16_t timeout) {
- // start TWI module and acknowledge data after reception
- TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
-
- uint16_t timeout_timer = timer_read();
- while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
- return I2C_STATUS_TIMEOUT;
+ // start TWI module and acknowledge data after reception
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
+
+ uint16_t timeout_timer = timer_read();
+ while (!(TWCR & (1 << TWINT))) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ return I2C_STATUS_TIMEOUT;
+ }
}
- }
- // return received data from TWDR
- return TWDR;
+ // return received data from TWDR
+ return TWDR;
}
int16_t i2c_read_nack(uint16_t timeout) {
- // start receiving without acknowledging reception
- TWCR = (1 << TWINT) | (1 << TWEN);
-
- uint16_t timeout_timer = timer_read();
- while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
- return I2C_STATUS_TIMEOUT;
+ // start receiving without acknowledging reception
+ TWCR = (1 << TWINT) | (1 << TWEN);
+
+ uint16_t timeout_timer = timer_read();
+ while (!(TWCR & (1 << TWINT))) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ return I2C_STATUS_TIMEOUT;
+ }
}
- }
- // return received data from TWDR
- return TWDR;
+ // return received data from TWDR
+ return TWDR;
}
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
+ i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
- for (uint16_t i = 0; i < length && status >= 0; i++) {
- status = i2c_write(data[i], timeout);
- }
+ for (uint16_t i = 0; i < length && status >= 0; i++) {
+ status = i2c_write(data[i], timeout);
+ }
- i2c_stop();
+ i2c_stop();
- return status;
+ return status;
}
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_status_t status = i2c_start(address | I2C_READ, timeout);
+ i2c_status_t status = i2c_start(address | I2C_READ, timeout);
- for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) {
- status = i2c_read_ack(timeout);
- if (status >= 0) {
- data[i] = status;
+ for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) {
+ status = i2c_read_ack(timeout);
+ if (status >= 0) {
+ data[i] = status;
+ }
}
- }
- if (status >= 0) {
- status = i2c_read_nack(timeout);
if (status >= 0) {
- data[(length - 1)] = status;
+ status = i2c_read_nack(timeout);
+ if (status >= 0) {
+ data[(length - 1)] = status;
+ }
}
- }
- i2c_stop();
+ i2c_stop();
- return (status < 0) ? status : I2C_STATUS_SUCCESS;
+ return (status < 0) ? status : I2C_STATUS_SUCCESS;
}
i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_status_t status = i2c_start(devaddr | 0x00, timeout);
- if (status >= 0) {
- status = i2c_write(regaddr, timeout);
+ i2c_status_t status = i2c_start(devaddr | 0x00, timeout);
+ if (status >= 0) {
+ status = i2c_write(regaddr, timeout);
- for (uint16_t i = 0; i < length && status >= 0; i++) {
- status = i2c_write(data[i], timeout);
+ for (uint16_t i = 0; i < length && status >= 0; i++) {
+ status = i2c_write(data[i], timeout);
+ }
}
- }
- i2c_stop();
+ i2c_stop();
- return status;
+ return status;
}
i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_status_t status = i2c_start(devaddr, timeout);
- if (status < 0) {
- goto error;
- }
+ i2c_status_t status = i2c_start(devaddr, timeout);
+ if (status < 0) {
+ goto error;
+ }
- status = i2c_write(regaddr, timeout);
- if (status < 0) {
- goto error;
- }
+ status = i2c_write(regaddr, timeout);
+ if (status < 0) {
+ goto error;
+ }
- status = i2c_start(devaddr | 0x01, timeout);
+ status = i2c_start(devaddr | 0x01, timeout);
- for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) {
- status = i2c_read_ack(timeout);
- if (status >= 0) {
- data[i] = status;
+ for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) {
+ status = i2c_read_ack(timeout);
+ if (status >= 0) {
+ data[i] = status;
+ }
}
- }
- if (status >= 0) {
- status = i2c_read_nack(timeout);
if (status >= 0) {
- data[(length - 1)] = status;
+ status = i2c_read_nack(timeout);
+ if (status >= 0) {
+ data[(length - 1)] = status;
+ }
}
- }
error:
- i2c_stop();
+ i2c_stop();
- return (status < 0) ? status : I2C_STATUS_SUCCESS;
+ return (status < 0) ? status : I2C_STATUS_SUCCESS;
}
void i2c_stop(void) {
- // transmit STOP condition
- TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
+ // transmit STOP condition
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
}
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h
index b4613115d9..0a3b6c508c 100755..100644
--- a/drivers/avr/i2c_master.h
+++ b/drivers/avr/i2c_master.h
@@ -1,3 +1,18 @@
+/* Copyright (C) 2019 Elia Ritterbusch
+ +
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
/* Library made by: g4lvanix
* Github repository: https://github.com/g4lvanix/I2C-master-lib
*/
@@ -11,21 +26,21 @@
typedef int16_t i2c_status_t;
#define I2C_STATUS_SUCCESS (0)
-#define I2C_STATUS_ERROR (-1)
+#define I2C_STATUS_ERROR (-1)
#define I2C_STATUS_TIMEOUT (-2)
#define I2C_TIMEOUT_IMMEDIATE (0)
#define I2C_TIMEOUT_INFINITE (0xFFFF)
-void i2c_init(void);
+void i2c_init(void);
i2c_status_t i2c_start(uint8_t address, uint16_t timeout);
i2c_status_t i2c_write(uint8_t data, uint16_t timeout);
-int16_t i2c_read_ack(uint16_t timeout);
-int16_t i2c_read_nack(uint16_t timeout);
+int16_t i2c_read_ack(uint16_t timeout);
+int16_t i2c_read_nack(uint16_t timeout);
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
-void i2c_stop(void);
+void i2c_stop(void);
-#endif // I2C_MASTER_H
+#endif // I2C_MASTER_H
diff --git a/drivers/avr/i2c_slave.c b/drivers/avr/i2c_slave.c
index dbb9fb0df3..3fb684f70a 100755..100644
--- a/drivers/avr/i2c_slave.c
+++ b/drivers/avr/i2c_slave.c
@@ -1,3 +1,18 @@
+/* Copyright (C) 2019 Elia Ritterbusch
+ +
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
/* Library made by: g4lvanix
* Github repository: https://github.com/g4lvanix/I2C-slave-lib
*/
@@ -12,24 +27,24 @@
volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT];
static volatile uint8_t buffer_address;
-static volatile bool slave_has_register_set = false;
+static volatile bool slave_has_register_set = false;
-void i2c_slave_init(uint8_t address){
+void i2c_slave_init(uint8_t address) {
// load address into TWI address register
TWAR = address;
// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
}
-void i2c_slave_stop(void){
+void i2c_slave_stop(void) {
// clear acknowledge and enable bits
TWCR &= ~((1 << TWEA) | (1 << TWEN));
}
-ISR(TWI_vect){
+ISR(TWI_vect) {
uint8_t ack = 1;
- switch(TW_STATUS){
+ switch (TW_STATUS) {
case TW_SR_SLA_ACK:
// The device is now a slave receiver
slave_has_register_set = false;
@@ -38,14 +53,14 @@ ISR(TWI_vect){
case TW_SR_DATA_ACK:
// This device is a slave receiver and has received data
// First byte is the location then the bytes will be writen in buffer with auto-incriment
- if(!slave_has_register_set){
+ if (!slave_has_register_set) {
buffer_address = TWDR;
if (buffer_address >= I2C_SLAVE_REG_COUNT) { // address out of bounds dont ack
- ack = 0;
- buffer_address = 0;
+ ack = 0;
+ buffer_address = 0;
}
- slave_has_register_set = true; // address has been receaved now fill in buffer
+ slave_has_register_set = true; // address has been receaved now fill in buffer
} else {
i2c_slave_reg[buffer_address] = TWDR;
buffer_address++;
@@ -68,4 +83,4 @@ ISR(TWI_vect){
// Reset i2c state machine to be ready for next interrupt
TWCR |= (1 << TWIE) | (1 << TWINT) | (ack << TWEA) | (1 << TWEN);
-} \ No newline at end of file
+}
diff --git a/drivers/avr/i2c_slave.h b/drivers/avr/i2c_slave.h
index 7b5dcbdc3e..5ed0b11a8e 100755..100644
--- a/drivers/avr/i2c_slave.h
+++ b/drivers/avr/i2c_slave.h
@@ -1,3 +1,18 @@
+/* Copyright (C) 2019 Elia Ritterbusch
+ +
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
/* Library made by: g4lvanix
* Github repository: https://github.com/g4lvanix/I2C-slave-lib
@@ -15,4 +30,4 @@ extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT];
void i2c_slave_init(uint8_t address);
void i2c_slave_stop(void);
-#endif // I2C_SLAVE_H \ No newline at end of file
+#endif // I2C_SLAVE_H
diff --git a/drivers/avr/pro_micro.h b/drivers/avr/pro_micro.h
index f9e7ed75d9..762a99a058 100644
--- a/drivers/avr/pro_micro.h
+++ b/drivers/avr/pro_micro.h
@@ -90,14 +90,14 @@
#undef OCR2_6
#undef OCR2_7
-#define NUM_DIGITAL_PINS 30
+#define NUM_DIGITAL_PINS 30
#define NUM_ANALOG_INPUTS 12
-#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
-#define TXLED0 PORTD |= (1<<5)
-#define TXLED1 PORTD &= ~(1<<5)
-#define RXLED0 PORTB |= (1<<0)
-#define RXLED1 PORTB &= ~(1<<0)
+#define TX_RX_LED_INIT DDRD |= (1 << 5), DDRB |= (1 << 0)
+#define TXLED0 PORTD |= (1 << 5)
+#define TXLED1 PORTD &= ~(1 << 5)
+#define RXLED0 PORTB |= (1 << 0)
+#define RXLED1 PORTB &= ~(1 << 0)
static const uint8_t SDA = 2;
static const uint8_t SCL = 3;
@@ -111,27 +111,27 @@ static const uint8_t SCK = 15;
// Mapping of analog pins as digital I/O
// A6-A11 share with digital pins
-static const uint8_t ADC0 = 18;
-static const uint8_t ADC1 = 19;
-static const uint8_t ADC2 = 20;
-static const uint8_t ADC3 = 21;
-static const uint8_t ADC4 = 22;
-static const uint8_t ADC5 = 23;
-static const uint8_t ADC6 = 24; // D4
-static const uint8_t ADC7 = 25; // D6
-static const uint8_t ADC8 = 26; // D8
-static const uint8_t ADC9 = 27; // D9
+static const uint8_t ADC0 = 18;
+static const uint8_t ADC1 = 19;
+static const uint8_t ADC2 = 20;
+static const uint8_t ADC3 = 21;
+static const uint8_t ADC4 = 22;
+static const uint8_t ADC5 = 23;
+static const uint8_t ADC6 = 24; // D4
+static const uint8_t ADC7 = 25; // D6
+static const uint8_t ADC8 = 26; // D8
+static const uint8_t ADC9 = 27; // D9
static const uint8_t ADC10 = 28; // D10
static const uint8_t ADC11 = 29; // D12
-#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
+#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) 0
-#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
-#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
+#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
+#define digitalPinToPCMSKbit(p) (((p) >= 8 && (p) <= 11) ? (p)-4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
-#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
+#define analogPinToChannel(P) (pgm_read_byte(analog_pin_to_channel_PGM + (P)))
#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
@@ -182,159 +182,121 @@ extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] = {
- NOT_A_PORT,
- NOT_A_PORT,
- (uint16_t) &DDRB,
- (uint16_t) &DDRC,
- (uint16_t) &DDRD,
- (uint16_t) &DDRE,
- (uint16_t) &DDRF,
+ NOT_A_PORT, NOT_A_PORT, (uint16_t)&DDRB, (uint16_t)&DDRC, (uint16_t)&DDRD, (uint16_t)&DDRE, (uint16_t)&DDRF,
};
const uint16_t PROGMEM port_to_output_PGM[] = {
- NOT_A_PORT,
- NOT_A_PORT,
- (uint16_t) &PORTB,
- (uint16_t) &PORTC,
- (uint16_t) &PORTD,
- (uint16_t) &PORTE,
- (uint16_t) &PORTF,
+ NOT_A_PORT, NOT_A_PORT, (uint16_t)&PORTB, (uint16_t)&PORTC, (uint16_t)&PORTD, (uint16_t)&PORTE, (uint16_t)&PORTF,
};
const uint16_t PROGMEM port_to_input_PGM[] = {
- NOT_A_PORT,
- NOT_A_PORT,
- (uint16_t) &PINB,
- (uint16_t) &PINC,
- (uint16_t) &PIND,
- (uint16_t) &PINE,
- (uint16_t) &PINF,
+ NOT_A_PORT, NOT_A_PORT, (uint16_t)&PINB, (uint16_t)&PINC, (uint16_t)&PIND, (uint16_t)&PINE, (uint16_t)&PINF,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
- PD, // D0 - PD2
- PD, // D1 - PD3
- PD, // D2 - PD1
- PD, // D3 - PD0
- PD, // D4 - PD4
- PC, // D5 - PC6
- PD, // D6 - PD7
- PE, // D7 - PE6
-
- PB, // D8 - PB4
- PB, // D9 - PB5
- PB, // D10 - PB6
- PB, // D11 - PB7
- PD, // D12 - PD6
- PC, // D13 - PC7
-
- PB, // D14 - MISO - PB3
- PB, // D15 - SCK - PB1
- PB, // D16 - MOSI - PB2
- PB, // D17 - SS - PB0
-
- PF, // D18 - A0 - PF7
- PF, // D19 - A1 - PF6
- PF, // D20 - A2 - PF5
- PF, // D21 - A3 - PF4
- PF, // D22 - A4 - PF1
- PF, // D23 - A5 - PF0
-
- PD, // D24 - PD5
- PD, // D25 / D6 - A7 - PD7
- PB, // D26 / D8 - A8 - PB4
- PB, // D27 / D9 - A9 - PB5
- PB, // D28 / D10 - A10 - PB6
- PD, // D29 / D12 - A11 - PD6
+ PD, // D0 - PD2
+ PD, // D1 - PD3
+ PD, // D2 - PD1
+ PD, // D3 - PD0
+ PD, // D4 - PD4
+ PC, // D5 - PC6
+ PD, // D6 - PD7
+ PE, // D7 - PE6
+
+ PB, // D8 - PB4
+ PB, // D9 - PB5
+ PB, // D10 - PB6
+ PB, // D11 - PB7
+ PD, // D12 - PD6
+ PC, // D13 - PC7
+
+ PB, // D14 - MISO - PB3
+ PB, // D15 - SCK - PB1
+ PB, // D16 - MOSI - PB2
+ PB, // D17 - SS - PB0
+
+ PF, // D18 - A0 - PF7
+ PF, // D19 - A1 - PF6
+ PF, // D20 - A2 - PF5
+ PF, // D21 - A3 - PF4
+ PF, // D22 - A4 - PF1
+ PF, // D23 - A5 - PF0
+
+ PD, // D24 - PD5
+ PD, // D25 / D6 - A7 - PD7
+ PB, // D26 / D8 - A8 - PB4
+ PB, // D27 / D9 - A9 - PB5
+ PB, // D28 / D10 - A10 - PB6
+ PD, // D29 / D12 - A11 - PD6
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
- _BV(2), // D0 - PD2
- _BV(3), // D1 - PD3
- _BV(1), // D2 - PD1
- _BV(0), // D3 - PD0
- _BV(4), // D4 - PD4
- _BV(6), // D5 - PC6
- _BV(7), // D6 - PD7
- _BV(6), // D7 - PE6
-
- _BV(4), // D8 - PB4
- _BV(5), // D9 - PB5
- _BV(6), // D10 - PB6
- _BV(7), // D11 - PB7
- _BV(6), // D12 - PD6
- _BV(7), // D13 - PC7
-
- _BV(3), // D14 - MISO - PB3
- _BV(1), // D15 - SCK - PB1
- _BV(2), // D16 - MOSI - PB2
- _BV(0), // D17 - SS - PB0
-
- _BV(7), // D18 - A0 - PF7
- _BV(6), // D19 - A1 - PF6
- _BV(5), // D20 - A2 - PF5
- _BV(4), // D21 - A3 - PF4
- _BV(1), // D22 - A4 - PF1
- _BV(0), // D23 - A5 - PF0
-
- _BV(5), // D24 - PD5
- _BV(7), // D25 / D6 - A7 - PD7
- _BV(4), // D26 / D8 - A8 - PB4
- _BV(5), // D27 / D9 - A9 - PB5
- _BV(6), // D28 / D10 - A10 - PB6
- _BV(6), // D29 / D12 - A11 - PD6
+ _BV(2), // D0 - PD2
+ _BV(3), // D1 - PD3
+ _BV(1), // D2 - PD1
+ _BV(0), // D3 - PD0
+ _BV(4), // D4 - PD4
+ _BV(6), // D5 - PC6
+ _BV(7), // D6 - PD7
+ _BV(6), // D7 - PE6
+
+ _BV(4), // D8 - PB4
+ _BV(5), // D9 - PB5
+ _BV(6), // D10 - PB6
+ _BV(7), // D11 - PB7
+ _BV(6), // D12 - PD6
+ _BV(7), // D13 - PC7
+
+ _BV(3), // D14 - MISO - PB3
+ _BV(1), // D15 - SCK - PB1
+ _BV(2), // D16 - MOSI - PB2
+ _BV(0), // D17 - SS - PB0
+
+ _BV(7), // D18 - A0 - PF7
+ _BV(6), // D19 - A1 - PF6
+ _BV(5), // D20 - A2 - PF5
+ _BV(4), // D21 - A3 - PF4
+ _BV(1), // D22 - A4 - PF1
+ _BV(0), // D23 - A5 - PF0
+
+ _BV(5), // D24 - PD5
+ _BV(7), // D25 / D6 - A7 - PD7
+ _BV(4), // D26 / D8 - A8 - PB4
+ _BV(5), // D27 / D9 - A9 - PB5
+ _BV(6), // D28 / D10 - A10 - PB6
+ _BV(6), // D29 / D12 - A11 - PD6
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
- NOT_ON_TIMER,
- NOT_ON_TIMER,
- NOT_ON_TIMER,
- TIMER0B, /* 3 */
- NOT_ON_TIMER,
- TIMER3A, /* 5 */
- TIMER4D, /* 6 */
+ NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, TIMER0B, /* 3 */
+ NOT_ON_TIMER, TIMER3A, /* 5 */
+ TIMER4D, /* 6 */
NOT_ON_TIMER,
- NOT_ON_TIMER,
- TIMER1A, /* 9 */
- TIMER1B, /* 10 */
- TIMER0A, /* 11 */
+ NOT_ON_TIMER, TIMER1A, /* 9 */
+ TIMER1B, /* 10 */
+ TIMER0A, /* 11 */
- NOT_ON_TIMER,
- TIMER4A, /* 13 */
+ NOT_ON_TIMER, TIMER4A, /* 13 */
- 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, 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,
- 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, NOT_ON_TIMER, NOT_ON_TIMER,
};
const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
- 7, // A0 PF7 ADC7
- 6, // A1 PF6 ADC6
- 5, // A2 PF5 ADC5
- 4, // A3 PF4 ADC4
- 1, // A4 PF1 ADC1
- 0, // A5 PF0 ADC0
- 8, // A6 D4 PD4 ADC8
- 10, // A7 D6 PD7 ADC10
- 11, // A8 D8 PB4 ADC11
- 12, // A9 D9 PB5 ADC12
- 13, // A10 D10 PB6 ADC13
- 9 // A11 D12 PD6 ADC9
+ 7, // A0 PF7 ADC7
+ 6, // A1 PF6 ADC6
+ 5, // A2 PF5 ADC5
+ 4, // A3 PF4 ADC4
+ 1, // A4 PF1 ADC1
+ 0, // A5 PF0 ADC0
+ 8, // A6 D4 PD4 ADC8
+ 10, // A7 D6 PD7 ADC10
+ 11, // A8 D8 PB4 ADC11
+ 12, // A9 D9 PB5 ADC12
+ 13, // A10 D10 PB6 ADC13
+ 9 // A11 D12 PD6 ADC9
};
#endif /* ARDUINO_MAIN */
@@ -354,9 +316,9 @@ const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
-#define SERIAL_PORT_MONITOR Serial
-#define SERIAL_PORT_USBVIRTUAL Serial
-#define SERIAL_PORT_HARDWARE Serial1
-#define SERIAL_PORT_HARDWARE_OPEN Serial1
+#define SERIAL_PORT_MONITOR Serial
+#define SERIAL_PORT_USBVIRTUAL Serial
+#define SERIAL_PORT_HARDWARE Serial1
+#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* Pins_Arduino_h */
diff --git a/drivers/avr/ssd1306.c b/drivers/avr/ssd1306.c
index bb8938bba3..61d7a99531 100644
--- a/drivers/avr/ssd1306.c
+++ b/drivers/avr/ssd1306.c
@@ -1,325 +1,320 @@
#ifdef SSD1306OLED
-#include "ssd1306.h"
-#include "i2c.h"
-#include <string.h>
-#include "print.h"
-#include "glcdfont.c"
-#ifdef ADAFRUIT_BLE_ENABLE
-#include "adafruit_ble.h"
-#endif
-#ifdef PROTOCOL_LUFA
-#include "lufa.h"
-#endif
-#include "sendchar.h"
-#include "timer.h"
+# include "ssd1306.h"
+# include "i2c.h"
+# include <string.h>
+# include "print.h"
+# include "glcdfont.c"
+# ifdef ADAFRUIT_BLE_ENABLE
+# include "adafruit_ble.h"
+# endif
+# ifdef PROTOCOL_LUFA
+# include "lufa.h"
+# endif
+# include "sendchar.h"
+# include "timer.h"
// Set this to 1 to help diagnose early startup problems
// when testing power-on with ble. Turn it off otherwise,
// as the latency of printing most of the debug info messes
// with the matrix scan, causing keys to drop.
-#define DEBUG_TO_SCREEN 0
+# define DEBUG_TO_SCREEN 0
-//static uint16_t last_battery_update;
-//static uint32_t vbat;
+// static uint16_t last_battery_update;
+// static uint32_t vbat;
//#define BatteryUpdateInterval 10000 /* milliseconds */
-#define ScreenOffInterval 300000 /* milliseconds */
-#if DEBUG_TO_SCREEN
+# define ScreenOffInterval 300000 /* milliseconds */
+# if DEBUG_TO_SCREEN
static uint8_t displaying;
-#endif
+# endif
static uint16_t last_flush;
// Write command sequence.
// Returns true on success.
static inline bool _send_cmd1(uint8_t cmd) {
- bool res = false;
+ bool res = false;
- if (i2c_start_write(SSD1306_ADDRESS)) {
- xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
- goto done;
- }
+ if (i2c_start_write(SSD1306_ADDRESS)) {
+ xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
+ goto done;
+ }
- if (i2c_master_write(0x0 /* command byte follows */)) {
- print("failed to write control byte\n");
+ if (i2c_master_write(0x0 /* command byte follows */)) {
+ print("failed to write control byte\n");
- goto done;
- }
+ goto done;
+ }
- if (i2c_master_write(cmd)) {
- xprintf("failed to write command %d\n", cmd);
- goto done;
- }
- res = true;
+ if (i2c_master_write(cmd)) {
+ xprintf("failed to write command %d\n", cmd);
+ goto done;
+ }
+ res = true;
done:
- i2c_master_stop();
- return res;
+ i2c_master_stop();
+ return res;
}
// Write 2-byte command sequence.
// Returns true on success
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
- if (!_send_cmd1(cmd)) {
- return false;
- }
- return _send_cmd1(opr);
+ if (!_send_cmd1(cmd)) {
+ return false;
+ }
+ return _send_cmd1(opr);
}
// Write 3-byte command sequence.
// Returns true on success
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
- if (!_send_cmd1(cmd)) {
- return false;
- }
- if (!_send_cmd1(opr1)) {
- return false;
- }
- return _send_cmd1(opr2);
+ if (!_send_cmd1(cmd)) {
+ return false;
+ }
+ if (!_send_cmd1(opr1)) {
+ return false;
+ }
+ return _send_cmd1(opr2);
}
-#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
-#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
-#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
+# define send_cmd1(c) \
+ if (!_send_cmd1(c)) { \
+ goto done; \
+ }
+# define send_cmd2(c, o) \
+ if (!_send_cmd2(c, o)) { \
+ goto done; \
+ }
+# define send_cmd3(c, o1, o2) \
+ if (!_send_cmd3(c, o1, o2)) { \
+ goto done; \
+ }
static void clear_display(void) {
- matrix_clear(&display);
-
- // Clear all of the display bits (there can be random noise
- // in the RAM on startup)
- send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
- send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
-
- if (i2c_start_write(SSD1306_ADDRESS)) {
- goto done;
- }
- if (i2c_master_write(0x40)) {
- // Data mode
- goto done;
- }
- for (uint8_t row = 0; row < MatrixRows; ++row) {
- for (uint8_t col = 0; col < DisplayWidth; ++col) {
- i2c_master_write(0);
+ matrix_clear(&display);
+
+ // Clear all of the display bits (there can be random noise
+ // in the RAM on startup)
+ send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
+ send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
+
+ if (i2c_start_write(SSD1306_ADDRESS)) {
+ goto done;
+ }
+ if (i2c_master_write(0x40)) {
+ // Data mode
+ goto done;
+ }
+ for (uint8_t row = 0; row < MatrixRows; ++row) {
+ for (uint8_t col = 0; col < DisplayWidth; ++col) {
+ i2c_master_write(0);
+ }
}
- }
- display.dirty = false;
+ display.dirty = false;
done:
- i2c_master_stop();
+ i2c_master_stop();
}
-#if DEBUG_TO_SCREEN
-#undef sendchar
+# if DEBUG_TO_SCREEN
+# undef sendchar
static int8_t capture_sendchar(uint8_t c) {
- sendchar(c);
- iota_gfx_write_char(c);
+ sendchar(c);
+ iota_gfx_write_char(c);
- if (!displaying) {
- iota_gfx_flush();
- }
- return 0;
+ if (!displaying) {
+ iota_gfx_flush();
+ }
+ return 0;
}
-#endif
+# endif
bool iota_gfx_init(void) {
- bool success = false;
+ bool success = false;
- send_cmd1(DisplayOff);
- send_cmd2(SetDisplayClockDiv, 0x80);
- send_cmd2(SetMultiPlex, DisplayHeight - 1);
+ send_cmd1(DisplayOff);
+ send_cmd2(SetDisplayClockDiv, 0x80);
+ send_cmd2(SetMultiPlex, DisplayHeight - 1);
- send_cmd2(SetDisplayOffset, 0);
+ send_cmd2(SetDisplayOffset, 0);
+ send_cmd1(SetStartLine | 0x0);
+ send_cmd2(SetChargePump, 0x14 /* Enable */);
+ send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
- send_cmd1(SetStartLine | 0x0);
- send_cmd2(SetChargePump, 0x14 /* Enable */);
- send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
+# ifdef OLED_ROTATE180
+ // the following Flip the display orientation 180 degrees
+ send_cmd1(SegRemap);
+ send_cmd1(ComScanInc);
+# endif
+# ifndef OLED_ROTATE180
+ // Flips the display orientation 0 degrees
+ send_cmd1(SegRemap | 0x1);
+ send_cmd1(ComScanDec);
+# endif
-#ifdef OLED_ROTATE180
-// the following Flip the display orientation 180 degrees
- send_cmd1(SegRemap);
- send_cmd1(ComScanInc);
-#endif
-#ifndef OLED_ROTATE180
-// Flips the display orientation 0 degrees
- send_cmd1(SegRemap | 0x1);
- send_cmd1(ComScanDec);
-#endif
-
- send_cmd2(SetComPins, 0x2);
- send_cmd2(SetContrast, 0x8f);
- send_cmd2(SetPreCharge, 0xf1);
- send_cmd2(SetVComDetect, 0x40);
- send_cmd1(DisplayAllOnResume);
- send_cmd1(NormalDisplay);
- send_cmd1(DeActivateScroll);
- send_cmd1(DisplayOn);
+ send_cmd2(SetComPins, 0x2);
+ send_cmd2(SetContrast, 0x8f);
+ send_cmd2(SetPreCharge, 0xf1);
+ send_cmd2(SetVComDetect, 0x40);
+ send_cmd1(DisplayAllOnResume);
+ send_cmd1(NormalDisplay);
+ send_cmd1(DeActivateScroll);
+ send_cmd1(DisplayOn);
- send_cmd2(SetContrast, 0); // Dim
+ send_cmd2(SetContrast, 0); // Dim
- clear_display();
+ clear_display();
- success = true;
+ success = true;
- iota_gfx_flush();
+ iota_gfx_flush();
-#if DEBUG_TO_SCREEN
- print_set_sendchar(capture_sendchar);
-#endif
+# if DEBUG_TO_SCREEN
+ print_set_sendchar(capture_sendchar);
+# endif
done:
- return success;
+ return success;
}
bool iota_gfx_off(void) {
- bool success = false;
+ bool success = false;
- send_cmd1(DisplayOff);
- success = true;
+ send_cmd1(DisplayOff);
+ success = true;
done:
- return success;
-}
+ return success;
+}
bool iota_gfx_on(void) {
- bool success = false;
+ bool success = false;
- send_cmd1(DisplayOn);
- success = true;
+ send_cmd1(DisplayOn);
+ success = true;
done:
- return success;
+ return success;
}
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
- *matrix->cursor = c;
- ++matrix->cursor;
-
- if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
- // We went off the end; scroll the display upwards by one line
- memmove(&matrix->display[0], &matrix->display[1],
- MatrixCols * (MatrixRows - 1));
- matrix->cursor = &matrix->display[MatrixRows - 1][0];
- memset(matrix->cursor, ' ', MatrixCols);
- }
+ *matrix->cursor = c;
+ ++matrix->cursor;
+
+ if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
+ // We went off the end; scroll the display upwards by one line
+ memmove(&matrix->display[0], &matrix->display[1], MatrixCols * (MatrixRows - 1));
+ matrix->cursor = &matrix->display[MatrixRows - 1][0];
+ memset(matrix->cursor, ' ', MatrixCols);
+ }
}
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
- matrix->dirty = true;
+ matrix->dirty = true;
- if (c == '\n') {
- // Clear to end of line from the cursor and then move to the
- // start of the next line
- uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
+ if (c == '\n') {
+ // Clear to end of line from the cursor and then move to the
+ // start of the next line
+ uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
- while (cursor_col++ < MatrixCols) {
- matrix_write_char_inner(matrix, ' ');
+ while (cursor_col++ < MatrixCols) {
+ matrix_write_char_inner(matrix, ' ');
+ }
+ return;
}
- return;
- }
- matrix_write_char_inner(matrix, c);
+ matrix_write_char_inner(matrix, c);
}
-void iota_gfx_write_char(uint8_t c) {
- matrix_write_char(&display, c);
-}
+void iota_gfx_write_char(uint8_t c) { matrix_write_char(&display, c); }
void matrix_write(struct CharacterMatrix *matrix, const char *data) {
- const char *end = data + strlen(data);
- while (data < end) {
- matrix_write_char(matrix, *data);
- ++data;
- }
+ const char *end = data + strlen(data);
+ while (data < end) {
+ matrix_write_char(matrix, *data);
+ ++data;
+ }
}
-void iota_gfx_write(const char *data) {
- matrix_write(&display, data);
-}
+void iota_gfx_write(const char *data) { matrix_write(&display, data); }
void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
- while (true) {
- uint8_t c = pgm_read_byte(data);
- if (c == 0) {
- return;
+ while (true) {
+ uint8_t c = pgm_read_byte(data);
+ if (c == 0) {
+ return;
+ }
+ matrix_write_char(matrix, c);
+ ++data;
}
- matrix_write_char(matrix, c);
- ++data;
- }
}
-void iota_gfx_write_P(const char *data) {
- matrix_write_P(&display, data);
-}
+void iota_gfx_write_P(const char *data) { matrix_write_P(&display, data); }
void matrix_clear(struct CharacterMatrix *matrix) {
- memset(matrix->display, ' ', sizeof(matrix->display));
- matrix->cursor = &matrix->display[0][0];
- matrix->dirty = true;
+ memset(matrix->display, ' ', sizeof(matrix->display));
+ matrix->cursor = &matrix->display[0][0];
+ matrix->dirty = true;
}
-void iota_gfx_clear_screen(void) {
- matrix_clear(&display);
-}
+void iota_gfx_clear_screen(void) { matrix_clear(&display); }
void matrix_render(struct CharacterMatrix *matrix) {
- last_flush = timer_read();
- iota_gfx_on();
-#if DEBUG_TO_SCREEN
- ++displaying;
-#endif
+ last_flush = timer_read();
+ iota_gfx_on();
+# if DEBUG_TO_SCREEN
+ ++displaying;
+# endif
+
+ // Move to the home position
+ send_cmd3(PageAddr, 0, MatrixRows - 1);
+ send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
+
+ if (i2c_start_write(SSD1306_ADDRESS)) {
+ goto done;
+ }
+ if (i2c_master_write(0x40)) {
+ // Data mode
+ goto done;
+ }
+
+ for (uint8_t row = 0; row < MatrixRows; ++row) {
+ for (uint8_t col = 0; col < MatrixCols; ++col) {
+ const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1));
+
+ for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) {
+ uint8_t colBits = pgm_read_byte(glyph + glyphCol);
+ i2c_master_write(colBits);
+ }
- // Move to the home position
- send_cmd3(PageAddr, 0, MatrixRows - 1);
- send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
-
- if (i2c_start_write(SSD1306_ADDRESS)) {
- goto done;
- }
- if (i2c_master_write(0x40)) {
- // Data mode
- goto done;
- }
-
- for (uint8_t row = 0; row < MatrixRows; ++row) {
- for (uint8_t col = 0; col < MatrixCols; ++col) {
- const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1));
-
- for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) {
- uint8_t colBits = pgm_read_byte(glyph + glyphCol);
- i2c_master_write(colBits);
- }
-
- // 1 column of space between chars (it's not included in the glyph)
- i2c_master_write(0);
+ // 1 column of space between chars (it's not included in the glyph)
+ i2c_master_write(0);
+ }
}
- }
- matrix->dirty = false;
+ matrix->dirty = false;
done:
- i2c_master_stop();
-#if DEBUG_TO_SCREEN
- --displaying;
-#endif
+ i2c_master_stop();
+# if DEBUG_TO_SCREEN
+ --displaying;
+# endif
}
-void iota_gfx_flush(void) {
- matrix_render(&display);
-}
+void iota_gfx_flush(void) { matrix_render(&display); }
-__attribute__ ((weak))
-void iota_gfx_task_user(void) {
-}
+__attribute__((weak)) void iota_gfx_task_user(void) {}
void iota_gfx_task(void) {
- iota_gfx_task_user();
+ iota_gfx_task_user();
- if (display.dirty) {
- iota_gfx_flush();
- }
+ if (display.dirty) {
+ iota_gfx_flush();
+ }
- if (timer_elapsed(last_flush) > ScreenOffInterval) {
- iota_gfx_off();
- }
+ if (timer_elapsed(last_flush) > ScreenOffInterval) {
+ iota_gfx_off();
+ }
}
#endif
diff --git a/drivers/avr/ssd1306.h b/drivers/avr/ssd1306.h
index df6a75359f..825b0d7d5b 100644
--- a/drivers/avr/ssd1306.h
+++ b/drivers/avr/ssd1306.h
@@ -7,49 +7,49 @@
#include "config.h"
enum ssd1306_cmds {
- DisplayOff = 0xAE,
- DisplayOn = 0xAF,
-
- SetContrast = 0x81,
- DisplayAllOnResume = 0xA4,
-
- DisplayAllOn = 0xA5,
- NormalDisplay = 0xA6,
- InvertDisplay = 0xA7,
- SetDisplayOffset = 0xD3,
- SetComPins = 0xda,
- SetVComDetect = 0xdb,
- SetDisplayClockDiv = 0xD5,
- SetPreCharge = 0xd9,
- SetMultiPlex = 0xa8,
- SetLowColumn = 0x00,
- SetHighColumn = 0x10,
- SetStartLine = 0x40,
-
- SetMemoryMode = 0x20,
- ColumnAddr = 0x21,
- PageAddr = 0x22,
-
- ComScanInc = 0xc0,
- ComScanDec = 0xc8,
- SegRemap = 0xa0,
- SetChargePump = 0x8d,
- ExternalVcc = 0x01,
- SwitchCapVcc = 0x02,
-
- ActivateScroll = 0x2f,
- DeActivateScroll = 0x2e,
- SetVerticalScrollArea = 0xa3,
- RightHorizontalScroll = 0x26,
- LeftHorizontalScroll = 0x27,
- VerticalAndRightHorizontalScroll = 0x29,
- VerticalAndLeftHorizontalScroll = 0x2a,
+ DisplayOff = 0xAE,
+ DisplayOn = 0xAF,
+
+ SetContrast = 0x81,
+ DisplayAllOnResume = 0xA4,
+
+ DisplayAllOn = 0xA5,
+ NormalDisplay = 0xA6,
+ InvertDisplay = 0xA7,
+ SetDisplayOffset = 0xD3,
+ SetComPins = 0xda,
+ SetVComDetect = 0xdb,
+ SetDisplayClockDiv = 0xD5,
+ SetPreCharge = 0xd9,
+ SetMultiPlex = 0xa8,
+ SetLowColumn = 0x00,
+ SetHighColumn = 0x10,
+ SetStartLine = 0x40,
+
+ SetMemoryMode = 0x20,
+ ColumnAddr = 0x21,
+ PageAddr = 0x22,
+
+ ComScanInc = 0xc0,
+ ComScanDec = 0xc8,
+ SegRemap = 0xa0,
+ SetChargePump = 0x8d,
+ ExternalVcc = 0x01,
+ SwitchCapVcc = 0x02,
+
+ ActivateScroll = 0x2f,
+ DeActivateScroll = 0x2e,
+ SetVerticalScrollArea = 0xa3,
+ RightHorizontalScroll = 0x26,
+ LeftHorizontalScroll = 0x27,
+ VerticalAndRightHorizontalScroll = 0x29,
+ VerticalAndLeftHorizontalScroll = 0x2a,
};
// Controls the SSD1306 128x32 OLED display via i2c
#ifndef SSD1306_ADDRESS
-#define SSD1306_ADDRESS 0x3C
+# define SSD1306_ADDRESS 0x3C
#endif
#define DisplayHeight 32
@@ -62,9 +62,9 @@ enum ssd1306_cmds {
#define MatrixCols (DisplayWidth / FontWidth)
struct CharacterMatrix {
- uint8_t display[MatrixRows][MatrixCols];
- uint8_t *cursor;
- bool dirty;
+ uint8_t display[MatrixRows][MatrixCols];
+ uint8_t *cursor;
+ bool dirty;
};
struct CharacterMatrix display;
@@ -88,6 +88,4 @@ void matrix_write(struct CharacterMatrix *matrix, const char *data);
void matrix_write_P(struct CharacterMatrix *matrix, const char *data);
void matrix_render(struct CharacterMatrix *matrix);
-
-
#endif
diff --git a/drivers/avr/ws2812.c b/drivers/avr/ws2812.c
index 7c3cb5174d..82d985c20a 100644
--- a/drivers/avr/ws2812.c
+++ b/drivers/avr/ws2812.c
@@ -1,230 +1,61 @@
/*
-* light weight WS2812 lib V2.0b
-*
-* Controls WS2811/WS2812/WS2812B RGB-LEDs
-* Author: Tim (cpldcpu@gmail.com)
-*
-* Jan 18th, 2014 v2.0b Initial Version
-* Nov 29th, 2015 v2.3 Added SK6812RGBW support
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ * light weight WS2812 lib V2.0b
+ *
+ * Controls WS2811/WS2812/WS2812B RGB-LEDs
+ * Author: Tim (cpldcpu@gmail.com)
+ *
+ * Jan 18th, 2014 v2.0b Initial Version
+ * Nov 29th, 2015 v2.3 Added SK6812RGBW support
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include "ws2812.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
-#include "debug.h"
-
-#if !defined(LED_ARRAY) && defined(RGB_MATRIX_ENABLE)
-// LED color buffer
-LED_TYPE led[DRIVER_LED_TOTAL];
- #define LED_ARRAY led
-#endif
-
-#ifdef RGBW_BB_TWI
-
-// Port for the I2C
-#define I2C_DDR DDRD
-#define I2C_PIN PIND
-#define I2C_PORT PORTD
-
-// Pins to be used in the bit banging
-#define I2C_CLK 0
-#define I2C_DAT 1
-
-#define I2C_DATA_HI()\
-I2C_DDR &= ~ (1 << I2C_DAT);\
-I2C_PORT |= (1 << I2C_DAT);
-#define I2C_DATA_LO()\
-I2C_DDR |= (1 << I2C_DAT);\
-I2C_PORT &= ~ (1 << I2C_DAT);
-
-#define I2C_CLOCK_HI()\
-I2C_DDR &= ~ (1 << I2C_CLK);\
-I2C_PORT |= (1 << I2C_CLK);
-#define I2C_CLOCK_LO()\
-I2C_DDR |= (1 << I2C_CLK);\
-I2C_PORT &= ~ (1 << I2C_CLK);
-
-#define I2C_DELAY 1
-
-void I2C_WriteBit(unsigned char c)
-{
- if (c > 0)
- {
- I2C_DATA_HI();
- }
- else
- {
- I2C_DATA_LO();
- }
-
- I2C_CLOCK_HI();
- _delay_us(I2C_DELAY);
-
- I2C_CLOCK_LO();
- _delay_us(I2C_DELAY);
-
- if (c > 0)
- {
- I2C_DATA_LO();
- }
-
- _delay_us(I2C_DELAY);
-}
-
-// Inits bitbanging port, must be called before using the functions below
-//
-void I2C_Init(void)
-{
- I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
-
- I2C_CLOCK_HI();
- I2C_DATA_HI();
-
- _delay_us(I2C_DELAY);
-}
-
-// Send a START Condition
-//
-void I2C_Start(void)
-{
- // set both to high at the same time
- I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
- _delay_us(I2C_DELAY);
-
- I2C_DATA_LO();
- _delay_us(I2C_DELAY);
-
- I2C_CLOCK_LO();
- _delay_us(I2C_DELAY);
-}
-
-// Send a STOP Condition
-//
-void I2C_Stop(void)
-{
- I2C_CLOCK_HI();
- _delay_us(I2C_DELAY);
-
- I2C_DATA_HI();
- _delay_us(I2C_DELAY);
-}
-
-// write a byte to the I2C slave device
-//
-unsigned char I2C_Write(unsigned char c)
-{
- for (char i = 0; i < 8; i++)
- {
- I2C_WriteBit(c & 128);
- c <<= 1;
- }
-
-
- I2C_WriteBit(0);
- _delay_us(I2C_DELAY);
- _delay_us(I2C_DELAY);
-
- // _delay_us(I2C_DELAY);
- //return I2C_ReadBit();
- return 0;
-}
-
-
-#endif
+/*
+ * Forward declare internal functions
+ *
+ * The functions take a byte-array and send to the data output as WS2812 bitstream.
+ * The length is the number of bytes to send - three per LED.
+ */
-#ifdef RGB_MATRIX_ENABLE
-// Set an led in the buffer to a color
-void inline ws2812_setled(int i, uint8_t r, uint8_t g, uint8_t b)
-{
- led[i].r = r;
- led[i].g = g;
- led[i].b = b;
-}
-
-void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b)
-{
- for (int i = 0; i < sizeof(led)/sizeof(led[0]); i++) {
- led[i].r = r;
- led[i].g = g;
- led[i].b = b;
- }
-}
-#endif
+void ws2812_sendarray(uint8_t *array, uint16_t length);
+void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask);
// Setleds for standard RGB
-void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
-{
- // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
- ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF));
+void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {
+ // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
+ ws2812_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF));
}
-void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask)
-{
- // ws2812_DDRREG |= pinmask; // Enable DDR
- // new universal format (DDR)
- _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask;
-
- ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask);
- _delay_us(50);
-}
+void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) {
+ // new universal format (DDR)
+ _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask;
-// Setleds for SK6812RGBW
-void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
-{
+ ws2812_sendarray_mask((uint8_t *)ledarray, leds * sizeof(LED_TYPE), pinmask);
- #ifdef RGBW_BB_TWI
- uint8_t sreg_prev, twcr_prev;
- sreg_prev=SREG;
- twcr_prev=TWCR;
- cli();
- TWCR &= ~(1<<TWEN);
- I2C_Init();
- I2C_Start();
- I2C_Write(0x84);
- uint16_t datlen = leds<<2;
- uint8_t curbyte;
- uint8_t * data = (uint8_t*)ledarray;
- while (datlen--) {
- curbyte=*data++;
- I2C_Write(curbyte);
- }
- I2C_Stop();
- SREG=sreg_prev;
- TWCR=twcr_prev;
- #endif
-
-
- // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
- // new universal format (DDR)
- _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
-
- ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
-
-
- #ifndef RGBW_BB_TWI
+#ifdef RGBW
_delay_us(80);
- #endif
+#else
+ _delay_us(50);
+#endif
}
-void ws2812_sendarray(uint8_t *data,uint16_t datlen)
-{
- ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF));
-}
+void ws2812_sendarray(uint8_t *data, uint16_t datlen) { ws2812_sendarray_mask(data, datlen, _BV(RGB_DI_PIN & 0xF)); }
/*
This routine writes an array of bytes with RGB values to the Dataout pin
@@ -232,136 +63,133 @@ void ws2812_sendarray(uint8_t *data,uint16_t datlen)
*/
// Timing in ns
-#define w_zeropulse 350
-#define w_onepulse 900
+#define w_zeropulse 350
+#define w_onepulse 900
#define w_totalperiod 1250
// Fixed cycles used by the inner loop
-#define w_fixedlow 2
-#define w_fixedhigh 4
-#define w_fixedtotal 8
+#define w_fixedlow 2
+#define w_fixedhigh 4
+#define w_fixedtotal 8
// Insert NOPs to match the timing, if possible
-#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000)
-#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000)
-#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000)
+#define w_zerocycles (((F_CPU / 1000) * w_zeropulse) / 1000000)
+#define w_onecycles (((F_CPU / 1000) * w_onepulse + 500000) / 1000000)
+#define w_totalcycles (((F_CPU / 1000) * w_totalperiod + 500000) / 1000000)
// w1 - nops between rising edge and falling edge - low
-#define w1 (w_zerocycles-w_fixedlow)
+#define w1 (w_zerocycles - w_fixedlow)
// w2 nops between fe low and fe high
-#define w2 (w_onecycles-w_fixedhigh-w1)
+#define w2 (w_onecycles - w_fixedhigh - w1)
// w3 nops to complete loop
-#define w3 (w_totalcycles-w_fixedtotal-w1-w2)
+#define w3 (w_totalcycles - w_fixedtotal - w1 - w2)
-#if w1>0
- #define w1_nops w1
+#if w1 > 0
+# define w1_nops w1
#else
- #define w1_nops 0
+# define w1_nops 0
#endif
// The only critical timing parameter is the minimum pulse length of the "0"
// Warn or throw error if this timing can not be met with current F_CPU settings.
-#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
-#if w_lowtime>550
- #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
-#elif w_lowtime>450
- #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
- #warning "Please consider a higher clockspeed, if possible"
+#define w_lowtime ((w1_nops + w_fixedlow) * 1000000) / (F_CPU / 1000)
+#if w_lowtime > 550
+# error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
+#elif w_lowtime > 450
+# warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
+# warning "Please consider a higher clockspeed, if possible"
#endif
-#if w2>0
-#define w2_nops w2
+#if w2 > 0
+# define w2_nops w2
#else
-#define w2_nops 0
+# define w2_nops 0
#endif
-#if w3>0
-#define w3_nops w3
+#if w3 > 0
+# define w3_nops w3
#else
-#define w3_nops 0
+# define w3_nops 0
#endif
-#define w_nop1 "nop \n\t"
-#define w_nop2 "rjmp .+0 \n\t"
-#define w_nop4 w_nop2 w_nop2
-#define w_nop8 w_nop4 w_nop4
+#define w_nop1 "nop \n\t"
+#define w_nop2 "rjmp .+0 \n\t"
+#define w_nop4 w_nop2 w_nop2
+#define w_nop8 w_nop4 w_nop4
#define w_nop16 w_nop8 w_nop8
-void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
-{
- uint8_t curbyte,ctr,masklo;
- uint8_t sreg_prev;
+void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi) {
+ uint8_t curbyte, ctr, masklo;
+ uint8_t sreg_prev;
- // masklo =~maskhi&ws2812_PORTREG;
- // maskhi |= ws2812_PORTREG;
- masklo =~maskhi&_SFR_IO8((RGB_DI_PIN >> 4) + 2);
- maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2);
- sreg_prev=SREG;
- cli();
+ // masklo =~maskhi&ws2812_PORTREG;
+ // maskhi |= ws2812_PORTREG;
+ masklo = ~maskhi & _SFR_IO8((RGB_DI_PIN >> 4) + 2);
+ maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2);
+ sreg_prev = SREG;
+ cli();
- while (datlen--) {
- curbyte=(*data++);
+ while (datlen--) {
+ curbyte = (*data++);
- asm volatile(
- " ldi %0,8 \n\t"
- "loop%=: \n\t"
- " out %2,%3 \n\t" // '1' [01] '0' [01] - re
-#if (w1_nops&1)
-w_nop1
+ asm volatile(" ldi %0,8 \n\t"
+ "loop%=: \n\t"
+ " out %2,%3 \n\t" // '1' [01] '0' [01] - re
+#if (w1_nops & 1)
+ w_nop1
#endif
-#if (w1_nops&2)
-w_nop2
+#if (w1_nops & 2)
+ w_nop2
#endif
-#if (w1_nops&4)
-w_nop4
+#if (w1_nops & 4)
+ w_nop4
#endif
-#if (w1_nops&8)
-w_nop8
+#if (w1_nops & 8)
+ w_nop8
#endif
-#if (w1_nops&16)
-w_nop16
+#if (w1_nops & 16)
+ w_nop16
#endif
- " sbrs %1,7 \n\t" // '1' [03] '0' [02]
- " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low
- " lsl %1 \n\t" // '1' [04] '0' [04]
-#if (w2_nops&1)
- w_nop1
+ " sbrs %1,7 \n\t" // '1' [03] '0' [02]
+ " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low
+ " lsl %1 \n\t" // '1' [04] '0' [04]
+#if (w2_nops & 1)
+ w_nop1
#endif
-#if (w2_nops&2)
- w_nop2
+#if (w2_nops & 2)
+ w_nop2
#endif
-#if (w2_nops&4)
- w_nop4
+#if (w2_nops & 4)
+ w_nop4
#endif
-#if (w2_nops&8)
- w_nop8
+#if (w2_nops & 8)
+ w_nop8
#endif
-#if (w2_nops&16)
- w_nop16
+#if (w2_nops & 16)
+ w_nop16
#endif
- " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high
-#if (w3_nops&1)
-w_nop1
+ " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high
+#if (w3_nops & 1)
+ w_nop1
#endif
-#if (w3_nops&2)
-w_nop2
+#if (w3_nops & 2)
+ w_nop2
#endif
-#if (w3_nops&4)
-w_nop4
+#if (w3_nops & 4)
+ w_nop4
#endif
-#if (w3_nops&8)
-w_nop8
+#if (w3_nops & 8)
+ w_nop8
#endif
-#if (w3_nops&16)
-w_nop16
+#if (w3_nops & 16)
+ w_nop16
#endif
- " dec %0 \n\t" // '1' [+2] '0' [+2]
- " brne loop%=\n\t" // '1' [+3] '0' [+4]
- : "=&d" (ctr)
- : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo)
- );
- }
+ " dec %0 \n\t" // '1' [+2] '0' [+2]
+ " brne loop%=\n\t" // '1' [+3] '0' [+4]
+ : "=&d"(ctr)
+ : "r"(curbyte), "I"(_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r"(maskhi), "r"(masklo));
+ }
- SREG=sreg_prev;
+ SREG = sreg_prev;
}
diff --git a/drivers/avr/ws2812.h b/drivers/avr/ws2812.h
index 95f540b184..b869fb28c8 100644
--- a/drivers/avr/ws2812.h
+++ b/drivers/avr/ws2812.h
@@ -20,13 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LIGHT_WS2812_H_
-#define LIGHT_WS2812_H_
-
-#include <avr/io.h>
-#include <avr/interrupt.h>
-//#include "ws2812_config.h"
-//#include "i2cmaster.h"
+#pragma once
#include "quantum/color.h"
@@ -40,36 +34,7 @@
* The functions will perform the following actions:
* - Set the data-out pin as output
* - Send out the LED data
- * - Wait 50�s to reset the LEDs
- */
-#ifdef RGB_MATRIX_ENABLE
-void ws2812_setled (int index, uint8_t r, uint8_t g, uint8_t b);
-void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b);
-#endif
-
-void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds);
-void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask);
-void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
-
-/*
- * Old interface / Internal functions
- *
- * The functions take a byte-array and send to the data output as WS2812 bitstream.
- * The length is the number of bytes to send - three per LED.
+ * - Wait 50us to reset the LEDs
*/
-
-void ws2812_sendarray (uint8_t *array,uint16_t length);
-void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
-
-
-/*
- * Internal defines
- */
-#ifndef CONCAT
-#define CONCAT(a, b) a ## b
-#endif
-#ifndef CONCAT_EXP
-#define CONCAT_EXP(a, b) CONCAT(a, b)
-#endif
-
-#endif /* LIGHT_WS2812_H_ */
+void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
+void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask);
diff --git a/drivers/avr/ws2812_i2c.c b/drivers/avr/ws2812_i2c.c
new file mode 100644
index 0000000000..1c332e24b6
--- /dev/null
+++ b/drivers/avr/ws2812_i2c.c
@@ -0,0 +1,27 @@
+#include "ws2812.h"
+#include "i2c_master.h"
+
+#ifdef RGBW
+# error "RGBW not supported"
+#endif
+
+#ifndef WS2812_ADDRESS
+# define WS2812_ADDRESS 0xb0
+#endif
+
+#ifndef WS2812_TIMEOUT
+# define WS2812_TIMEOUT 100
+#endif
+
+void ws2812_init(void) { i2c_init(); }
+
+// Setleds for standard RGB
+void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {
+ static bool s_init = false;
+ if (!s_init) {
+ ws2812_init();
+ s_init = true;
+ }
+
+ i2c_transmit(WS2812_ADDRESS, (uint8_t *)ledarray, sizeof(LED_TYPE) * leds, WS2812_TIMEOUT);
+}