clang-format changes
This commit is contained in:
parent
61af76a10d
commit
b624f32f94
502 changed files with 32259 additions and 39062 deletions
|
@ -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;
|
||||
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!
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,34 +19,34 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
void analogReference(uint8_t mode);
|
||||
void analogReference(uint8_t mode);
|
||||
int16_t analogRead(uint8_t pin);
|
||||
int16_t adc_read(uint8_t mux);
|
||||
|
||||
#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
|
||||
|
|
157
drivers/avr/apa102.c
Executable file → Normal file
157
drivers/avr/apa102.c
Executable file → Normal file
|
@ -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);
|
||||
|
||||
apa102_send_array((uint8_t *)ledarray, leds)
|
||||
}
|
||||
|
||||
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)
|
||||
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_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.
|
||||
|
||||
apa102_send_byte(0xFF);
|
||||
for (uint16_t i = 0; i < 5 + leds / 16; i++) {
|
||||
apa102_send_byte(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?
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
5
drivers/avr/apa102.h
Executable file → Normal file
5
drivers/avr/apa102.h
Executable file → Normal file
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "color.h"
|
||||
|
||||
|
||||
/* User Interface
|
||||
*
|
||||
* Input:
|
||||
|
@ -41,6 +40,6 @@
|
|||
* - Wait 50<EFBFBD>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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
#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 PIN(x) (*(&x - 2)) /* address of input register of port x */
|
||||
#endif
|
||||
|
||||
#if LCD_IO_MODE
|
||||
#if LCD_LINES==1
|
||||
#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE
|
||||
#else
|
||||
#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES
|
||||
# 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
|
||||
# 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_e_high();
|
||||
lcd_e_delay();
|
||||
data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */
|
||||
lcd_e_low();
|
||||
|
||||
lcd_e_delay(); /* Enable 500ns low */
|
||||
|
||||
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)&0x0F; /* read low nibble */
|
||||
data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */
|
||||
lcd_e_low();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
lcd_e_delay(); /* Enable 500ns low */
|
||||
|
||||
lcd_e_high();
|
||||
lcd_e_delay();
|
||||
data |= PIN(LCD_DATA0_PORT) & 0x0F; /* read low nibble */
|
||||
lcd_e_low();
|
||||
} 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_REP); /* delay, busy flag can't be checked here */
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -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
|
||||
# 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__)
|
||||
#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
|
||||
|
|
250
drivers/avr/i2c_master.c
Executable file → Normal file
250
drivers/avr/i2c_master.c
Executable file → Normal file
|
@ -25,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)
|
||||
|
||||
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);
|
||||
// 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;
|
||||
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 start condition was successfully transmitted
|
||||
if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) {
|
||||
return I2C_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// load slave address into data register
|
||||
TWDR = address;
|
||||
// start transmission of address
|
||||
TWCR = (1 << TWINT) | (1 << TWEN);
|
||||
|
||||
return I2C_STATUS_SUCCESS;
|
||||
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);
|
||||
// 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;
|
||||
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);
|
||||
// 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;
|
||||
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);
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
status = i2c_write(regaddr, timeout);
|
||||
if (status < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
i2c_status_t status = i2c_start(devaddr, timeout);
|
||||
if (status < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (status >= 0) {
|
||||
status = i2c_read_nack(timeout);
|
||||
if (status >= 0) {
|
||||
data[(length - 1)] = status;
|
||||
status = i2c_write(regaddr, timeout);
|
||||
if (status < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (status >= 0) {
|
||||
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);
|
||||
}
|
||||
|
|
12
drivers/avr/i2c_master.h
Executable file → Normal file
12
drivers/avr/i2c_master.h
Executable file → Normal file
|
@ -26,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
|
||||
|
|
18
drivers/avr/i2c_slave.c
Executable file → Normal file
18
drivers/avr/i2c_slave.c
Executable file → Normal file
|
@ -27,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;
|
||||
|
@ -53,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++;
|
||||
|
|
2
drivers/avr/i2c_slave.h
Executable file → Normal file
2
drivers/avr/i2c_slave.h
Executable file → Normal file
|
@ -30,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
|
||||
#endif // I2C_SLAVE_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
|
||||
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, // 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
|
||||
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
|
||||
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, // 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(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(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(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(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(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 */
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
// 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);
|
||||
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;
|
||||
*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);
|
||||
}
|
||||
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);
|
||||
// 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);
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
goto done;
|
||||
}
|
||||
if (i2c_master_write(0x40)) {
|
||||
// Data mode
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
matrix->dirty = false;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -7,49 +7,49 @@
|
|||
#include "config.h"
|
||||
|
||||
enum ssd1306_cmds {
|
||||
DisplayOff = 0xAE,
|
||||
DisplayOn = 0xAF,
|
||||
DisplayOff = 0xAE,
|
||||
DisplayOn = 0xAF,
|
||||
|
||||
SetContrast = 0x81,
|
||||
DisplayAllOnResume = 0xA4,
|
||||
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,
|
||||
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,
|
||||
SetMemoryMode = 0x20,
|
||||
ColumnAddr = 0x21,
|
||||
PageAddr = 0x22,
|
||||
|
||||
ComScanInc = 0xc0,
|
||||
ComScanDec = 0xc8,
|
||||
SegRemap = 0xa0,
|
||||
SetChargePump = 0x8d,
|
||||
ExternalVcc = 0x01,
|
||||
SwitchCapVcc = 0x02,
|
||||
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,
|
||||
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
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
/*
|
||||
* 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>
|
||||
|
@ -30,44 +30,40 @@
|
|||
#if !defined(LED_ARRAY) && defined(RGB_MATRIX_ENABLE)
|
||||
// LED color buffer
|
||||
LED_TYPE led[DRIVER_LED_TOTAL];
|
||||
#define LED_ARRAY led
|
||||
# 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
|
||||
# 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_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_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_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
|
||||
# define I2C_DELAY 1
|
||||
|
||||
void I2C_WriteBit(unsigned char c)
|
||||
{
|
||||
if (c > 0)
|
||||
{
|
||||
void I2C_WriteBit(unsigned char c) {
|
||||
if (c > 0) {
|
||||
I2C_DATA_HI();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
I2C_DATA_LO();
|
||||
}
|
||||
|
||||
|
@ -77,8 +73,7 @@ void I2C_WriteBit(unsigned char c)
|
|||
I2C_CLOCK_LO();
|
||||
_delay_us(I2C_DELAY);
|
||||
|
||||
if (c > 0)
|
||||
{
|
||||
if (c > 0) {
|
||||
I2C_DATA_LO();
|
||||
}
|
||||
|
||||
|
@ -87,9 +82,8 @@ void I2C_WriteBit(unsigned char c)
|
|||
|
||||
// Inits bitbanging port, must be called before using the functions below
|
||||
//
|
||||
void I2C_Init(void)
|
||||
{
|
||||
I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
|
||||
void I2C_Init(void) {
|
||||
I2C_PORT &= ~((1 << I2C_DAT) | (1 << I2C_CLK));
|
||||
|
||||
I2C_CLOCK_HI();
|
||||
I2C_DATA_HI();
|
||||
|
@ -99,10 +93,9 @@ void I2C_Init(void)
|
|||
|
||||
// Send a START Condition
|
||||
//
|
||||
void I2C_Start(void)
|
||||
{
|
||||
void I2C_Start(void) {
|
||||
// set both to high at the same time
|
||||
I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
|
||||
I2C_DDR &= ~((1 << I2C_DAT) | (1 << I2C_CLK));
|
||||
_delay_us(I2C_DELAY);
|
||||
|
||||
I2C_DATA_LO();
|
||||
|
@ -114,8 +107,7 @@ void I2C_Start(void)
|
|||
|
||||
// Send a STOP Condition
|
||||
//
|
||||
void I2C_Stop(void)
|
||||
{
|
||||
void I2C_Stop(void) {
|
||||
I2C_CLOCK_HI();
|
||||
_delay_us(I2C_DELAY);
|
||||
|
||||
|
@ -125,106 +117,91 @@ void I2C_Stop(void)
|
|||
|
||||
// write a byte to the I2C slave device
|
||||
//
|
||||
unsigned char I2C_Write(unsigned char c)
|
||||
{
|
||||
for (char i = 0; i < 8; i++)
|
||||
{
|
||||
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 I2C_ReadBit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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
|
||||
|
||||
// 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;
|
||||
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);
|
||||
ws2812_sendarray_mask((uint8_t *)ledarray, leds + leds + leds, pinmask);
|
||||
_delay_us(50);
|
||||
}
|
||||
|
||||
// Setleds for SK6812RGBW
|
||||
void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
|
||||
{
|
||||
|
||||
#ifdef RGBW_BB_TWI
|
||||
void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) {
|
||||
#ifdef RGBW_BB_TWI
|
||||
uint8_t sreg_prev, twcr_prev;
|
||||
sreg_prev=SREG;
|
||||
twcr_prev=TWCR;
|
||||
sreg_prev = SREG;
|
||||
twcr_prev = TWCR;
|
||||
cli();
|
||||
TWCR &= ~(1<<TWEN);
|
||||
TWCR &= ~(1 << TWEN);
|
||||
I2C_Init();
|
||||
I2C_Start();
|
||||
I2C_Write(0x84);
|
||||
uint16_t datlen = leds<<2;
|
||||
uint8_t curbyte;
|
||||
uint8_t * data = (uint8_t*)ledarray;
|
||||
uint16_t datlen = leds << 2;
|
||||
uint8_t curbyte;
|
||||
uint8_t *data = (uint8_t *)ledarray;
|
||||
while (datlen--) {
|
||||
curbyte=*data++;
|
||||
I2C_Write(curbyte);
|
||||
curbyte = *data++;
|
||||
I2C_Write(curbyte);
|
||||
}
|
||||
I2C_Stop();
|
||||
SREG=sreg_prev;
|
||||
TWCR=twcr_prev;
|
||||
#endif
|
||||
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_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));
|
||||
|
||||
ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
|
||||
|
||||
|
||||
#ifndef RGBW_BB_TWI
|
||||
#ifndef RGBW_BB_TWI
|
||||
_delay_us(80);
|
||||
#endif
|
||||
#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 +209,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;
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@
|
|||
* - Wait 50<EFBFBD>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);
|
||||
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(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);
|
||||
|
||||
/*
|
||||
|
@ -58,18 +58,17 @@ void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
|
|||
* The length is the number of bytes to send - three per LED.
|
||||
*/
|
||||
|
||||
void ws2812_sendarray (uint8_t *array,uint16_t length);
|
||||
void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
|
||||
|
||||
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
|
||||
# define CONCAT(a, b) a##b
|
||||
#endif
|
||||
#ifndef CONCAT_EXP
|
||||
#define CONCAT_EXP(a, b) CONCAT(a, b)
|
||||
# define CONCAT_EXP(a, b) CONCAT(a, b)
|
||||
#endif
|
||||
|
||||
#endif /* LIGHT_WS2812_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue