clang-format changes
This commit is contained in:
		
							parent
							
								
									61af76a10d
								
							
						
					
					
						commit
						b624f32f94
					
				
					 502 changed files with 32259 additions and 39062 deletions
				
			
		|  | @ -34,98 +34,83 @@ static uint8_t i2c_address; | |||
| 
 | ||||
| static const I2CConfig i2cconfig = { | ||||
| #ifdef USE_I2CV1 | ||||
|   I2C1_OPMODE, | ||||
|   I2C1_CLOCK_SPEED, | ||||
|   I2C1_DUTY_CYCLE, | ||||
|     I2C1_OPMODE, | ||||
|     I2C1_CLOCK_SPEED, | ||||
|     I2C1_DUTY_CYCLE, | ||||
| #else | ||||
|   STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | | ||||
|   STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | | ||||
|   STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH)  | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), | ||||
|   0, | ||||
|   0 | ||||
|     STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), 0, 0 | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| static i2c_status_t chibios_to_qmk(const msg_t* status) { | ||||
|   switch (*status) { | ||||
|     case I2C_NO_ERROR: | ||||
|       return I2C_STATUS_SUCCESS; | ||||
|     case I2C_TIMEOUT: | ||||
|       return I2C_STATUS_TIMEOUT; | ||||
|     // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
 | ||||
|     default: | ||||
|       return I2C_STATUS_ERROR; | ||||
|   } | ||||
|     switch (*status) { | ||||
|         case I2C_NO_ERROR: | ||||
|             return I2C_STATUS_SUCCESS; | ||||
|         case I2C_TIMEOUT: | ||||
|             return I2C_STATUS_TIMEOUT; | ||||
|         // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
 | ||||
|         default: | ||||
|             return I2C_STATUS_ERROR; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| void i2c_init(void) | ||||
| { | ||||
|   // Try releasing special pins for a short time
 | ||||
|   palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT); | ||||
|   palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT); | ||||
| __attribute__((weak)) void i2c_init(void) { | ||||
|     // Try releasing special pins for a short time
 | ||||
|     palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT); | ||||
|     palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT); | ||||
| 
 | ||||
|   chThdSleepMilliseconds(10); | ||||
|     chThdSleepMilliseconds(10); | ||||
| 
 | ||||
| #ifdef USE_I2CV1 | ||||
|   palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); | ||||
|   palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); | ||||
|     palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); | ||||
|     palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); | ||||
| #else | ||||
|   palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); | ||||
|   palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); | ||||
|     palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); | ||||
|     palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); | ||||
| #endif | ||||
| 
 | ||||
|   //i2cInit(); //This is invoked by halInit() so no need to redo it.
 | ||||
|     // i2cInit(); //This is invoked by halInit() so no need to redo it.
 | ||||
| } | ||||
| 
 | ||||
| i2c_status_t i2c_start(uint8_t address) | ||||
| { | ||||
|   i2c_address = address; | ||||
|   i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|   return I2C_STATUS_SUCCESS; | ||||
| i2c_status_t i2c_start(uint8_t address) { | ||||
|     i2c_address = address; | ||||
|     i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|     return I2C_STATUS_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) | ||||
| { | ||||
|   i2c_address = address; | ||||
|   i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|   msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout)); | ||||
|   return chibios_to_qmk(&status); | ||||
| i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { | ||||
|     i2c_address = address; | ||||
|     i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|     msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout)); | ||||
|     return chibios_to_qmk(&status); | ||||
| } | ||||
| 
 | ||||
| i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) | ||||
| { | ||||
|   i2c_address = address; | ||||
|   i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|   msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout)); | ||||
|   return chibios_to_qmk(&status); | ||||
| i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { | ||||
|     i2c_address = address; | ||||
|     i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|     msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout)); | ||||
|     return chibios_to_qmk(&status); | ||||
| } | ||||
| 
 | ||||
| i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) | ||||
| { | ||||
|   i2c_address = devaddr; | ||||
|   i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
| i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { | ||||
|     i2c_address = devaddr; | ||||
|     i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
| 
 | ||||
|   uint8_t complete_packet[length + 1]; | ||||
|   for(uint8_t i = 0; i < length; i++) | ||||
|   { | ||||
|     complete_packet[i+1] = data[i]; | ||||
|   } | ||||
|   complete_packet[0] = regaddr; | ||||
|     uint8_t complete_packet[length + 1]; | ||||
|     for (uint8_t i = 0; i < length; i++) { | ||||
|         complete_packet[i + 1] = data[i]; | ||||
|     } | ||||
|     complete_packet[0] = regaddr; | ||||
| 
 | ||||
|   msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); | ||||
|   return chibios_to_qmk(&status); | ||||
|     msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); | ||||
|     return chibios_to_qmk(&status); | ||||
| } | ||||
| 
 | ||||
| i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) | ||||
| { | ||||
|   i2c_address = devaddr; | ||||
|   i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|   msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), ®addr, 1, data, length, MS2ST(timeout)); | ||||
|   return chibios_to_qmk(&status); | ||||
| i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { | ||||
|     i2c_address = devaddr; | ||||
|     i2cStart(&I2C_DRIVER, &i2cconfig); | ||||
|     msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), ®addr, 1, data, length, MS2ST(timeout)); | ||||
|     return chibios_to_qmk(&status); | ||||
| } | ||||
| 
 | ||||
| void i2c_stop(void) | ||||
| { | ||||
|   i2cStop(&I2C_DRIVER); | ||||
| } | ||||
| void i2c_stop(void) { i2cStop(&I2C_DRIVER); } | ||||
|  |  | |||
|  | @ -27,84 +27,83 @@ | |||
| #include "ch.h" | ||||
| #include <hal.h> | ||||
| 
 | ||||
| 
 | ||||
| #if defined(STM32F1XX) || defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32L0xx) || defined(STM32L1xx) | ||||
|     #define USE_I2CV1 | ||||
| #    define USE_I2CV1 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef I2C1_BANK | ||||
|     #define I2C1_SCL_BANK I2C1_BANK | ||||
|     #define I2C1_SDA_BANK I2C1_BANK | ||||
| #    define I2C1_SCL_BANK I2C1_BANK | ||||
| #    define I2C1_SDA_BANK I2C1_BANK | ||||
| #endif | ||||
| 
 | ||||
| #ifndef I2C1_SCL_BANK | ||||
|     #define I2C1_SCL_BANK GPIOB | ||||
| #    define I2C1_SCL_BANK GPIOB | ||||
| #endif | ||||
| 
 | ||||
| #ifndef I2C1_SDA_BANK | ||||
|     #define I2C1_SDA_BANK GPIOB | ||||
| #    define I2C1_SDA_BANK GPIOB | ||||
| #endif | ||||
| 
 | ||||
| #ifndef I2C1_SCL | ||||
|     #define I2C1_SCL 6 | ||||
| #    define I2C1_SCL 6 | ||||
| #endif | ||||
| #ifndef I2C1_SDA | ||||
|     #define I2C1_SDA 7 | ||||
| #    define I2C1_SDA 7 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef USE_I2CV1 | ||||
|     #ifndef I2C1_OPMODE | ||||
|         #define I2C1_OPMODE OPMODE_I2C | ||||
|     #endif | ||||
|     #ifndef I2C1_CLOCK_SPEED | ||||
|         #define I2C1_CLOCK_SPEED 100000 /* 400000 */ | ||||
|     #endif | ||||
|     #ifndef I2C1_DUTY_CYCLE | ||||
|         #define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ | ||||
|     #endif | ||||
| #    ifndef I2C1_OPMODE | ||||
| #        define I2C1_OPMODE OPMODE_I2C | ||||
| #    endif | ||||
| #    ifndef I2C1_CLOCK_SPEED | ||||
| #        define I2C1_CLOCK_SPEED 100000 /* 400000 */ | ||||
| #    endif | ||||
| #    ifndef I2C1_DUTY_CYCLE | ||||
| #        define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ | ||||
| #    endif | ||||
| #else | ||||
|     // The default PAL alternate modes are used to signal that the pins are used for I2C
 | ||||
|     #ifndef I2C1_SCL_PAL_MODE | ||||
|         #define I2C1_SCL_PAL_MODE 4 | ||||
|     #endif | ||||
|     #ifndef I2C1_SDA_PAL_MODE | ||||
|         #define I2C1_SDA_PAL_MODE 4 | ||||
|     #endif | ||||
| // The default PAL alternate modes are used to signal that the pins are used for I2C
 | ||||
| #    ifndef I2C1_SCL_PAL_MODE | ||||
| #        define I2C1_SCL_PAL_MODE 4 | ||||
| #    endif | ||||
| #    ifndef I2C1_SDA_PAL_MODE | ||||
| #        define I2C1_SDA_PAL_MODE 4 | ||||
| #    endif | ||||
| 
 | ||||
|     // The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
 | ||||
|     // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
 | ||||
|     #ifndef I2C1_TIMINGR_PRESC | ||||
|         #define I2C1_TIMINGR_PRESC 15U | ||||
|     #endif | ||||
|     #ifndef I2C1_TIMINGR_SCLDEL | ||||
|         #define I2C1_TIMINGR_SCLDEL 4U | ||||
|     #endif | ||||
|     #ifndef I2C1_TIMINGR_SDADEL | ||||
|         #define I2C1_TIMINGR_SDADEL 2U | ||||
|     #endif | ||||
|     #ifndef I2C1_TIMINGR_SCLH | ||||
|         #define I2C1_TIMINGR_SCLH 15U | ||||
|     #endif | ||||
|     #ifndef I2C1_TIMINGR_SCLL | ||||
|         #define I2C1_TIMINGR_SCLL 21U | ||||
|     #endif | ||||
| // The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
 | ||||
| // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
 | ||||
| #    ifndef I2C1_TIMINGR_PRESC | ||||
| #        define I2C1_TIMINGR_PRESC 15U | ||||
| #    endif | ||||
| #    ifndef I2C1_TIMINGR_SCLDEL | ||||
| #        define I2C1_TIMINGR_SCLDEL 4U | ||||
| #    endif | ||||
| #    ifndef I2C1_TIMINGR_SDADEL | ||||
| #        define I2C1_TIMINGR_SDADEL 2U | ||||
| #    endif | ||||
| #    ifndef I2C1_TIMINGR_SCLH | ||||
| #        define I2C1_TIMINGR_SCLH 15U | ||||
| #    endif | ||||
| #    ifndef I2C1_TIMINGR_SCLL | ||||
| #        define I2C1_TIMINGR_SCLL 21U | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| #ifndef I2C_DRIVER | ||||
|   #define I2C_DRIVER I2CD1 | ||||
| #    define I2C_DRIVER I2CD1 | ||||
| #endif | ||||
| 
 | ||||
| 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) | ||||
| 
 | ||||
| void i2c_init(void); | ||||
| void         i2c_init(void); | ||||
| i2c_status_t i2c_start(uint8_t address); | ||||
| 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_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); | ||||
| i2c_status_t i2c_transmit_receive(uint8_t address, uint8_t* tx_body, uint16_t tx_length, uint8_t* rx_body, uint16_t rx_length); | ||||
| 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); | ||||
|  |  | |||
|  | @ -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_ */ | ||||
|  |  | |||
|  | @ -23,42 +23,33 @@ | |||
|  *          This variable is used by the HAL when initializing the PAL driver. | ||||
|  */ | ||||
| const PALConfig pal_default_config = { | ||||
| #if STM32_HAS_GPIOA | ||||
|   {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, | ||||
|    VAL_GPIOA_ODR,   VAL_GPIOA_AFRL,   VAL_GPIOA_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOB | ||||
|   {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, | ||||
|    VAL_GPIOB_ODR,   VAL_GPIOB_AFRL,   VAL_GPIOB_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOC | ||||
|   {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, | ||||
|    VAL_GPIOC_ODR,   VAL_GPIOC_AFRL,   VAL_GPIOC_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOD | ||||
|   {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, | ||||
|    VAL_GPIOD_ODR,   VAL_GPIOD_AFRL,   VAL_GPIOD_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOE | ||||
|   {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, | ||||
|    VAL_GPIOE_ODR,   VAL_GPIOE_AFRL,   VAL_GPIOE_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOF | ||||
|   {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, | ||||
|    VAL_GPIOF_ODR,   VAL_GPIOF_AFRL,   VAL_GPIOF_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOG | ||||
|   {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, | ||||
|    VAL_GPIOG_ODR,   VAL_GPIOG_AFRL,   VAL_GPIOG_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOH | ||||
|   {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, | ||||
|    VAL_GPIOH_ODR,   VAL_GPIOH_AFRL,   VAL_GPIOH_AFRH}, | ||||
| #endif | ||||
| #if STM32_HAS_GPIOI | ||||
|   {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, | ||||
|    VAL_GPIOI_ODR,   VAL_GPIOI_AFRL,   VAL_GPIOI_AFRH} | ||||
| #endif | ||||
| #    if STM32_HAS_GPIOA | ||||
|     {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOB | ||||
|     {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOC | ||||
|     {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOD | ||||
|     {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOE | ||||
|     {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOF | ||||
|     {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOG | ||||
|     {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOH | ||||
|     {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, | ||||
| #    endif | ||||
| #    if STM32_HAS_GPIOI | ||||
|     {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} | ||||
| #    endif | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
|  | @ -70,8 +61,8 @@ void enter_bootloader_mode_if_requested(void); | |||
|  *          and before any other initialization. | ||||
|  */ | ||||
| void __early_init(void) { | ||||
|   enter_bootloader_mode_if_requested(); | ||||
|   stm32_clock_init(); | ||||
|     enter_bootloader_mode_if_requested(); | ||||
|     stm32_clock_init(); | ||||
| } | ||||
| 
 | ||||
| #if HAL_USE_SDC || defined(__DOXYGEN__) | ||||
|  | @ -79,20 +70,18 @@ void __early_init(void) { | |||
|  * @brief   SDC card detection. | ||||
|  */ | ||||
| bool sdc_lld_is_card_inserted(SDCDriver *sdcp) { | ||||
| 
 | ||||
|   (void)sdcp; | ||||
|   /* TODO: Fill the implementation.*/ | ||||
|   return true; | ||||
|     (void)sdcp; | ||||
|     /* TODO: Fill the implementation.*/ | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief   SDC card write protection detection. | ||||
|  */ | ||||
| bool sdc_lld_is_write_protected(SDCDriver *sdcp) { | ||||
| 
 | ||||
|   (void)sdcp; | ||||
|   /* TODO: Fill the implementation.*/ | ||||
|   return false; | ||||
|     (void)sdcp; | ||||
|     /* TODO: Fill the implementation.*/ | ||||
|     return false; | ||||
| } | ||||
| #endif /* HAL_USE_SDC */ | ||||
| 
 | ||||
|  | @ -101,20 +90,18 @@ bool sdc_lld_is_write_protected(SDCDriver *sdcp) { | |||
|  * @brief   MMC_SPI card detection. | ||||
|  */ | ||||
| bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { | ||||
| 
 | ||||
|   (void)mmcp; | ||||
|   /* TODO: Fill the implementation.*/ | ||||
|   return true; | ||||
|     (void)mmcp; | ||||
|     /* TODO: Fill the implementation.*/ | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief   MMC_SPI card write protection detection. | ||||
|  */ | ||||
| bool mmc_lld_is_write_protected(MMCDriver *mmcp) { | ||||
| 
 | ||||
|   (void)mmcp; | ||||
|   /* TODO: Fill the implementation.*/ | ||||
|   return false; | ||||
|     (void)mmcp; | ||||
|     /* TODO: Fill the implementation.*/ | ||||
|     return false; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | @ -122,5 +109,4 @@ bool mmc_lld_is_write_protected(MMCDriver *mmcp) { | |||
|  * @brief   Board-specific initialization code. | ||||
|  * @todo    Add your board-specific code, if any. | ||||
|  */ | ||||
| void boardInit(void) { | ||||
| } | ||||
| void boardInit(void) {} | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -21,154 +21,109 @@ | |||
|  * @details Digital I/O ports static configuration as defined in @p board.h. | ||||
|  *          This variable is used by the HAL when initializing the PAL driver. | ||||
|  */ | ||||
| const PALConfig pal_default_config = | ||||
| { | ||||
|     .ports = { | ||||
| const PALConfig pal_default_config = { | ||||
|     .ports = | ||||
|         { | ||||
|             /*
 | ||||
|              * PORTA setup. | ||||
|              * | ||||
|              * PTA4  - PIN33 | ||||
|              * PTA5  - PIN24 | ||||
|              * PTA12 - PIN3 | ||||
|              * PTA13 - PIN4 | ||||
|              * | ||||
|              * PTA18/19 crystal | ||||
|              * PTA0/3 SWD | ||||
|              */ | ||||
|             .port = IOPORT1, | ||||
|             .pads = { | ||||
|                 PAL_MODE_ALTERNATIVE_7,     PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_ALTERNATIVE_7,     PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_INPUT_ANALOG,      PAL_MODE_INPUT_ANALOG,      PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|             { | ||||
|                 /*
 | ||||
|                  * PORTA setup. | ||||
|                  * | ||||
|                  * PTA4  - PIN33 | ||||
|                  * PTA5  - PIN24 | ||||
|                  * PTA12 - PIN3 | ||||
|                  * PTA13 - PIN4 | ||||
|                  * | ||||
|                  * PTA18/19 crystal | ||||
|                  * PTA0/3 SWD | ||||
|                  */ | ||||
|                 .port = IOPORT1, | ||||
|                 .pads = | ||||
|                     { | ||||
|                         PAL_MODE_ALTERNATIVE_7, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_ALTERNATIVE_7, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_INPUT_ANALOG, PAL_MODE_INPUT_ANALOG, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, | ||||
|                     }, | ||||
|             }, | ||||
|             { | ||||
|                 /*
 | ||||
|                  * PORTB setup. | ||||
|                  * | ||||
|                  * PTB0  - PIN16 | ||||
|                  * PTB1  - PIN17 | ||||
|                  * PTB2  - PIN19 | ||||
|                  * PTB3  - PIN18 | ||||
|                  * PTB16 - PIN0 - UART0_TX | ||||
|                  * PTB17 - PIN1 - UART0_RX | ||||
|                  * PTB18 - PIN32 | ||||
|                  * PTB19 - PIN25 | ||||
|                  */ | ||||
|                 .port = IOPORT2, | ||||
|                 .pads = | ||||
|                     { | ||||
|                         PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_ALTERNATIVE_3, PAL_MODE_ALTERNATIVE_3, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, | ||||
|                     }, | ||||
|             }, | ||||
|             { | ||||
|                 /*
 | ||||
|                  * PORTC setup. | ||||
|                  * | ||||
|                  * PTC0  - PIN15 | ||||
|                  * PTC1  - PIN22 | ||||
|                  * PTC2  - PIN23 | ||||
|                  * PTC3  - PIN9 | ||||
|                  * PTC4  - PIN10 | ||||
|                  * PTC5  - PIN13 | ||||
|                  * PTC6  - PIN11 | ||||
|                  * PTC7  - PIN12 | ||||
|                  * PTC8  - PIN28 | ||||
|                  * PTC9  - PIN27 | ||||
|                  * PTC10 - PIN29 | ||||
|                  * PTC11 - PIN30 | ||||
|                  */ | ||||
|                 .port = IOPORT3, | ||||
|                 .pads = | ||||
|                     { | ||||
|                         PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, | ||||
|                     }, | ||||
|             }, | ||||
|             { | ||||
|                 /*
 | ||||
|                  * PORTD setup. | ||||
|                  * | ||||
|                  * PTD0  - PIN2 | ||||
|                  * PTD1  - PIN14 | ||||
|                  * PTD2  - PIN7 | ||||
|                  * PTD3  - PIN8 | ||||
|                  * PTD4  - PIN6 | ||||
|                  * PTD5  - PIN20 | ||||
|                  * PTD6  - PIN21 | ||||
|                  * PTD7  - PIN5 | ||||
|                  */ | ||||
|                 .port = IOPORT4, | ||||
|                 .pads = | ||||
|                     { | ||||
|                         PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, | ||||
|                     }, | ||||
|             }, | ||||
|             { | ||||
|                 /*
 | ||||
|                  * PORTE setup. | ||||
|                  * | ||||
|                  * PTE0  - PIN31 | ||||
|                  * PTE1  - PIN26 | ||||
|                  */ | ||||
|                 .port = IOPORT5, | ||||
|                 .pads = | ||||
|                     { | ||||
|                         PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_OUTPUT_PUSHPULL, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, PAL_MODE_UNCONNECTED, | ||||
|                     }, | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             /*
 | ||||
|              * PORTB setup. | ||||
|              * | ||||
|              * PTB0  - PIN16 | ||||
|              * PTB1  - PIN17 | ||||
|              * PTB2  - PIN19 | ||||
|              * PTB3  - PIN18 | ||||
|              * PTB16 - PIN0 - UART0_TX | ||||
|              * PTB17 - PIN1 - UART0_RX | ||||
|              * PTB18 - PIN32 | ||||
|              * PTB19 - PIN25 | ||||
|              */ | ||||
|             .port = IOPORT2, | ||||
|             .pads = { | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_ALTERNATIVE_3,     PAL_MODE_ALTERNATIVE_3, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             /*
 | ||||
|              * PORTC setup. | ||||
|              * | ||||
|              * PTC0  - PIN15 | ||||
|              * PTC1  - PIN22 | ||||
|              * PTC2  - PIN23 | ||||
|              * PTC3  - PIN9 | ||||
|              * PTC4  - PIN10 | ||||
|              * PTC5  - PIN13 | ||||
|              * PTC6  - PIN11 | ||||
|              * PTC7  - PIN12 | ||||
|              * PTC8  - PIN28 | ||||
|              * PTC9  - PIN27 | ||||
|              * PTC10 - PIN29 | ||||
|              * PTC11 - PIN30 | ||||
|              */ | ||||
|             .port = IOPORT3, | ||||
|             .pads = { | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             /*
 | ||||
|              * PORTD setup. | ||||
|              * | ||||
|              * PTD0  - PIN2 | ||||
|              * PTD1  - PIN14 | ||||
|              * PTD2  - PIN7 | ||||
|              * PTD3  - PIN8 | ||||
|              * PTD4  - PIN6 | ||||
|              * PTD5  - PIN20 | ||||
|              * PTD6  - PIN21 | ||||
|              * PTD7  - PIN5 | ||||
|              */ | ||||
|             .port = IOPORT4, | ||||
|             .pads = { | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL, | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             /*
 | ||||
|              * PORTE setup. | ||||
|              * | ||||
|              * PTE0  - PIN31 | ||||
|              * PTE1  - PIN26 | ||||
|              */ | ||||
|             .port = IOPORT5, | ||||
|             .pads = { | ||||
|                 PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_OUTPUT_PUSHPULL,   PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|                 PAL_MODE_UNCONNECTED,       PAL_MODE_UNCONNECTED, | ||||
|             }, | ||||
|         }, | ||||
|     }, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| // NOTE: This value comes from kiibohd/controller and is the location of a value
 | ||||
| // which needs to be checked before disabling the watchdog (which happens in
 | ||||
| // k20x_clock_init)
 | ||||
| #define WDOG_TMROUTL            *(volatile uint16_t *)0x40052012 | ||||
| #define WDOG_TMROUTL *(volatile uint16_t *)0x40052012 | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief   Early initialization code. | ||||
|  | @ -176,16 +131,16 @@ const PALConfig pal_default_config = | |||
|  *          and before any other initialization. | ||||
|  */ | ||||
| void __early_init(void) { | ||||
|   // This is a dirty hack and should only be used as a temporary fix until this
 | ||||
|   // is upstreamed.
 | ||||
|   while (WDOG_TMROUTL < 2); // Must wait for WDOG timer if already running, before jumping
 | ||||
|     // This is a dirty hack and should only be used as a temporary fix until this
 | ||||
|     // is upstreamed.
 | ||||
|     while (WDOG_TMROUTL < 2) | ||||
|         ;  // Must wait for WDOG timer if already running, before jumping
 | ||||
| 
 | ||||
|   k20x_clock_init(); | ||||
|     k20x_clock_init(); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief   Board-specific initialization code. | ||||
|  * @todo    Add your board-specific code, if any. | ||||
|  */ | ||||
| void boardInit(void) { | ||||
| } | ||||
| void boardInit(void) {} | ||||
|  |  | |||
|  | @ -25,13 +25,13 @@ | |||
|  * Board identifier. | ||||
|  */ | ||||
| #define BOARD_PJRC_TEENSY_3_1 | ||||
| #define BOARD_NAME                  "PJRC Teensy 3.1" | ||||
| #define BOARD_NAME "PJRC Teensy 3.1" | ||||
| 
 | ||||
| /* External 16 MHz crystal */ | ||||
| #define KINETIS_XTAL_FREQUENCY      16000000UL | ||||
| #define KINETIS_XTAL_FREQUENCY 16000000UL | ||||
| 
 | ||||
| /* Use internal capacitors for the crystal */ | ||||
| #define KINETIS_BOARD_OSCILLATOR_SETTING OSC_CR_SC8P|OSC_CR_SC2P | ||||
| #define KINETIS_BOARD_OSCILLATOR_SETTING OSC_CR_SC8P | OSC_CR_SC2P | ||||
| 
 | ||||
| /*
 | ||||
|  * MCU type | ||||
|  | @ -41,79 +41,79 @@ | |||
| /*
 | ||||
|  * IO pins assignments. | ||||
|  */ | ||||
| #define PORTA_PIN0                  0 | ||||
| #define PORTA_PIN1                  1 | ||||
| #define PORTA_PIN2                  2 | ||||
| #define PORTA_PIN3                  3 | ||||
| #define TEENSY_PIN33                4 | ||||
| #define TEENSY_PIN24                5 | ||||
| #define PORTA_PIN6                  6 | ||||
| #define PORTA_PIN7                  7 | ||||
| #define PORTA_PIN8                  8 | ||||
| #define PORTA_PIN9                  9 | ||||
| #define PORTA_PIN10                 10 | ||||
| #define PORTA_PIN11                 11 | ||||
| #define TEENSY_PIN3                 12 | ||||
| #define TEENSY_PIN4                 13 | ||||
| #define PORTA_PIN14                 14 | ||||
| #define PORTA_PIN15                 15 | ||||
| #define PORTA_PIN16                 16 | ||||
| #define PORTA_PIN17                 17 | ||||
| #define PORTA_PIN18                 18 | ||||
| #define PORTA_PIN19                 19 | ||||
| #define PORTA_PIN20                 20 | ||||
| #define PORTA_PIN21                 21 | ||||
| #define PORTA_PIN22                 22 | ||||
| #define PORTA_PIN23                 23 | ||||
| #define PORTA_PIN24                 24 | ||||
| #define PORTA_PIN25                 25 | ||||
| #define PORTA_PIN26                 26 | ||||
| #define PORTA_PIN27                 27 | ||||
| #define PORTA_PIN28                 28 | ||||
| #define PORTA_PIN29                 29 | ||||
| #define PORTA_PIN30                 30 | ||||
| #define PORTA_PIN31                 31 | ||||
| #define PORTA_PIN0 0 | ||||
| #define PORTA_PIN1 1 | ||||
| #define PORTA_PIN2 2 | ||||
| #define PORTA_PIN3 3 | ||||
| #define TEENSY_PIN33 4 | ||||
| #define TEENSY_PIN24 5 | ||||
| #define PORTA_PIN6 6 | ||||
| #define PORTA_PIN7 7 | ||||
| #define PORTA_PIN8 8 | ||||
| #define PORTA_PIN9 9 | ||||
| #define PORTA_PIN10 10 | ||||
| #define PORTA_PIN11 11 | ||||
| #define TEENSY_PIN3 12 | ||||
| #define TEENSY_PIN4 13 | ||||
| #define PORTA_PIN14 14 | ||||
| #define PORTA_PIN15 15 | ||||
| #define PORTA_PIN16 16 | ||||
| #define PORTA_PIN17 17 | ||||
| #define PORTA_PIN18 18 | ||||
| #define PORTA_PIN19 19 | ||||
| #define PORTA_PIN20 20 | ||||
| #define PORTA_PIN21 21 | ||||
| #define PORTA_PIN22 22 | ||||
| #define PORTA_PIN23 23 | ||||
| #define PORTA_PIN24 24 | ||||
| #define PORTA_PIN25 25 | ||||
| #define PORTA_PIN26 26 | ||||
| #define PORTA_PIN27 27 | ||||
| #define PORTA_PIN28 28 | ||||
| #define PORTA_PIN29 29 | ||||
| #define PORTA_PIN30 30 | ||||
| #define PORTA_PIN31 31 | ||||
| 
 | ||||
| #define TEENSY_PIN3_IOPORT  IOPORT1 | ||||
| #define TEENSY_PIN4_IOPORT  IOPORT1 | ||||
| #define TEENSY_PIN3_IOPORT IOPORT1 | ||||
| #define TEENSY_PIN4_IOPORT IOPORT1 | ||||
| #define TEENSY_PIN24_IOPORT IOPORT1 | ||||
| #define TEENSY_PIN33_IOPORT IOPORT1 | ||||
| 
 | ||||
| #define TEENSY_PIN16                0 | ||||
| #define TEENSY_PIN17                1 | ||||
| #define TEENSY_PIN19                2 | ||||
| #define TEENSY_PIN18                3 | ||||
| #define PORTB_PIN4                  4 | ||||
| #define PORTB_PIN5                  5 | ||||
| #define PORTB_PIN6                  6 | ||||
| #define PORTB_PIN7                  7 | ||||
| #define PORTB_PIN8                  8 | ||||
| #define PORTB_PIN9                  9 | ||||
| #define PORTB_PIN10                 10 | ||||
| #define PORTB_PIN11                 11 | ||||
| #define PORTB_PIN12                 12 | ||||
| #define PORTB_PIN13                 13 | ||||
| #define PORTB_PIN14                 14 | ||||
| #define PORTB_PIN15                 15 | ||||
| #define TEENSY_PIN0                 16 | ||||
| #define TEENSY_PIN1                 17 | ||||
| #define TEENSY_PIN32                18 | ||||
| #define TEENSY_PIN25                19 | ||||
| #define PORTB_PIN20                 20 | ||||
| #define PORTB_PIN21                 21 | ||||
| #define PORTB_PIN22                 22 | ||||
| #define PORTB_PIN23                 23 | ||||
| #define PORTB_PIN24                 24 | ||||
| #define PORTB_PIN25                 25 | ||||
| #define PORTB_PIN26                 26 | ||||
| #define PORTB_PIN27                 27 | ||||
| #define PORTB_PIN28                 28 | ||||
| #define PORTB_PIN29                 29 | ||||
| #define PORTB_PIN30                 30 | ||||
| #define PORTB_PIN31                 31 | ||||
| #define TEENSY_PIN16 0 | ||||
| #define TEENSY_PIN17 1 | ||||
| #define TEENSY_PIN19 2 | ||||
| #define TEENSY_PIN18 3 | ||||
| #define PORTB_PIN4 4 | ||||
| #define PORTB_PIN5 5 | ||||
| #define PORTB_PIN6 6 | ||||
| #define PORTB_PIN7 7 | ||||
| #define PORTB_PIN8 8 | ||||
| #define PORTB_PIN9 9 | ||||
| #define PORTB_PIN10 10 | ||||
| #define PORTB_PIN11 11 | ||||
| #define PORTB_PIN12 12 | ||||
| #define PORTB_PIN13 13 | ||||
| #define PORTB_PIN14 14 | ||||
| #define PORTB_PIN15 15 | ||||
| #define TEENSY_PIN0 16 | ||||
| #define TEENSY_PIN1 17 | ||||
| #define TEENSY_PIN32 18 | ||||
| #define TEENSY_PIN25 19 | ||||
| #define PORTB_PIN20 20 | ||||
| #define PORTB_PIN21 21 | ||||
| #define PORTB_PIN22 22 | ||||
| #define PORTB_PIN23 23 | ||||
| #define PORTB_PIN24 24 | ||||
| #define PORTB_PIN25 25 | ||||
| #define PORTB_PIN26 26 | ||||
| #define PORTB_PIN27 27 | ||||
| #define PORTB_PIN28 28 | ||||
| #define PORTB_PIN29 29 | ||||
| #define PORTB_PIN30 30 | ||||
| #define PORTB_PIN31 31 | ||||
| 
 | ||||
| #define TEENSY_PIN0_IOPORT  IOPORT2 | ||||
| #define TEENSY_PIN1_IOPORT  IOPORT2 | ||||
| #define TEENSY_PIN0_IOPORT IOPORT2 | ||||
| #define TEENSY_PIN1_IOPORT IOPORT2 | ||||
| #define TEENSY_PIN16_IOPORT IOPORT2 | ||||
| #define TEENSY_PIN17_IOPORT IOPORT2 | ||||
| #define TEENSY_PIN18_IOPORT IOPORT2 | ||||
|  | @ -121,40 +121,40 @@ | |||
| #define TEENSY_PIN25_IOPORT IOPORT2 | ||||
| #define TEENSY_PIN32_IOPORT IOPORT2 | ||||
| 
 | ||||
| #define TEENSY_PIN15                0 | ||||
| #define TEENSY_PIN22                1 | ||||
| #define TEENSY_PIN23                2 | ||||
| #define TEENSY_PIN9                 3 | ||||
| #define TEENSY_PIN10                4 | ||||
| #define TEENSY_PIN13                5 | ||||
| #define TEENSY_PIN11                6 | ||||
| #define TEENSY_PIN12                7 | ||||
| #define TEENSY_PIN28                8 | ||||
| #define TEENSY_PIN27                9 | ||||
| #define TEENSY_PIN29                10 | ||||
| #define TEENSY_PIN30                11 | ||||
| #define PORTC_PIN12                 12 | ||||
| #define PORTC_PIN13                 13 | ||||
| #define PORTC_PIN14                 14 | ||||
| #define PORTC_PIN15                 15 | ||||
| #define PORTC_PIN16                 16 | ||||
| #define PORTC_PIN17                 17 | ||||
| #define PORTC_PIN18                 18 | ||||
| #define PORTC_PIN19                 19 | ||||
| #define PORTC_PIN20                 20 | ||||
| #define PORTC_PIN21                 21 | ||||
| #define PORTC_PIN22                 22 | ||||
| #define PORTC_PIN23                 23 | ||||
| #define PORTC_PIN24                 24 | ||||
| #define PORTC_PIN25                 25 | ||||
| #define PORTC_PIN26                 26 | ||||
| #define PORTC_PIN27                 27 | ||||
| #define PORTC_PIN28                 28 | ||||
| #define PORTC_PIN29                 29 | ||||
| #define PORTC_PIN30                 30 | ||||
| #define PORTC_PIN31                 31 | ||||
| #define TEENSY_PIN15 0 | ||||
| #define TEENSY_PIN22 1 | ||||
| #define TEENSY_PIN23 2 | ||||
| #define TEENSY_PIN9 3 | ||||
| #define TEENSY_PIN10 4 | ||||
| #define TEENSY_PIN13 5 | ||||
| #define TEENSY_PIN11 6 | ||||
| #define TEENSY_PIN12 7 | ||||
| #define TEENSY_PIN28 8 | ||||
| #define TEENSY_PIN27 9 | ||||
| #define TEENSY_PIN29 10 | ||||
| #define TEENSY_PIN30 11 | ||||
| #define PORTC_PIN12 12 | ||||
| #define PORTC_PIN13 13 | ||||
| #define PORTC_PIN14 14 | ||||
| #define PORTC_PIN15 15 | ||||
| #define PORTC_PIN16 16 | ||||
| #define PORTC_PIN17 17 | ||||
| #define PORTC_PIN18 18 | ||||
| #define PORTC_PIN19 19 | ||||
| #define PORTC_PIN20 20 | ||||
| #define PORTC_PIN21 21 | ||||
| #define PORTC_PIN22 22 | ||||
| #define PORTC_PIN23 23 | ||||
| #define PORTC_PIN24 24 | ||||
| #define PORTC_PIN25 25 | ||||
| #define PORTC_PIN26 26 | ||||
| #define PORTC_PIN27 27 | ||||
| #define PORTC_PIN28 28 | ||||
| #define PORTC_PIN29 29 | ||||
| #define PORTC_PIN30 30 | ||||
| #define PORTC_PIN31 31 | ||||
| 
 | ||||
| #define TEENSY_PIN9_IOPORT  IOPORT3 | ||||
| #define TEENSY_PIN9_IOPORT IOPORT3 | ||||
| #define TEENSY_PIN10_IOPORT IOPORT3 | ||||
| #define TEENSY_PIN11_IOPORT IOPORT3 | ||||
| #define TEENSY_PIN12_IOPORT IOPORT3 | ||||
|  | @ -167,129 +167,129 @@ | |||
| #define TEENSY_PIN29_IOPORT IOPORT3 | ||||
| #define TEENSY_PIN30_IOPORT IOPORT3 | ||||
| 
 | ||||
| #define TEENSY_PIN2                 0 | ||||
| #define TEENSY_PIN14                1 | ||||
| #define TEENSY_PIN7                 2 | ||||
| #define TEENSY_PIN8                 3 | ||||
| #define TEENSY_PIN6                 4 | ||||
| #define TEENSY_PIN20                5 | ||||
| #define TEENSY_PIN21                6 | ||||
| #define TEENSY_PIN5                 7 | ||||
| #define PORTD_PIN8                  8 | ||||
| #define PORTD_PIN9                  9 | ||||
| #define PORTD_PIN10                 10 | ||||
| #define PORTD_PIN11                 11 | ||||
| #define PORTD_PIN12                 12 | ||||
| #define PORTD_PIN13                 13 | ||||
| #define PORTD_PIN14                 14 | ||||
| #define PORTD_PIN15                 15 | ||||
| #define PORTD_PIN16                 16 | ||||
| #define PORTD_PIN17                 17 | ||||
| #define PORTD_PIN18                 18 | ||||
| #define PORTD_PIN19                 19 | ||||
| #define PORTD_PIN20                 20 | ||||
| #define PORTD_PIN21                 21 | ||||
| #define PORTD_PIN22                 22 | ||||
| #define PORTD_PIN23                 23 | ||||
| #define PORTD_PIN24                 24 | ||||
| #define PORTD_PIN25                 25 | ||||
| #define PORTD_PIN26                 26 | ||||
| #define PORTD_PIN27                 27 | ||||
| #define PORTD_PIN28                 28 | ||||
| #define PORTD_PIN29                 29 | ||||
| #define PORTD_PIN30                 30 | ||||
| #define PORTD_PIN31                 31 | ||||
| #define TEENSY_PIN2 0 | ||||
| #define TEENSY_PIN14 1 | ||||
| #define TEENSY_PIN7 2 | ||||
| #define TEENSY_PIN8 3 | ||||
| #define TEENSY_PIN6 4 | ||||
| #define TEENSY_PIN20 5 | ||||
| #define TEENSY_PIN21 6 | ||||
| #define TEENSY_PIN5 7 | ||||
| #define PORTD_PIN8 8 | ||||
| #define PORTD_PIN9 9 | ||||
| #define PORTD_PIN10 10 | ||||
| #define PORTD_PIN11 11 | ||||
| #define PORTD_PIN12 12 | ||||
| #define PORTD_PIN13 13 | ||||
| #define PORTD_PIN14 14 | ||||
| #define PORTD_PIN15 15 | ||||
| #define PORTD_PIN16 16 | ||||
| #define PORTD_PIN17 17 | ||||
| #define PORTD_PIN18 18 | ||||
| #define PORTD_PIN19 19 | ||||
| #define PORTD_PIN20 20 | ||||
| #define PORTD_PIN21 21 | ||||
| #define PORTD_PIN22 22 | ||||
| #define PORTD_PIN23 23 | ||||
| #define PORTD_PIN24 24 | ||||
| #define PORTD_PIN25 25 | ||||
| #define PORTD_PIN26 26 | ||||
| #define PORTD_PIN27 27 | ||||
| #define PORTD_PIN28 28 | ||||
| #define PORTD_PIN29 29 | ||||
| #define PORTD_PIN30 30 | ||||
| #define PORTD_PIN31 31 | ||||
| 
 | ||||
| #define TEENSY_PIN2_IOPORT  IOPORT4 | ||||
| #define TEENSY_PIN5_IOPORT  IOPORT4 | ||||
| #define TEENSY_PIN6_IOPORT  IOPORT4 | ||||
| #define TEENSY_PIN7_IOPORT  IOPORT4 | ||||
| #define TEENSY_PIN8_IOPORT  IOPORT4 | ||||
| #define TEENSY_PIN2_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN5_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN6_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN7_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN8_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN14_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN20_IOPORT IOPORT4 | ||||
| #define TEENSY_PIN21_IOPORT IOPORT4 | ||||
| 
 | ||||
| #define TEENSY_PIN31                0 | ||||
| #define TEENSY_PIN26                1 | ||||
| #define PORTE_PIN2                  2 | ||||
| #define PORTE_PIN3                  3 | ||||
| #define PORTE_PIN4                  4 | ||||
| #define PORTE_PIN5                  5 | ||||
| #define PORTE_PIN6                  6 | ||||
| #define PORTE_PIN7                  7 | ||||
| #define PORTE_PIN8                  8 | ||||
| #define PORTE_PIN9                  9 | ||||
| #define PORTE_PIN10                 10 | ||||
| #define PORTE_PIN11                 11 | ||||
| #define PORTE_PIN12                 12 | ||||
| #define PORTE_PIN13                 13 | ||||
| #define PORTE_PIN14                 14 | ||||
| #define PORTE_PIN15                 15 | ||||
| #define PORTE_PIN16                 16 | ||||
| #define PORTE_PIN17                 17 | ||||
| #define PORTE_PIN18                 18 | ||||
| #define PORTE_PIN19                 19 | ||||
| #define PORTE_PIN20                 20 | ||||
| #define PORTE_PIN21                 21 | ||||
| #define PORTE_PIN22                 22 | ||||
| #define PORTE_PIN23                 23 | ||||
| #define PORTE_PIN24                 24 | ||||
| #define PORTE_PIN25                 25 | ||||
| #define PORTE_PIN26                 26 | ||||
| #define PORTE_PIN27                 27 | ||||
| #define PORTE_PIN28                 28 | ||||
| #define PORTE_PIN29                 29 | ||||
| #define PORTE_PIN30                 30 | ||||
| #define PORTE_PIN31                 31 | ||||
| #define TEENSY_PIN31 0 | ||||
| #define TEENSY_PIN26 1 | ||||
| #define PORTE_PIN2 2 | ||||
| #define PORTE_PIN3 3 | ||||
| #define PORTE_PIN4 4 | ||||
| #define PORTE_PIN5 5 | ||||
| #define PORTE_PIN6 6 | ||||
| #define PORTE_PIN7 7 | ||||
| #define PORTE_PIN8 8 | ||||
| #define PORTE_PIN9 9 | ||||
| #define PORTE_PIN10 10 | ||||
| #define PORTE_PIN11 11 | ||||
| #define PORTE_PIN12 12 | ||||
| #define PORTE_PIN13 13 | ||||
| #define PORTE_PIN14 14 | ||||
| #define PORTE_PIN15 15 | ||||
| #define PORTE_PIN16 16 | ||||
| #define PORTE_PIN17 17 | ||||
| #define PORTE_PIN18 18 | ||||
| #define PORTE_PIN19 19 | ||||
| #define PORTE_PIN20 20 | ||||
| #define PORTE_PIN21 21 | ||||
| #define PORTE_PIN22 22 | ||||
| #define PORTE_PIN23 23 | ||||
| #define PORTE_PIN24 24 | ||||
| #define PORTE_PIN25 25 | ||||
| #define PORTE_PIN26 26 | ||||
| #define PORTE_PIN27 27 | ||||
| #define PORTE_PIN28 28 | ||||
| #define PORTE_PIN29 29 | ||||
| #define PORTE_PIN30 30 | ||||
| #define PORTE_PIN31 31 | ||||
| 
 | ||||
| #define TEENSY_PIN26_IOPORT IOPORT5 | ||||
| #define TEENSY_PIN31_IOPORT IOPORT5 | ||||
| 
 | ||||
| #define LINE_PIN1           PAL_LINE(TEENSY_PIN1_IOPORT, TEENSY_PIN1) | ||||
| #define LINE_PIN2           PAL_LINE(TEENSY_PIN2_IOPORT, TEENSY_PIN2) | ||||
| #define LINE_PIN3           PAL_LINE(TEENSY_PIN3_IOPORT, TEENSY_PIN3) | ||||
| #define LINE_PIN4           PAL_LINE(TEENSY_PIN4_IOPORT, TEENSY_PIN4) | ||||
| #define LINE_PIN5           PAL_LINE(TEENSY_PIN5_IOPORT, TEENSY_PIN5) | ||||
| #define LINE_PIN6           PAL_LINE(TEENSY_PIN6_IOPORT, TEENSY_PIN6) | ||||
| #define LINE_PIN7           PAL_LINE(TEENSY_PIN7_IOPORT, TEENSY_PIN7) | ||||
| #define LINE_PIN8           PAL_LINE(TEENSY_PIN8_IOPORT, TEENSY_PIN8) | ||||
| #define LINE_PIN9           PAL_LINE(TEENSY_PIN9_IOPORT, TEENSY_PIN9) | ||||
| #define LINE_PIN10          PAL_LINE(TEENSY_PIN10_IOPORT, TEENSY_PIN10) | ||||
| #define LINE_PIN11          PAL_LINE(TEENSY_PIN11_IOPORT, TEENSY_PIN11) | ||||
| #define LINE_PIN12          PAL_LINE(TEENSY_PIN12_IOPORT, TEENSY_PIN12) | ||||
| #define LINE_PIN13          PAL_LINE(TEENSY_PIN13_IOPORT, TEENSY_PIN13) | ||||
| #define LINE_PIN14          PAL_LINE(TEENSY_PIN14_IOPORT, TEENSY_PIN14) | ||||
| #define LINE_PIN15          PAL_LINE(TEENSY_PIN15_IOPORT, TEENSY_PIN15) | ||||
| #define LINE_PIN16          PAL_LINE(TEENSY_PIN16_IOPORT, TEENSY_PIN16) | ||||
| #define LINE_PIN17          PAL_LINE(TEENSY_PIN17_IOPORT, TEENSY_PIN17) | ||||
| #define LINE_PIN18          PAL_LINE(TEENSY_PIN18_IOPORT, TEENSY_PIN18) | ||||
| #define LINE_PIN19          PAL_LINE(TEENSY_PIN19_IOPORT, TEENSY_PIN19) | ||||
| #define LINE_PIN20          PAL_LINE(TEENSY_PIN20_IOPORT, TEENSY_PIN20) | ||||
| #define LINE_PIN21          PAL_LINE(TEENSY_PIN21_IOPORT, TEENSY_PIN21) | ||||
| #define LINE_PIN22          PAL_LINE(TEENSY_PIN22_IOPORT, TEENSY_PIN22) | ||||
| #define LINE_PIN23          PAL_LINE(TEENSY_PIN23_IOPORT, TEENSY_PIN23) | ||||
| #define LINE_PIN24          PAL_LINE(TEENSY_PIN24_IOPORT, TEENSY_PIN24) | ||||
| #define LINE_PIN25          PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25) | ||||
| #define LINE_PIN25          PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25) | ||||
| #define LINE_PIN26          PAL_LINE(TEENSY_PIN26_IOPORT, TEENSY_PIN26) | ||||
| #define LINE_PIN27          PAL_LINE(TEENSY_PIN27_IOPORT, TEENSY_PIN27) | ||||
| #define LINE_PIN28          PAL_LINE(TEENSY_PIN28_IOPORT, TEENSY_PIN28) | ||||
| #define LINE_PIN29          PAL_LINE(TEENSY_PIN29_IOPORT, TEENSY_PIN29) | ||||
| #define LINE_PIN30          PAL_LINE(TEENSY_PIN30_IOPORT, TEENSY_PIN30) | ||||
| #define LINE_PIN31          PAL_LINE(TEENSY_PIN31_IOPORT, TEENSY_PIN31) | ||||
| #define LINE_PIN32          PAL_LINE(TEENSY_PIN32_IOPORT, TEENSY_PIN32) | ||||
| #define LINE_PIN33          PAL_LINE(TEENSY_PIN33_IOPORT, TEENSY_PIN33) | ||||
| #define LINE_PIN1 PAL_LINE(TEENSY_PIN1_IOPORT, TEENSY_PIN1) | ||||
| #define LINE_PIN2 PAL_LINE(TEENSY_PIN2_IOPORT, TEENSY_PIN2) | ||||
| #define LINE_PIN3 PAL_LINE(TEENSY_PIN3_IOPORT, TEENSY_PIN3) | ||||
| #define LINE_PIN4 PAL_LINE(TEENSY_PIN4_IOPORT, TEENSY_PIN4) | ||||
| #define LINE_PIN5 PAL_LINE(TEENSY_PIN5_IOPORT, TEENSY_PIN5) | ||||
| #define LINE_PIN6 PAL_LINE(TEENSY_PIN6_IOPORT, TEENSY_PIN6) | ||||
| #define LINE_PIN7 PAL_LINE(TEENSY_PIN7_IOPORT, TEENSY_PIN7) | ||||
| #define LINE_PIN8 PAL_LINE(TEENSY_PIN8_IOPORT, TEENSY_PIN8) | ||||
| #define LINE_PIN9 PAL_LINE(TEENSY_PIN9_IOPORT, TEENSY_PIN9) | ||||
| #define LINE_PIN10 PAL_LINE(TEENSY_PIN10_IOPORT, TEENSY_PIN10) | ||||
| #define LINE_PIN11 PAL_LINE(TEENSY_PIN11_IOPORT, TEENSY_PIN11) | ||||
| #define LINE_PIN12 PAL_LINE(TEENSY_PIN12_IOPORT, TEENSY_PIN12) | ||||
| #define LINE_PIN13 PAL_LINE(TEENSY_PIN13_IOPORT, TEENSY_PIN13) | ||||
| #define LINE_PIN14 PAL_LINE(TEENSY_PIN14_IOPORT, TEENSY_PIN14) | ||||
| #define LINE_PIN15 PAL_LINE(TEENSY_PIN15_IOPORT, TEENSY_PIN15) | ||||
| #define LINE_PIN16 PAL_LINE(TEENSY_PIN16_IOPORT, TEENSY_PIN16) | ||||
| #define LINE_PIN17 PAL_LINE(TEENSY_PIN17_IOPORT, TEENSY_PIN17) | ||||
| #define LINE_PIN18 PAL_LINE(TEENSY_PIN18_IOPORT, TEENSY_PIN18) | ||||
| #define LINE_PIN19 PAL_LINE(TEENSY_PIN19_IOPORT, TEENSY_PIN19) | ||||
| #define LINE_PIN20 PAL_LINE(TEENSY_PIN20_IOPORT, TEENSY_PIN20) | ||||
| #define LINE_PIN21 PAL_LINE(TEENSY_PIN21_IOPORT, TEENSY_PIN21) | ||||
| #define LINE_PIN22 PAL_LINE(TEENSY_PIN22_IOPORT, TEENSY_PIN22) | ||||
| #define LINE_PIN23 PAL_LINE(TEENSY_PIN23_IOPORT, TEENSY_PIN23) | ||||
| #define LINE_PIN24 PAL_LINE(TEENSY_PIN24_IOPORT, TEENSY_PIN24) | ||||
| #define LINE_PIN25 PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25) | ||||
| #define LINE_PIN25 PAL_LINE(TEENSY_PIN25_IOPORT, TEENSY_PIN25) | ||||
| #define LINE_PIN26 PAL_LINE(TEENSY_PIN26_IOPORT, TEENSY_PIN26) | ||||
| #define LINE_PIN27 PAL_LINE(TEENSY_PIN27_IOPORT, TEENSY_PIN27) | ||||
| #define LINE_PIN28 PAL_LINE(TEENSY_PIN28_IOPORT, TEENSY_PIN28) | ||||
| #define LINE_PIN29 PAL_LINE(TEENSY_PIN29_IOPORT, TEENSY_PIN29) | ||||
| #define LINE_PIN30 PAL_LINE(TEENSY_PIN30_IOPORT, TEENSY_PIN30) | ||||
| #define LINE_PIN31 PAL_LINE(TEENSY_PIN31_IOPORT, TEENSY_PIN31) | ||||
| #define LINE_PIN32 PAL_LINE(TEENSY_PIN32_IOPORT, TEENSY_PIN32) | ||||
| #define LINE_PIN33 PAL_LINE(TEENSY_PIN33_IOPORT, TEENSY_PIN33) | ||||
| 
 | ||||
| #define LINE_LED            LINE_PIN13 | ||||
| #define LINE_LED LINE_PIN13 | ||||
| 
 | ||||
| #if !defined(_FROM_ASM_) | ||||
| #ifdef __cplusplus | ||||
| #    ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|   void boardInit(void); | ||||
| #ifdef __cplusplus | ||||
| #    endif | ||||
| void boardInit(void); | ||||
| #    ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| #    endif | ||||
| #endif /* _FROM_ASM_ */ | ||||
| 
 | ||||
| #endif /* _BOARD_H_ */ | ||||
|  |  | |||
|  | @ -22,57 +22,57 @@ | |||
| #define TIMEOUT 100 | ||||
| 
 | ||||
| enum { | ||||
|   CMD_INPUT_0 = 0, | ||||
|   CMD_INPUT_1, | ||||
|   CMD_OUTPUT_0, | ||||
|   CMD_OUTPUT_1, | ||||
|   CMD_INVERSION_0, | ||||
|   CMD_INVERSION_1, | ||||
|   CMD_CONFIG_0, | ||||
|   CMD_CONFIG_1, | ||||
|     CMD_INPUT_0 = 0, | ||||
|     CMD_INPUT_1, | ||||
|     CMD_OUTPUT_0, | ||||
|     CMD_OUTPUT_1, | ||||
|     CMD_INVERSION_0, | ||||
|     CMD_INVERSION_1, | ||||
|     CMD_CONFIG_0, | ||||
|     CMD_CONFIG_1, | ||||
| }; | ||||
| 
 | ||||
| void pca9555_init(uint8_t slave_addr) { | ||||
|   static uint8_t s_init = 0; | ||||
|   if (!s_init) { | ||||
|     i2c_init(); | ||||
|     static uint8_t s_init = 0; | ||||
|     if (!s_init) { | ||||
|         i2c_init(); | ||||
| 
 | ||||
|     s_init = 1; | ||||
|   } | ||||
|         s_init = 1; | ||||
|     } | ||||
| 
 | ||||
|   // TODO: could check device connected
 | ||||
|   // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE);
 | ||||
|   // i2c_stop();
 | ||||
|     // TODO: could check device connected
 | ||||
|     // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE);
 | ||||
|     // i2c_stop();
 | ||||
| } | ||||
| 
 | ||||
| void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { | ||||
|   uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|   uint8_t cmd  = port ? CMD_CONFIG_1 : CMD_CONFIG_0; | ||||
|     uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|     uint8_t cmd  = port ? CMD_CONFIG_1 : CMD_CONFIG_0; | ||||
| 
 | ||||
|   i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); | ||||
|   if (ret != I2C_STATUS_SUCCESS) { | ||||
|     print("pca9555_set_config::FAILED\n"); | ||||
|   } | ||||
|     i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); | ||||
|     if (ret != I2C_STATUS_SUCCESS) { | ||||
|         print("pca9555_set_config::FAILED\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { | ||||
|   uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|   uint8_t cmd  = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; | ||||
|     uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|     uint8_t cmd  = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; | ||||
| 
 | ||||
|   i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); | ||||
|   if (ret != I2C_STATUS_SUCCESS) { | ||||
|     print("pca9555_set_output::FAILED\n"); | ||||
|   } | ||||
|     i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); | ||||
|     if (ret != I2C_STATUS_SUCCESS) { | ||||
|         print("pca9555_set_output::FAILED\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { | ||||
|   uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|   uint8_t cmd  = port ? CMD_INPUT_1 : CMD_INPUT_0; | ||||
|     uint8_t addr = SLAVE_TO_ADDR(slave_addr); | ||||
|     uint8_t cmd  = port ? CMD_INPUT_1 : CMD_INPUT_0; | ||||
| 
 | ||||
|   uint8_t      data = 0; | ||||
|   i2c_status_t ret  = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); | ||||
|   if (ret != I2C_STATUS_SUCCESS) { | ||||
|     print("pca9555_readPins::FAILED\n"); | ||||
|   } | ||||
|   return data; | ||||
|     uint8_t      data = 0; | ||||
|     i2c_status_t ret  = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); | ||||
|     if (ret != I2C_STATUS_SUCCESS) { | ||||
|         print("pca9555_readPins::FAILED\n"); | ||||
|     } | ||||
|     return data; | ||||
| } | ||||
|  |  | |||
|  | @ -20,110 +20,102 @@ | |||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| 
 | ||||
| uint8_t DRV2605L_transfer_buffer[2]; | ||||
| uint8_t DRV2605L_tx_register[0]; | ||||
| uint8_t DRV2605L_read_buffer[0]; | ||||
| uint8_t DRV2605L_read_register; | ||||
| 
 | ||||
| 
 | ||||
| void DRV_write(uint8_t drv_register, uint8_t settings) { | ||||
|   DRV2605L_transfer_buffer[0] = drv_register; | ||||
|   DRV2605L_transfer_buffer[1] = settings; | ||||
|   i2c_transmit(DRV2605L_BASE_ADDRESS << 1, DRV2605L_transfer_buffer, 2, 100); | ||||
|     DRV2605L_transfer_buffer[0] = drv_register; | ||||
|     DRV2605L_transfer_buffer[1] = settings; | ||||
|     i2c_transmit(DRV2605L_BASE_ADDRESS << 1, DRV2605L_transfer_buffer, 2, 100); | ||||
| } | ||||
| 
 | ||||
| uint8_t DRV_read(uint8_t regaddress) { | ||||
| #ifdef __AVR__ | ||||
|   i2c_readReg(DRV2605L_BASE_ADDRESS << 1, | ||||
|     regaddress, DRV2605L_read_buffer, 1, 100); | ||||
|   DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0]; | ||||
|     i2c_readReg(DRV2605L_BASE_ADDRESS << 1, regaddress, DRV2605L_read_buffer, 1, 100); | ||||
|     DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0]; | ||||
| #else | ||||
|   DRV2605L_tx_register[0] = regaddress; | ||||
|   if (MSG_OK != i2c_transmit_receive(DRV2605L_BASE_ADDRESS << 1, | ||||
|     DRV2605L_tx_register, 1, | ||||
|     DRV2605L_read_buffer, 1 | ||||
| )){ | ||||
|     printf("err reading reg \n"); | ||||
|   } | ||||
|   DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0]; | ||||
|     DRV2605L_tx_register[0] = regaddress; | ||||
|     if (MSG_OK != i2c_transmit_receive(DRV2605L_BASE_ADDRESS << 1, DRV2605L_tx_register, 1, DRV2605L_read_buffer, 1)) { | ||||
|         printf("err reading reg \n"); | ||||
|     } | ||||
|     DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0]; | ||||
| #endif | ||||
| return DRV2605L_read_register; | ||||
|     return DRV2605L_read_register; | ||||
| } | ||||
| 
 | ||||
| void DRV_init(void) | ||||
| { | ||||
|   i2c_init(); | ||||
|   /* 0x07 sets DRV2605 into calibration mode */ | ||||
|   DRV_write(DRV_MODE,0x07);  | ||||
| void DRV_init(void) { | ||||
|     i2c_init(); | ||||
|     /* 0x07 sets DRV2605 into calibration mode */ | ||||
|     DRV_write(DRV_MODE, 0x07); | ||||
| 
 | ||||
| //  DRV_write(DRV_FEEDBACK_CTRL,0xB6);
 | ||||
|      | ||||
|   #if FB_ERM_LRA == 0 | ||||
|     //  DRV_write(DRV_FEEDBACK_CTRL,0xB6);
 | ||||
| 
 | ||||
| #if FB_ERM_LRA == 0 | ||||
|     /* ERM settings */ | ||||
|   DRV_write(DRV_RATED_VOLT, (RATED_VOLTAGE/21.33)*1000); | ||||
|   #if ERM_OPEN_LOOP == 0 | ||||
|   DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (((V_PEAK*(DRIVE_TIME+BLANKING_TIME+IDISS_TIME))/0.02133)/(DRIVE_TIME-0.0003)));  | ||||
|   #elif ERM_OPEN_LOOP == 1 | ||||
|   DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196)); | ||||
|   #endif | ||||
|   #elif FB_ERM_LRA == 1 | ||||
|   DRV_write(DRV_RATED_VOLT, ((V_RMS * sqrt(1 - ((4 * ((150+(SAMPLE_TIME*50))*0.000001)) + 0.0003)* F_LRA)/0.02071))); | ||||
|   #if LRA_OPEN_LOOP == 0 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, ((V_PEAK/sqrt(1-(F_LRA*0.0008))/0.02133))); | ||||
|   #elif LRA_OPEN_LOOP == 1 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196)); | ||||
|   #endif | ||||
|   #endif | ||||
|        | ||||
|   DRVREG_FBR FB_SET; | ||||
|     FB_SET.Bits.ERM_LRA = FB_ERM_LRA; | ||||
|     DRV_write(DRV_RATED_VOLT, (RATED_VOLTAGE / 21.33) * 1000); | ||||
| #    if ERM_OPEN_LOOP == 0 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (((V_PEAK * (DRIVE_TIME + BLANKING_TIME + IDISS_TIME)) / 0.02133) / (DRIVE_TIME - 0.0003))); | ||||
| #    elif ERM_OPEN_LOOP == 1 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK / 0.02196)); | ||||
| #    endif | ||||
| #elif FB_ERM_LRA == 1 | ||||
|     DRV_write(DRV_RATED_VOLT, ((V_RMS * sqrt(1 - ((4 * ((150 + (SAMPLE_TIME * 50)) * 0.000001)) + 0.0003) * F_LRA) / 0.02071))); | ||||
| #    if LRA_OPEN_LOOP == 0 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, ((V_PEAK / sqrt(1 - (F_LRA * 0.0008)) / 0.02133))); | ||||
| #    elif LRA_OPEN_LOOP == 1 | ||||
|     DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK / 0.02196)); | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
|     DRVREG_FBR FB_SET; | ||||
|     FB_SET.Bits.ERM_LRA      = FB_ERM_LRA; | ||||
|     FB_SET.Bits.BRAKE_FACTOR = FB_BRAKEFACTOR; | ||||
|     FB_SET.Bits.LOOP_GAIN =FB_LOOPGAIN; | ||||
|     FB_SET.Bits.BEMF_GAIN = 0; /* auto-calibration populates this field*/ | ||||
|     DRV_write(DRV_FEEDBACK_CTRL, (uint8_t) FB_SET.Byte); | ||||
|   DRVREG_CTRL1 C1_SET; | ||||
|     C1_SET.Bits.C1_DRIVE_TIME = DRIVE_TIME; | ||||
|     C1_SET.Bits.C1_AC_COUPLE = AC_COUPLE; | ||||
|     FB_SET.Bits.LOOP_GAIN    = FB_LOOPGAIN; | ||||
|     FB_SET.Bits.BEMF_GAIN    = 0; /* auto-calibration populates this field*/ | ||||
|     DRV_write(DRV_FEEDBACK_CTRL, (uint8_t)FB_SET.Byte); | ||||
|     DRVREG_CTRL1 C1_SET; | ||||
|     C1_SET.Bits.C1_DRIVE_TIME    = DRIVE_TIME; | ||||
|     C1_SET.Bits.C1_AC_COUPLE     = AC_COUPLE; | ||||
|     C1_SET.Bits.C1_STARTUP_BOOST = STARTUP_BOOST; | ||||
|     DRV_write(DRV_CTRL_1, (uint8_t) C1_SET.Byte); | ||||
|   DRVREG_CTRL2 C2_SET; | ||||
|     C2_SET.Bits.C2_BIDIR_INPUT = BIDIR_INPUT; | ||||
|     C2_SET.Bits.C2_BRAKE_STAB = BRAKE_STAB; | ||||
|     C2_SET.Bits.C2_SAMPLE_TIME = SAMPLE_TIME; | ||||
|     DRV_write(DRV_CTRL_1, (uint8_t)C1_SET.Byte); | ||||
|     DRVREG_CTRL2 C2_SET; | ||||
|     C2_SET.Bits.C2_BIDIR_INPUT   = BIDIR_INPUT; | ||||
|     C2_SET.Bits.C2_BRAKE_STAB    = BRAKE_STAB; | ||||
|     C2_SET.Bits.C2_SAMPLE_TIME   = SAMPLE_TIME; | ||||
|     C2_SET.Bits.C2_BLANKING_TIME = BLANKING_TIME; | ||||
|     C2_SET.Bits.C2_IDISS_TIME = IDISS_TIME; | ||||
|     DRV_write(DRV_CTRL_2, (uint8_t) C2_SET.Byte); | ||||
|   DRVREG_CTRL3 C3_SET; | ||||
|     C3_SET.Bits.C3_LRA_OPEN_LOOP = LRA_OPEN_LOOP; | ||||
|     C3_SET.Bits.C3_N_PWM_ANALOG = N_PWM_ANALOG; | ||||
|     C3_SET.Bits.C3_LRA_DRIVE_MODE = LRA_DRIVE_MODE; | ||||
|     C2_SET.Bits.C2_IDISS_TIME    = IDISS_TIME; | ||||
|     DRV_write(DRV_CTRL_2, (uint8_t)C2_SET.Byte); | ||||
|     DRVREG_CTRL3 C3_SET; | ||||
|     C3_SET.Bits.C3_LRA_OPEN_LOOP   = LRA_OPEN_LOOP; | ||||
|     C3_SET.Bits.C3_N_PWM_ANALOG    = N_PWM_ANALOG; | ||||
|     C3_SET.Bits.C3_LRA_DRIVE_MODE  = LRA_DRIVE_MODE; | ||||
|     C3_SET.Bits.C3_DATA_FORMAT_RTO = DATA_FORMAT_RTO; | ||||
|     C3_SET.Bits.C3_SUPPLY_COMP_DIS = SUPPLY_COMP_DIS; | ||||
|     C3_SET.Bits.C3_ERM_OPEN_LOOP = ERM_OPEN_LOOP; | ||||
|     C3_SET.Bits.C3_NG_THRESH = NG_THRESH; | ||||
|     DRV_write(DRV_CTRL_3, (uint8_t) C3_SET.Byte); | ||||
|   DRVREG_CTRL4 C4_SET; | ||||
|     C4_SET.Bits.C4_ZC_DET_TIME = ZC_DET_TIME; | ||||
|     C3_SET.Bits.C3_ERM_OPEN_LOOP   = ERM_OPEN_LOOP; | ||||
|     C3_SET.Bits.C3_NG_THRESH       = NG_THRESH; | ||||
|     DRV_write(DRV_CTRL_3, (uint8_t)C3_SET.Byte); | ||||
|     DRVREG_CTRL4 C4_SET; | ||||
|     C4_SET.Bits.C4_ZC_DET_TIME   = ZC_DET_TIME; | ||||
|     C4_SET.Bits.C4_AUTO_CAL_TIME = AUTO_CAL_TIME; | ||||
|     DRV_write(DRV_CTRL_4, (uint8_t) C4_SET.Byte); | ||||
|   DRV_write(DRV_LIB_SELECTION,LIB_SELECTION); | ||||
|     DRV_write(DRV_CTRL_4, (uint8_t)C4_SET.Byte); | ||||
|     DRV_write(DRV_LIB_SELECTION, LIB_SELECTION); | ||||
| 
 | ||||
|   DRV_write(DRV_GO, 0x01); | ||||
|     DRV_write(DRV_GO, 0x01); | ||||
| 
 | ||||
|   /* 0x00 sets DRV2605 out of standby and to use internal trigger
 | ||||
|    * 0x01 sets DRV2605 out of standby and to use external trigger */ | ||||
|   DRV_write(DRV_MODE,0x00);  | ||||
|     /* 0x00 sets DRV2605 out of standby and to use internal trigger
 | ||||
|      * 0x01 sets DRV2605 out of standby and to use external trigger */ | ||||
|     DRV_write(DRV_MODE, 0x00); | ||||
| 
 | ||||
| //Play greeting sequence
 | ||||
|   DRV_write(DRV_GO, 0x00); | ||||
|   DRV_write(DRV_WAVEFORM_SEQ_1, DRV_GREETING); | ||||
|   DRV_write(DRV_GO, 0x01); | ||||
|     // Play greeting sequence
 | ||||
|     DRV_write(DRV_GO, 0x00); | ||||
|     DRV_write(DRV_WAVEFORM_SEQ_1, DRV_GREETING); | ||||
|     DRV_write(DRV_GO, 0x01); | ||||
| } | ||||
| 
 | ||||
| void DRV_pulse(uint8_t sequence) | ||||
| { | ||||
|   DRV_write(DRV_GO, 0x00); | ||||
|   DRV_write(DRV_WAVEFORM_SEQ_1, sequence); | ||||
|   DRV_write(DRV_GO, 0x01); | ||||
| void DRV_pulse(uint8_t sequence) { | ||||
|     DRV_write(DRV_GO, 0x00); | ||||
|     DRV_write(DRV_WAVEFORM_SEQ_1, sequence); | ||||
|     DRV_write(DRV_GO, 0x01); | ||||
| } | ||||
|  | @ -22,383 +22,383 @@ | |||
| 
 | ||||
|  * Feedback Control Settings */ | ||||
| #ifndef FB_ERM_LRA | ||||
| #define FB_ERM_LRA 1 /* For ERM:0 or LRA:1*/ | ||||
| #    define FB_ERM_LRA 1 /* For ERM:0 or LRA:1*/ | ||||
| #endif | ||||
| #ifndef FB_BRAKEFACTOR | ||||
| #define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ | ||||
| #    define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ | ||||
| #endif | ||||
| #ifndef FB_LOOPGAIN | ||||
| #define FB_LOOPGAIN 1 /* For  Low:0, Medium:1, High:2, Very High:3 */ | ||||
| #    define FB_LOOPGAIN 1 /* For  Low:0, Medium:1, High:2, Very High:3 */ | ||||
| #endif | ||||
| 
 | ||||
| /* LRA specific settings */ | ||||
| #if FB_ERM_LRA == 1 | ||||
| #ifndef V_RMS | ||||
| #define V_RMS 2.0 | ||||
| #endif | ||||
| #ifndef V_PEAK | ||||
| #define V_PEAK 2.1 | ||||
| #endif | ||||
| #ifndef F_LRA | ||||
| #define F_LRA 205 | ||||
| #endif | ||||
| #ifndef RATED_VOLTAGE | ||||
| #define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */ | ||||
| #endif | ||||
| #    ifndef V_RMS | ||||
| #        define V_RMS 2.0 | ||||
| #    endif | ||||
| #    ifndef V_PEAK | ||||
| #        define V_PEAK 2.1 | ||||
| #    endif | ||||
| #    ifndef F_LRA | ||||
| #        define F_LRA 205 | ||||
| #    endif | ||||
| #    ifndef RATED_VOLTAGE | ||||
| #        define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */ | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| #ifndef RATED_VOLTAGE | ||||
| #define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */ | ||||
| #    define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */ | ||||
| #endif | ||||
| #ifndef V_PEAK | ||||
| #define V_PEAK 2.8 | ||||
| #    define V_PEAK 2.8 | ||||
| #endif | ||||
| 
 | ||||
| /* Library Selection */ | ||||
| #ifndef LIB_SELECTION | ||||
| #if FB_ERM_LRA == 1 | ||||
| #define LIB_SELECTION 6 /* For Empty:0' TS2200 library A to D:1-5, LRA Library: 6 */ | ||||
| #else | ||||
| #define LIB_SELECTION 1 | ||||
| #endif | ||||
| #    if FB_ERM_LRA == 1 | ||||
| #        define LIB_SELECTION 6 /* For Empty:0' TS2200 library A to D:1-5, LRA Library: 6 */ | ||||
| #    else | ||||
| #        define LIB_SELECTION 1 | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| #ifndef DRV_GREETING | ||||
| #define DRV_GREETING alert_750ms | ||||
| #    define DRV_GREETING alert_750ms | ||||
| #endif | ||||
| #ifndef DRV_MODE_DEFAULT | ||||
| #define DRV_MODE_DEFAULT strong_click1 | ||||
| #    define DRV_MODE_DEFAULT strong_click1 | ||||
| #endif | ||||
| 
 | ||||
| /* Control 1 register settings */ | ||||
| #ifndef DRIVE_TIME | ||||
| #define DRIVE_TIME 25 | ||||
| #    define DRIVE_TIME 25 | ||||
| #endif | ||||
| #ifndef AC_COUPLE | ||||
| #define AC_COUPLE 0 | ||||
| #    define AC_COUPLE 0 | ||||
| #endif | ||||
| #ifndef STARTUP_BOOST | ||||
| #define STARTUP_BOOST 1 | ||||
| #    define STARTUP_BOOST 1 | ||||
| #endif | ||||
| 
 | ||||
| /* Control 2 Settings */ | ||||
| #ifndef BIDIR_INPUT | ||||
| #define BIDIR_INPUT 1 | ||||
| #    define BIDIR_INPUT 1 | ||||
| #endif | ||||
| #ifndef BRAKE_STAB | ||||
| #define BRAKE_STAB 1 /* Loopgain is reduced when braking is almost complete to improve stability */ | ||||
| #    define BRAKE_STAB 1 /* Loopgain is reduced when braking is almost complete to improve stability */ | ||||
| #endif | ||||
| #ifndef SAMPLE_TIME  | ||||
| #define SAMPLE_TIME 3 | ||||
| #ifndef SAMPLE_TIME | ||||
| #    define SAMPLE_TIME 3 | ||||
| #endif | ||||
| #ifndef BLANKING_TIME | ||||
| #define BLANKING_TIME 1 | ||||
| #    define BLANKING_TIME 1 | ||||
| #endif | ||||
| #ifndef IDISS_TIME | ||||
| #define IDISS_TIME 1 | ||||
| #    define IDISS_TIME 1 | ||||
| #endif | ||||
| 
 | ||||
| /* Control 3 settings */ | ||||
| #ifndef NG_THRESH | ||||
| #define NG_THRESH 2 | ||||
| #    define NG_THRESH 2 | ||||
| #endif | ||||
| #ifndef ERM_OPEN_LOOP | ||||
| #define ERM_OPEN_LOOP 1 | ||||
| #    define ERM_OPEN_LOOP 1 | ||||
| #endif | ||||
| #ifndef SUPPLY_COMP_DIS | ||||
| #define SUPPLY_COMP_DIS 0 | ||||
| #    define SUPPLY_COMP_DIS 0 | ||||
| #endif | ||||
| #ifndef DATA_FORMAT_RTO | ||||
| #define DATA_FORMAT_RTO 0 | ||||
| #    define DATA_FORMAT_RTO 0 | ||||
| #endif | ||||
| #ifndef LRA_DRIVE_MODE | ||||
| #define LRA_DRIVE_MODE 0 | ||||
| #    define LRA_DRIVE_MODE 0 | ||||
| #endif | ||||
| #ifndef N_PWM_ANALOG | ||||
| #define N_PWM_ANALOG 0 | ||||
| #    define N_PWM_ANALOG 0 | ||||
| #endif | ||||
| #ifndef LRA_OPEN_LOOP | ||||
| #define LRA_OPEN_LOOP 0 | ||||
| #    define LRA_OPEN_LOOP 0 | ||||
| #endif | ||||
| 
 | ||||
| /* Control 4 settings */ | ||||
| #ifndef ZC_DET_TIME | ||||
| #define ZC_DET_TIME 0 | ||||
| #    define ZC_DET_TIME 0 | ||||
| #endif | ||||
| #ifndef AUTO_CAL_TIME | ||||
| #define AUTO_CAL_TIME 3 | ||||
| #    define AUTO_CAL_TIME 3 | ||||
| #endif | ||||
| 
 | ||||
| /* register defines -------------------------------------------------------- */ | ||||
| #define DRV2605L_BASE_ADDRESS       0x5A		/* DRV2605L Base address */ | ||||
| #define DRV_STATUS                  0x00 | ||||
| #define DRV_MODE                    0x01 | ||||
| #define DRV_RTP_INPUT               0x02 | ||||
| #define DRV_LIB_SELECTION           0x03 | ||||
| #define DRV_WAVEFORM_SEQ_1          0x04 | ||||
| #define DRV_WAVEFORM_SEQ_2          0x05 | ||||
| #define DRV_WAVEFORM_SEQ_3          0x06 | ||||
| #define DRV_WAVEFORM_SEQ_4          0x07 | ||||
| #define DRV_WAVEFORM_SEQ_5          0x08 | ||||
| #define DRV_WAVEFORM_SEQ_6          0x09 | ||||
| #define DRV_WAVEFORM_SEQ_7          0x0A | ||||
| #define DRV_WAVEFORM_SEQ_8          0x0B | ||||
| #define DRV_GO                      0x0C | ||||
| #define DRV_OVERDRIVE_TIME_OFFSET   0x0D | ||||
| #define DRV_SUSTAIN_TIME_OFFSET_P   0x0E | ||||
| #define DRV_SUSTAIN_TIME_OFFSET_N   0x0F | ||||
| #define DRV_BRAKE_TIME_OFFSET       0x10 | ||||
| #define DRV_AUDIO_2_VIBE_CTRL       0x11 | ||||
| #define DRV_AUDIO_2_VIBE_MIN_IN     0x12 | ||||
| #define DRV_AUDIO_2_VIBE_MAX_IN     0x13 | ||||
| #define DRV_AUDIO_2_VIBE_MIN_OUTDRV	0x14 | ||||
| #define DRV_AUDIO_2_VIBE_MAX_OUTDRV	0x15 | ||||
| #define DRV_RATED_VOLT              0x16 | ||||
| #define DRV_OVERDRIVE_CLAMP_VOLT    0x17 | ||||
| #define DRV_AUTO_CALIB_COMP_RESULT  0x18  | ||||
| #define DRV_AUTO_CALIB_BEMF_RESULT  0x19 | ||||
| #define DRV_FEEDBACK_CTRL           0x1A | ||||
| #define DRV_CTRL_1                  0x1B | ||||
| #define DRV_CTRL_2                  0x1C | ||||
| #define DRV_CTRL_3                  0x1D | ||||
| #define DRV_CTRL_4                  0x1E | ||||
| #define DRV_CTRL_5                  0x1F | ||||
| #define DRV_OPEN_LOOP_PERIOD        0x20 | ||||
| #define DRV_VBAT_VOLT_MONITOR       0x21 | ||||
| #define DRV_LRA_RESONANCE_PERIOD    0x22 | ||||
| #define DRV2605L_BASE_ADDRESS 0x5A /* DRV2605L Base address */ | ||||
| #define DRV_STATUS 0x00 | ||||
| #define DRV_MODE 0x01 | ||||
| #define DRV_RTP_INPUT 0x02 | ||||
| #define DRV_LIB_SELECTION 0x03 | ||||
| #define DRV_WAVEFORM_SEQ_1 0x04 | ||||
| #define DRV_WAVEFORM_SEQ_2 0x05 | ||||
| #define DRV_WAVEFORM_SEQ_3 0x06 | ||||
| #define DRV_WAVEFORM_SEQ_4 0x07 | ||||
| #define DRV_WAVEFORM_SEQ_5 0x08 | ||||
| #define DRV_WAVEFORM_SEQ_6 0x09 | ||||
| #define DRV_WAVEFORM_SEQ_7 0x0A | ||||
| #define DRV_WAVEFORM_SEQ_8 0x0B | ||||
| #define DRV_GO 0x0C | ||||
| #define DRV_OVERDRIVE_TIME_OFFSET 0x0D | ||||
| #define DRV_SUSTAIN_TIME_OFFSET_P 0x0E | ||||
| #define DRV_SUSTAIN_TIME_OFFSET_N 0x0F | ||||
| #define DRV_BRAKE_TIME_OFFSET 0x10 | ||||
| #define DRV_AUDIO_2_VIBE_CTRL 0x11 | ||||
| #define DRV_AUDIO_2_VIBE_MIN_IN 0x12 | ||||
| #define DRV_AUDIO_2_VIBE_MAX_IN 0x13 | ||||
| #define DRV_AUDIO_2_VIBE_MIN_OUTDRV 0x14 | ||||
| #define DRV_AUDIO_2_VIBE_MAX_OUTDRV 0x15 | ||||
| #define DRV_RATED_VOLT 0x16 | ||||
| #define DRV_OVERDRIVE_CLAMP_VOLT 0x17 | ||||
| #define DRV_AUTO_CALIB_COMP_RESULT 0x18 | ||||
| #define DRV_AUTO_CALIB_BEMF_RESULT 0x19 | ||||
| #define DRV_FEEDBACK_CTRL 0x1A | ||||
| #define DRV_CTRL_1 0x1B | ||||
| #define DRV_CTRL_2 0x1C | ||||
| #define DRV_CTRL_3 0x1D | ||||
| #define DRV_CTRL_4 0x1E | ||||
| #define DRV_CTRL_5 0x1F | ||||
| #define DRV_OPEN_LOOP_PERIOD 0x20 | ||||
| #define DRV_VBAT_VOLT_MONITOR 0x21 | ||||
| #define DRV_LRA_RESONANCE_PERIOD 0x22 | ||||
| 
 | ||||
| void DRV_init(void); | ||||
| void DRV_write(const uint8_t drv_register, const uint8_t settings); | ||||
| void    DRV_init(void); | ||||
| void    DRV_write(const uint8_t drv_register, const uint8_t settings); | ||||
| uint8_t DRV_read(const uint8_t regaddress); | ||||
| void DRV_pulse(const uint8_t sequence); | ||||
| void    DRV_pulse(const uint8_t sequence); | ||||
| 
 | ||||
| typedef enum DRV_EFFECT{ | ||||
|   clear_sequence      = 0, | ||||
|   strong_click 		    = 1, | ||||
|   strong_click_60 		= 2, | ||||
|   strong_click_30 		= 3, | ||||
|   sharp_click 		    = 4, | ||||
|   sharp_click_60      = 5, | ||||
|   sharp_click_30      = 6, | ||||
|   soft_bump           = 7, | ||||
|   soft_bump_60        = 8, | ||||
|   soft_bump_30        = 9, | ||||
|   dbl_click           = 10, | ||||
|   dbl_click_60        = 11, | ||||
|   trp_click           = 12, | ||||
|   soft_fuzz           = 13, | ||||
|   strong_buzz         = 14, | ||||
|   alert_750ms         = 15, | ||||
|   alert_1000ms        = 16, | ||||
|   strong_click1       = 17, | ||||
|   strong_click2_80    = 18, | ||||
|   strong_click3_60    = 19, | ||||
|   strong_click4_30    = 20, | ||||
|   medium_click1       = 21, | ||||
|   medium_click2_80    = 22, | ||||
|   medium_click3_60    = 23, | ||||
|   sharp_tick1         = 24, | ||||
|   sharp_tick2_80      = 25, | ||||
|   sharp_tick3_60      = 26, | ||||
|   sh_dblclick_str     = 27, | ||||
|   sh_dblclick_str_80  = 28, | ||||
|   sh_dblclick_str_60  = 29, | ||||
|   sh_dblclick_str_30  = 30, | ||||
|   sh_dblclick_med     = 31, | ||||
|   sh_dblclick_med_80  = 32, | ||||
|   sh_dblclick_med_60  = 33, | ||||
|   sh_dblsharp_tick    = 34, | ||||
|   sh_dblsharp_tick_80 = 35, | ||||
|   sh_dblsharp_tick_60 = 36, | ||||
|   lg_dblclick_str     = 37, | ||||
|   lg_dblclick_str_80  = 38, | ||||
|   lg_dblclick_str_60  = 39, | ||||
|   lg_dblclick_str_30  = 40, | ||||
|   lg_dblclick_med     = 41, | ||||
|   lg_dblclick_med_80  = 42, | ||||
|   lg_dblclick_med_60  = 43, | ||||
|   lg_dblsharp_tick    = 44, | ||||
|   lg_dblsharp_tick_80 = 45, | ||||
|   lg_dblsharp_tick_60 = 46, | ||||
|   buzz 					= 47, | ||||
|   buzz_80				= 48, | ||||
|   buzz_60				= 49, | ||||
|   buzz_40				= 50, | ||||
|   buzz_20				= 51, | ||||
|   pulsing_strong      = 52, | ||||
|   pulsing_strong_80   = 53, | ||||
|   pulsing_medium      = 54, | ||||
|   pulsing_medium_80   = 55, | ||||
|   pulsing_sharp       = 56, | ||||
|   pulsing_sharp_80    = 57, | ||||
|   transition_click		= 58, | ||||
|   transition_click_80 = 59, | ||||
|   transition_click_60	= 60, | ||||
|   transition_click_40	= 61, | ||||
|   transition_click_20	= 62, | ||||
|   transition_click_10	= 63, | ||||
|   transition_hum      = 64, | ||||
|   transition_hum_80   = 65, | ||||
|   transition_hum_60   = 66, | ||||
|   transition_hum_40   = 67, | ||||
|   transition_hum_20   = 68, | ||||
|   transition_hum_10   = 69, | ||||
|   transition_rampdown_long_smooth1  = 70, | ||||
|   transition_rampdown_long_smooth2  = 71, | ||||
|   transition_rampdown_med_smooth1   = 72, | ||||
|   transition_rampdown_med_smooth2   = 73, | ||||
|   transition_rampdown_short_smooth1 = 74, | ||||
|   transition_rampdown_short_smooth2 = 75, | ||||
|   transition_rampdown_long_sharp1   = 76, | ||||
|   transition_rampdown_long_sharp2   = 77, | ||||
|   transition_rampdown_med_sharp1    = 78, | ||||
|   transition_rampdown_med_sharp2    = 79, | ||||
|   transition_rampdown_short_sharp1  = 80, | ||||
|   transition_rampdown_short_sharp2  = 81, | ||||
|   transition_rampup_long_smooth1    = 82, | ||||
|   transition_rampup_long_smooth2    = 83, | ||||
|   transition_rampup_med_smooth1     = 84, | ||||
|   transition_rampup_med_smooth2     = 85, | ||||
|   transition_rampup_short_smooth1   = 86, | ||||
|   transition_rampup_short_smooth2   = 87, | ||||
|   transition_rampup_long_sharp1     = 88, | ||||
|   transition_rampup_long_sharp2     = 89, | ||||
|   transition_rampup_med_sharp1      = 90, | ||||
|   transition_rampup_med_sharp2      = 91, | ||||
|   transition_rampup_short_sharp1    = 92, | ||||
|   transition_rampup_short_sharp2    = 93, | ||||
|   transition_rampdown_long_smooth1_50  = 94, | ||||
|   transition_rampdown_long_smooth2_50  = 95, | ||||
|   transition_rampdown_med_smooth1_50   = 96, | ||||
|   transition_rampdown_med_smooth2_50   = 97, | ||||
|   transition_rampdown_short_smooth1_50 = 98, | ||||
|   transition_rampdown_short_smooth2_50 = 99, | ||||
|   transition_rampdown_long_sharp1_50   = 100, | ||||
|   transition_rampdown_long_sharp2_50   = 101, | ||||
|   transition_rampdown_med_sharp1_50    = 102, | ||||
|   transition_rampdown_med_sharp2_50    = 103, | ||||
|   transition_rampdown_short_sharp1_50  = 104, | ||||
|   transition_rampdown_short_sharp2_50  = 105, | ||||
|   transition_rampup_long_smooth1_50    = 106, | ||||
|   transition_rampup_long_smooth2_50    = 107, | ||||
|   transition_rampup_med_smooth1_50     = 108, | ||||
|   transition_rampup_med_smooth2_50     = 109, | ||||
|   transition_rampup_short_smooth1_50   = 110, | ||||
|   transition_rampup_short_smooth2_50   = 111, | ||||
|   transition_rampup_long_sharp1_50     = 112, | ||||
|   transition_rampup_long_sharp2_50     = 113, | ||||
|   transition_rampup_med_sharp1_50      = 114, | ||||
|   transition_rampup_med_sharp2_50      = 115, | ||||
|   transition_rampup_short_sharp1_50    = 116, | ||||
|   transition_rampup_short_sharp2_50    = 117, | ||||
|   long_buzz_for_programmatic_stopping  = 118, | ||||
|   smooth_hum1_50 = 119, | ||||
|   smooth_hum2_40 = 120, | ||||
|   smooth_hum3_30 = 121, | ||||
|   smooth_hum4_20 = 122, | ||||
|   smooth_hum5_10 = 123, | ||||
|   drv_effect_max = 124, | ||||
| typedef enum DRV_EFFECT { | ||||
|     clear_sequence                       = 0, | ||||
|     strong_click                         = 1, | ||||
|     strong_click_60                      = 2, | ||||
|     strong_click_30                      = 3, | ||||
|     sharp_click                          = 4, | ||||
|     sharp_click_60                       = 5, | ||||
|     sharp_click_30                       = 6, | ||||
|     soft_bump                            = 7, | ||||
|     soft_bump_60                         = 8, | ||||
|     soft_bump_30                         = 9, | ||||
|     dbl_click                            = 10, | ||||
|     dbl_click_60                         = 11, | ||||
|     trp_click                            = 12, | ||||
|     soft_fuzz                            = 13, | ||||
|     strong_buzz                          = 14, | ||||
|     alert_750ms                          = 15, | ||||
|     alert_1000ms                         = 16, | ||||
|     strong_click1                        = 17, | ||||
|     strong_click2_80                     = 18, | ||||
|     strong_click3_60                     = 19, | ||||
|     strong_click4_30                     = 20, | ||||
|     medium_click1                        = 21, | ||||
|     medium_click2_80                     = 22, | ||||
|     medium_click3_60                     = 23, | ||||
|     sharp_tick1                          = 24, | ||||
|     sharp_tick2_80                       = 25, | ||||
|     sharp_tick3_60                       = 26, | ||||
|     sh_dblclick_str                      = 27, | ||||
|     sh_dblclick_str_80                   = 28, | ||||
|     sh_dblclick_str_60                   = 29, | ||||
|     sh_dblclick_str_30                   = 30, | ||||
|     sh_dblclick_med                      = 31, | ||||
|     sh_dblclick_med_80                   = 32, | ||||
|     sh_dblclick_med_60                   = 33, | ||||
|     sh_dblsharp_tick                     = 34, | ||||
|     sh_dblsharp_tick_80                  = 35, | ||||
|     sh_dblsharp_tick_60                  = 36, | ||||
|     lg_dblclick_str                      = 37, | ||||
|     lg_dblclick_str_80                   = 38, | ||||
|     lg_dblclick_str_60                   = 39, | ||||
|     lg_dblclick_str_30                   = 40, | ||||
|     lg_dblclick_med                      = 41, | ||||
|     lg_dblclick_med_80                   = 42, | ||||
|     lg_dblclick_med_60                   = 43, | ||||
|     lg_dblsharp_tick                     = 44, | ||||
|     lg_dblsharp_tick_80                  = 45, | ||||
|     lg_dblsharp_tick_60                  = 46, | ||||
|     buzz                                 = 47, | ||||
|     buzz_80                              = 48, | ||||
|     buzz_60                              = 49, | ||||
|     buzz_40                              = 50, | ||||
|     buzz_20                              = 51, | ||||
|     pulsing_strong                       = 52, | ||||
|     pulsing_strong_80                    = 53, | ||||
|     pulsing_medium                       = 54, | ||||
|     pulsing_medium_80                    = 55, | ||||
|     pulsing_sharp                        = 56, | ||||
|     pulsing_sharp_80                     = 57, | ||||
|     transition_click                     = 58, | ||||
|     transition_click_80                  = 59, | ||||
|     transition_click_60                  = 60, | ||||
|     transition_click_40                  = 61, | ||||
|     transition_click_20                  = 62, | ||||
|     transition_click_10                  = 63, | ||||
|     transition_hum                       = 64, | ||||
|     transition_hum_80                    = 65, | ||||
|     transition_hum_60                    = 66, | ||||
|     transition_hum_40                    = 67, | ||||
|     transition_hum_20                    = 68, | ||||
|     transition_hum_10                    = 69, | ||||
|     transition_rampdown_long_smooth1     = 70, | ||||
|     transition_rampdown_long_smooth2     = 71, | ||||
|     transition_rampdown_med_smooth1      = 72, | ||||
|     transition_rampdown_med_smooth2      = 73, | ||||
|     transition_rampdown_short_smooth1    = 74, | ||||
|     transition_rampdown_short_smooth2    = 75, | ||||
|     transition_rampdown_long_sharp1      = 76, | ||||
|     transition_rampdown_long_sharp2      = 77, | ||||
|     transition_rampdown_med_sharp1       = 78, | ||||
|     transition_rampdown_med_sharp2       = 79, | ||||
|     transition_rampdown_short_sharp1     = 80, | ||||
|     transition_rampdown_short_sharp2     = 81, | ||||
|     transition_rampup_long_smooth1       = 82, | ||||
|     transition_rampup_long_smooth2       = 83, | ||||
|     transition_rampup_med_smooth1        = 84, | ||||
|     transition_rampup_med_smooth2        = 85, | ||||
|     transition_rampup_short_smooth1      = 86, | ||||
|     transition_rampup_short_smooth2      = 87, | ||||
|     transition_rampup_long_sharp1        = 88, | ||||
|     transition_rampup_long_sharp2        = 89, | ||||
|     transition_rampup_med_sharp1         = 90, | ||||
|     transition_rampup_med_sharp2         = 91, | ||||
|     transition_rampup_short_sharp1       = 92, | ||||
|     transition_rampup_short_sharp2       = 93, | ||||
|     transition_rampdown_long_smooth1_50  = 94, | ||||
|     transition_rampdown_long_smooth2_50  = 95, | ||||
|     transition_rampdown_med_smooth1_50   = 96, | ||||
|     transition_rampdown_med_smooth2_50   = 97, | ||||
|     transition_rampdown_short_smooth1_50 = 98, | ||||
|     transition_rampdown_short_smooth2_50 = 99, | ||||
|     transition_rampdown_long_sharp1_50   = 100, | ||||
|     transition_rampdown_long_sharp2_50   = 101, | ||||
|     transition_rampdown_med_sharp1_50    = 102, | ||||
|     transition_rampdown_med_sharp2_50    = 103, | ||||
|     transition_rampdown_short_sharp1_50  = 104, | ||||
|     transition_rampdown_short_sharp2_50  = 105, | ||||
|     transition_rampup_long_smooth1_50    = 106, | ||||
|     transition_rampup_long_smooth2_50    = 107, | ||||
|     transition_rampup_med_smooth1_50     = 108, | ||||
|     transition_rampup_med_smooth2_50     = 109, | ||||
|     transition_rampup_short_smooth1_50   = 110, | ||||
|     transition_rampup_short_smooth2_50   = 111, | ||||
|     transition_rampup_long_sharp1_50     = 112, | ||||
|     transition_rampup_long_sharp2_50     = 113, | ||||
|     transition_rampup_med_sharp1_50      = 114, | ||||
|     transition_rampup_med_sharp2_50      = 115, | ||||
|     transition_rampup_short_sharp1_50    = 116, | ||||
|     transition_rampup_short_sharp2_50    = 117, | ||||
|     long_buzz_for_programmatic_stopping  = 118, | ||||
|     smooth_hum1_50                       = 119, | ||||
|     smooth_hum2_40                       = 120, | ||||
|     smooth_hum3_30                       = 121, | ||||
|     smooth_hum4_20                       = 122, | ||||
|     smooth_hum5_10                       = 123, | ||||
|     drv_effect_max                       = 124, | ||||
| } DRV_EFFECT; | ||||
| 
 | ||||
| /* Register bit array unions */ | ||||
| 
 | ||||
| typedef union DRVREG_STATUS { /* register 0x00 */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t OC_DETECT   :1; /* set to 1 when overcurrent event is detected */ | ||||
|     uint8_t OVER_TEMP   :1; /* set to 1 when device exceeds temp threshold */ | ||||
|     uint8_t FB_STS      :1; /* set to 1 when feedback controller has timed out */ | ||||
|     /* auto-calibration routine and diagnostic result
 | ||||
|      * result  |  auto-calibation  |      diagnostic       | | ||||
|      *   0     |      passed       | actuator func normal  | | ||||
|      *   1     |      failed       | actuator func fault*  | | ||||
|      * * actuator is not present or is shorted, timing out, or giving out–of-range back-EMF */ | ||||
|     uint8_t DIAG_RESULT :1; | ||||
|     uint8_t             :1; | ||||
|     uint8_t DEVICE_ID   :3; /* Device IDs 3: DRV2605  4: DRV2604  5: DRV2604L  6: DRV2605L */ | ||||
|   } Bits; | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t OC_DETECT : 1; /* set to 1 when overcurrent event is detected */ | ||||
|         uint8_t OVER_TEMP : 1; /* set to 1 when device exceeds temp threshold */ | ||||
|         uint8_t FB_STS : 1;    /* set to 1 when feedback controller has timed out */ | ||||
|         /* auto-calibration routine and diagnostic result
 | ||||
|          * result  |  auto-calibation  |      diagnostic       | | ||||
|          *   0     |      passed       | actuator func normal  | | ||||
|          *   1     |      failed       | actuator func fault*  | | ||||
|          * * actuator is not present or is shorted, timing out, or giving out–of-range back-EMF */ | ||||
|         uint8_t DIAG_RESULT : 1; | ||||
|         uint8_t : 1; | ||||
|         uint8_t DEVICE_ID : 3; /* Device IDs 3: DRV2605  4: DRV2604  5: DRV2604L  6: DRV2605L */ | ||||
|     } Bits; | ||||
| } DRVREG_STATUS; | ||||
| 
 | ||||
| typedef union DRVREG_MODE { /* register 0x01 */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t MODE        :3; /* Mode setting */ | ||||
|     uint8_t             :3; | ||||
|     uint8_t STANDBY     :1; /* 0:standby 1:ready */ | ||||
|   } Bits; | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t MODE : 3; /* Mode setting */ | ||||
|         uint8_t : 3; | ||||
|         uint8_t STANDBY : 1; /* 0:standby 1:ready */ | ||||
|     } Bits; | ||||
| } DRVREG_MODE; | ||||
| 
 | ||||
| typedef union DRVREG_WAIT { | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t WAIT_MODE   :1; /* Set to 1 to interpret as wait for next 7 bits x10ms */ | ||||
|     uint8_t WAIT_TIME   :7; | ||||
|   } Bits; | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t WAIT_MODE : 1; /* Set to 1 to interpret as wait for next 7 bits x10ms */ | ||||
|         uint8_t WAIT_TIME : 7; | ||||
|     } Bits; | ||||
| } DRVREG_WAIT; | ||||
| 
 | ||||
| typedef union DRVREG_FBR{ /* register 0x1A */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t BEMF_GAIN    :2; | ||||
|     uint8_t LOOP_GAIN    :2; | ||||
|     uint8_t BRAKE_FACTOR :3; | ||||
|     uint8_t ERM_LRA      :1; | ||||
|   } Bits; | ||||
| typedef union DRVREG_FBR { /* register 0x1A */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t BEMF_GAIN : 2; | ||||
|         uint8_t LOOP_GAIN : 2; | ||||
|         uint8_t BRAKE_FACTOR : 3; | ||||
|         uint8_t ERM_LRA : 1; | ||||
|     } Bits; | ||||
| } DRVREG_FBR; | ||||
| 
 | ||||
| typedef union DRVREG_CTRL1{ /* register 0x1B */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t C1_DRIVE_TIME    :5; | ||||
|     uint8_t C1_AC_COUPLE     :1; | ||||
|     uint8_t                  :1; | ||||
|     uint8_t C1_STARTUP_BOOST :1; | ||||
|   } Bits; | ||||
| typedef union DRVREG_CTRL1 { /* register 0x1B */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t C1_DRIVE_TIME : 5; | ||||
|         uint8_t C1_AC_COUPLE : 1; | ||||
|         uint8_t : 1; | ||||
|         uint8_t C1_STARTUP_BOOST : 1; | ||||
|     } Bits; | ||||
| } DRVREG_CTRL1; | ||||
| 
 | ||||
| typedef union DRVREG_CTRL2{ /* register 0x1C */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t C2_IDISS_TIME    :2; | ||||
|     uint8_t C2_BLANKING_TIME :2; | ||||
|     uint8_t C2_SAMPLE_TIME   :2; | ||||
|     uint8_t C2_BRAKE_STAB    :1; | ||||
|     uint8_t C2_BIDIR_INPUT   :1; | ||||
|   } Bits; | ||||
| typedef union DRVREG_CTRL2 { /* register 0x1C */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t C2_IDISS_TIME : 2; | ||||
|         uint8_t C2_BLANKING_TIME : 2; | ||||
|         uint8_t C2_SAMPLE_TIME : 2; | ||||
|         uint8_t C2_BRAKE_STAB : 1; | ||||
|         uint8_t C2_BIDIR_INPUT : 1; | ||||
|     } Bits; | ||||
| } DRVREG_CTRL2; | ||||
| 
 | ||||
| typedef union DRVREG_CTRL3{ /* register 0x1D */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t C3_LRA_OPEN_LOOP   :1; | ||||
|     uint8_t C3_N_PWM_ANALOG    :1; | ||||
|     uint8_t C3_LRA_DRIVE_MODE  :1; | ||||
|     uint8_t C3_DATA_FORMAT_RTO :1; | ||||
|     uint8_t C3_SUPPLY_COMP_DIS :1; | ||||
|     uint8_t C3_ERM_OPEN_LOOP   :1; | ||||
|     uint8_t C3_NG_THRESH       :2; | ||||
|   } Bits; | ||||
| typedef union DRVREG_CTRL3 { /* register 0x1D */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t C3_LRA_OPEN_LOOP : 1; | ||||
|         uint8_t C3_N_PWM_ANALOG : 1; | ||||
|         uint8_t C3_LRA_DRIVE_MODE : 1; | ||||
|         uint8_t C3_DATA_FORMAT_RTO : 1; | ||||
|         uint8_t C3_SUPPLY_COMP_DIS : 1; | ||||
|         uint8_t C3_ERM_OPEN_LOOP : 1; | ||||
|         uint8_t C3_NG_THRESH : 2; | ||||
|     } Bits; | ||||
| } DRVREG_CTRL3; | ||||
| 
 | ||||
| typedef union DRVREG_CTRL4{ /* register 0x1E */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t C4_OTP_PROGRAM     :1; | ||||
|     uint8_t                    :1; | ||||
|     uint8_t C4_OTP_STATUS      :1; | ||||
|     uint8_t                    :1; | ||||
|     uint8_t C4_AUTO_CAL_TIME   :2; | ||||
|     uint8_t C4_ZC_DET_TIME     :2; | ||||
|   } Bits; | ||||
| typedef union DRVREG_CTRL4 { /* register 0x1E */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t C4_OTP_PROGRAM : 1; | ||||
|         uint8_t : 1; | ||||
|         uint8_t C4_OTP_STATUS : 1; | ||||
|         uint8_t : 1; | ||||
|         uint8_t C4_AUTO_CAL_TIME : 2; | ||||
|         uint8_t C4_ZC_DET_TIME : 2; | ||||
|     } Bits; | ||||
| } DRVREG_CTRL4; | ||||
| 
 | ||||
| typedef union DRVREG_CTRL5{ /* register 0x1F */ | ||||
|   uint8_t Byte; | ||||
|   struct { | ||||
|     uint8_t C5_IDISS_TIME         :2; | ||||
|     uint8_t C5_BLANKING_TIME      :2; | ||||
|     uint8_t C5_PLAYBACK_INTERVAL  :1; | ||||
|     uint8_t C5_LRA_AUTO_OPEN_LOOP :1; | ||||
|     uint8_t C5_AUTO_OL_CNT        :2; | ||||
|   } Bits; | ||||
| typedef union DRVREG_CTRL5 { /* register 0x1F */ | ||||
|     uint8_t Byte; | ||||
|     struct { | ||||
|         uint8_t C5_IDISS_TIME : 2; | ||||
|         uint8_t C5_BLANKING_TIME : 2; | ||||
|         uint8_t C5_PLAYBACK_INTERVAL : 1; | ||||
|         uint8_t C5_LRA_AUTO_OPEN_LOOP : 1; | ||||
|         uint8_t C5_AUTO_OL_CNT : 2; | ||||
|     } Bits; | ||||
| } DRVREG_CTRL5; | ||||
|  | @ -19,230 +19,248 @@ | |||
| #include "progmem.h" | ||||
| #include "debug.h" | ||||
| #ifdef DRV2605L | ||||
| #include "DRV2605L.h" | ||||
| #    include "DRV2605L.h" | ||||
| #endif | ||||
| #ifdef SOLENOID_ENABLE | ||||
| #include "solenoid.h" | ||||
| #    include "solenoid.h" | ||||
| #endif | ||||
| 
 | ||||
| haptic_config_t haptic_config; | ||||
| 
 | ||||
| void haptic_init(void) { | ||||
|   debug_enable = 1; //Debug is ON!
 | ||||
|   if (!eeconfig_is_enabled()) { | ||||
|   	eeconfig_init(); | ||||
|   } | ||||
|   haptic_config.raw = eeconfig_read_haptic(); | ||||
|   if (haptic_config.mode < 1){ | ||||
|   haptic_config.mode = 1; | ||||
|   } | ||||
|   if (!haptic_config.mode){ | ||||
|   dprintf("No haptic config found in eeprom, setting default configs\n"); | ||||
|   haptic_reset(); | ||||
|   } | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|     debug_enable = 1;  // Debug is ON!
 | ||||
|     if (!eeconfig_is_enabled()) { | ||||
|         eeconfig_init(); | ||||
|     } | ||||
|     haptic_config.raw = eeconfig_read_haptic(); | ||||
|     if (haptic_config.mode < 1) { | ||||
|         haptic_config.mode = 1; | ||||
|     } | ||||
|     if (!haptic_config.mode) { | ||||
|         dprintf("No haptic config found in eeprom, setting default configs\n"); | ||||
|         haptic_reset(); | ||||
|     } | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     solenoid_setup(); | ||||
|     dprintf("Solenoid driver initialized\n"); | ||||
|   #endif | ||||
|   #ifdef DRV2605L | ||||
| #endif | ||||
| #ifdef DRV2605L | ||||
|     DRV_init(); | ||||
|     dprintf("DRV2605 driver initialized\n"); | ||||
|   #endif | ||||
|   eeconfig_debug_haptic(); | ||||
| #endif | ||||
|     eeconfig_debug_haptic(); | ||||
| } | ||||
| 
 | ||||
| void haptic_task(void) { | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|   solenoid_check(); | ||||
|   #endif | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     solenoid_check(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void eeconfig_debug_haptic(void) { | ||||
|   dprintf("haptic_config eprom\n"); | ||||
|   dprintf("haptic_config.enable = %d\n", haptic_config.enable); | ||||
|   dprintf("haptic_config.mode = %d\n", haptic_config.mode); | ||||
|     dprintf("haptic_config eprom\n"); | ||||
|     dprintf("haptic_config.enable = %d\n", haptic_config.enable); | ||||
|     dprintf("haptic_config.mode = %d\n", haptic_config.mode); | ||||
| } | ||||
| 
 | ||||
| void haptic_enable(void) { | ||||
|   haptic_config.enable = 1; | ||||
|   xprintf("haptic_config.enable = %u\n", haptic_config.enable); | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|     haptic_config.enable = 1; | ||||
|     xprintf("haptic_config.enable = %u\n", haptic_config.enable); | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
| } | ||||
| 
 | ||||
| void haptic_disable(void) { | ||||
|   haptic_config.enable = 0; | ||||
|   xprintf("haptic_config.enable = %u\n", haptic_config.enable); | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|     haptic_config.enable = 0; | ||||
|     xprintf("haptic_config.enable = %u\n", haptic_config.enable); | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
| } | ||||
| 
 | ||||
| void haptic_toggle(void) { | ||||
| if (haptic_config.enable) { | ||||
|   haptic_disable(); | ||||
|   } else { | ||||
|   haptic_enable(); | ||||
|   } | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|     if (haptic_config.enable) { | ||||
|         haptic_disable(); | ||||
|     } else { | ||||
|         haptic_enable(); | ||||
|     } | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
| } | ||||
| 
 | ||||
| void haptic_feedback_toggle(void){ | ||||
|  haptic_config.feedback++; | ||||
|   if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) | ||||
|   haptic_config.feedback = KEY_PRESS; | ||||
|   xprintf("haptic_config.feedback = %u\n", !haptic_config.feedback); | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
| void haptic_feedback_toggle(void) { | ||||
|     haptic_config.feedback++; | ||||
|     if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) haptic_config.feedback = KEY_PRESS; | ||||
|     xprintf("haptic_config.feedback = %u\n", !haptic_config.feedback); | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
| } | ||||
| 
 | ||||
| void haptic_buzz_toggle(void) { | ||||
|   bool buzz_stat = !haptic_config.buzz; | ||||
|   haptic_config.buzz = buzz_stat; | ||||
|   haptic_set_buzz(buzz_stat); | ||||
|     bool buzz_stat     = !haptic_config.buzz; | ||||
|     haptic_config.buzz = buzz_stat; | ||||
|     haptic_set_buzz(buzz_stat); | ||||
| } | ||||
| 
 | ||||
| void haptic_mode_increase(void) { | ||||
|   uint8_t mode = haptic_config.mode + 1; | ||||
|   #ifdef DRV2605L | ||||
|   if (haptic_config.mode >= drv_effect_max) { | ||||
|     mode = 1; | ||||
|   } | ||||
|   #endif | ||||
|     uint8_t mode = haptic_config.mode + 1; | ||||
| #ifdef DRV2605L | ||||
|     if (haptic_config.mode >= drv_effect_max) { | ||||
|         mode = 1; | ||||
|     } | ||||
| #endif | ||||
|     haptic_set_mode(mode); | ||||
| } | ||||
| 
 | ||||
| void haptic_mode_decrease(void) { | ||||
|   uint8_t mode = haptic_config.mode -1; | ||||
|   #ifdef DRV2605L | ||||
|   if (haptic_config.mode < 1) { | ||||
|     mode = (drv_effect_max - 1); | ||||
|   } | ||||
|   #endif | ||||
|   haptic_set_mode(mode); | ||||
|     uint8_t mode = haptic_config.mode - 1; | ||||
| #ifdef DRV2605L | ||||
|     if (haptic_config.mode < 1) { | ||||
|         mode = (drv_effect_max - 1); | ||||
|     } | ||||
| #endif | ||||
|     haptic_set_mode(mode); | ||||
| } | ||||
| 
 | ||||
| void haptic_dwell_increase(void) { | ||||
|   uint8_t dwell = haptic_config.dwell + 1; | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|   if (haptic_config.dwell >= SOLENOID_MAX_DWELL) { | ||||
|     dwell = 1; | ||||
|   } | ||||
|   solenoid_set_dwell(dwell); | ||||
|   #endif | ||||
|   haptic_set_dwell(dwell); | ||||
|     uint8_t dwell = haptic_config.dwell + 1; | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     if (haptic_config.dwell >= SOLENOID_MAX_DWELL) { | ||||
|         dwell = 1; | ||||
|     } | ||||
|     solenoid_set_dwell(dwell); | ||||
| #endif | ||||
|     haptic_set_dwell(dwell); | ||||
| } | ||||
| 
 | ||||
| void haptic_dwell_decrease(void) { | ||||
|   uint8_t dwell = haptic_config.dwell -1; | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|   if (haptic_config.dwell < SOLENOID_MIN_DWELL) { | ||||
|     dwell = SOLENOID_MAX_DWELL; | ||||
|   } | ||||
|   solenoid_set_dwell(dwell); | ||||
|   #endif | ||||
|   haptic_set_dwell(dwell); | ||||
|     uint8_t dwell = haptic_config.dwell - 1; | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     if (haptic_config.dwell < SOLENOID_MIN_DWELL) { | ||||
|         dwell = SOLENOID_MAX_DWELL; | ||||
|     } | ||||
|     solenoid_set_dwell(dwell); | ||||
| #endif | ||||
|     haptic_set_dwell(dwell); | ||||
| } | ||||
| 
 | ||||
| void haptic_reset(void){ | ||||
|   haptic_config.enable = true; | ||||
|   uint8_t feedback = HAPTIC_FEEDBACK_DEFAULT; | ||||
|   haptic_config.feedback = feedback; | ||||
|   #ifdef DRV2605L | ||||
|     uint8_t mode = HAPTIC_MODE_DEFAULT; | ||||
| void haptic_reset(void) { | ||||
|     haptic_config.enable   = true; | ||||
|     uint8_t feedback       = HAPTIC_FEEDBACK_DEFAULT; | ||||
|     haptic_config.feedback = feedback; | ||||
| #ifdef DRV2605L | ||||
|     uint8_t mode       = HAPTIC_MODE_DEFAULT; | ||||
|     haptic_config.mode = mode; | ||||
|   #endif | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|     uint8_t dwell = SOLENOID_DEFAULT_DWELL; | ||||
| #endif | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     uint8_t dwell       = SOLENOID_DEFAULT_DWELL; | ||||
|     haptic_config.dwell = dwell; | ||||
|   #endif | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|   xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); | ||||
|   xprintf("haptic_config.mode = %u\n", haptic_config.mode); | ||||
| #endif | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
|     xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); | ||||
|     xprintf("haptic_config.mode = %u\n", haptic_config.mode); | ||||
| } | ||||
| 
 | ||||
| void haptic_set_feedback(uint8_t feedback) { | ||||
|   haptic_config.feedback = feedback; | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|   xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); | ||||
|     haptic_config.feedback = feedback; | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
|     xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); | ||||
| } | ||||
| 
 | ||||
| void haptic_set_mode(uint8_t mode) { | ||||
|   haptic_config.mode = mode; | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|   xprintf("haptic_config.mode = %u\n", haptic_config.mode); | ||||
|     haptic_config.mode = mode; | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
|     xprintf("haptic_config.mode = %u\n", haptic_config.mode); | ||||
| } | ||||
| 
 | ||||
| void haptic_set_buzz(uint8_t buzz) { | ||||
|   haptic_config.buzz = buzz; | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|   xprintf("haptic_config.buzz = %u\n", haptic_config.buzz); | ||||
|     haptic_config.buzz = buzz; | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
|     xprintf("haptic_config.buzz = %u\n", haptic_config.buzz); | ||||
| } | ||||
| 
 | ||||
| void haptic_set_dwell(uint8_t dwell) { | ||||
|   haptic_config.dwell = dwell; | ||||
|   eeconfig_update_haptic(haptic_config.raw); | ||||
|   xprintf("haptic_config.dwell = %u\n", haptic_config.dwell); | ||||
|     haptic_config.dwell = dwell; | ||||
|     eeconfig_update_haptic(haptic_config.raw); | ||||
|     xprintf("haptic_config.dwell = %u\n", haptic_config.dwell); | ||||
| } | ||||
| 
 | ||||
| uint8_t haptic_get_mode(void) { | ||||
|   if (!haptic_config.enable){ | ||||
|     return false; | ||||
|   } | ||||
|   return haptic_config.mode; | ||||
|     if (!haptic_config.enable) { | ||||
|         return false; | ||||
|     } | ||||
|     return haptic_config.mode; | ||||
| } | ||||
| 
 | ||||
| uint8_t haptic_get_feedback(void) { | ||||
|   if (!haptic_config.enable){ | ||||
|     return false; | ||||
|   } | ||||
|   return haptic_config.feedback; | ||||
|     if (!haptic_config.enable) { | ||||
|         return false; | ||||
|     } | ||||
|     return haptic_config.feedback; | ||||
| } | ||||
| 
 | ||||
| uint8_t haptic_get_dwell(void) { | ||||
|   if (!haptic_config.enable){ | ||||
|     return false; | ||||
|   } | ||||
|   return haptic_config.dwell; | ||||
|     if (!haptic_config.enable) { | ||||
|         return false; | ||||
|     } | ||||
|     return haptic_config.dwell; | ||||
| } | ||||
| 
 | ||||
| void haptic_play(void) { | ||||
|   #ifdef DRV2605L | ||||
|   uint8_t play_eff = 0; | ||||
|   play_eff = haptic_config.mode; | ||||
|   DRV_pulse(play_eff); | ||||
|   #endif | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|   solenoid_fire(); | ||||
|   #endif | ||||
| #ifdef DRV2605L | ||||
|     uint8_t play_eff = 0; | ||||
|     play_eff         = haptic_config.mode; | ||||
|     DRV_pulse(play_eff); | ||||
| #endif | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     solenoid_fire(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool process_haptic(uint16_t keycode, keyrecord_t *record) { | ||||
|     if (keycode == HPT_ON && record->event.pressed) { haptic_enable(); } | ||||
|     if (keycode == HPT_OFF && record->event.pressed) { haptic_disable(); } | ||||
|     if (keycode == HPT_TOG && record->event.pressed) { haptic_toggle(); } | ||||
|     if (keycode == HPT_RST && record->event.pressed) { haptic_reset(); } | ||||
|     if (keycode == HPT_FBK && record->event.pressed) { haptic_feedback_toggle(); } | ||||
|     if (keycode == HPT_BUZ && record->event.pressed) { haptic_buzz_toggle(); } | ||||
|     if (keycode == HPT_MODI && record->event.pressed) { haptic_mode_increase(); } | ||||
|     if (keycode == HPT_MODD && record->event.pressed) { haptic_mode_decrease(); } | ||||
|     if (keycode == HPT_DWLI && record->event.pressed) { haptic_dwell_increase(); } | ||||
|     if (keycode == HPT_DWLD && record->event.pressed) { haptic_dwell_decrease(); } | ||||
|   if (haptic_config.enable) { | ||||
|     if ( record->event.pressed ) { | ||||
| 	// keypress
 | ||||
|       if (haptic_config.feedback < 2) { | ||||
|       haptic_play(); | ||||
|       } | ||||
|     } else { | ||||
|     //keyrelease
 | ||||
|       if (haptic_config.feedback > 0) { | ||||
|       haptic_play(); | ||||
|       }  | ||||
|     if (keycode == HPT_ON && record->event.pressed) { | ||||
|         haptic_enable(); | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
|     if (keycode == HPT_OFF && record->event.pressed) { | ||||
|         haptic_disable(); | ||||
|     } | ||||
|     if (keycode == HPT_TOG && record->event.pressed) { | ||||
|         haptic_toggle(); | ||||
|     } | ||||
|     if (keycode == HPT_RST && record->event.pressed) { | ||||
|         haptic_reset(); | ||||
|     } | ||||
|     if (keycode == HPT_FBK && record->event.pressed) { | ||||
|         haptic_feedback_toggle(); | ||||
|     } | ||||
|     if (keycode == HPT_BUZ && record->event.pressed) { | ||||
|         haptic_buzz_toggle(); | ||||
|     } | ||||
|     if (keycode == HPT_MODI && record->event.pressed) { | ||||
|         haptic_mode_increase(); | ||||
|     } | ||||
|     if (keycode == HPT_MODD && record->event.pressed) { | ||||
|         haptic_mode_decrease(); | ||||
|     } | ||||
|     if (keycode == HPT_DWLI && record->event.pressed) { | ||||
|         haptic_dwell_increase(); | ||||
|     } | ||||
|     if (keycode == HPT_DWLD && record->event.pressed) { | ||||
|         haptic_dwell_decrease(); | ||||
|     } | ||||
|     if (haptic_config.enable) { | ||||
|         if (record->event.pressed) { | ||||
|             // keypress
 | ||||
|             if (haptic_config.feedback < 2) { | ||||
|                 haptic_play(); | ||||
|             } | ||||
|         } else { | ||||
|             // keyrelease
 | ||||
|             if (haptic_config.feedback > 0) { | ||||
|                 haptic_play(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void haptic_shutdown(void) { | ||||
|   #ifdef SOLENOID_ENABLE | ||||
|   solenoid_shutdown(); | ||||
|   #endif | ||||
| 
 | ||||
| #ifdef SOLENOID_ENABLE | ||||
|     solenoid_shutdown(); | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -20,63 +20,57 @@ | |||
| #include <stdbool.h> | ||||
| #include "quantum.h" | ||||
| #ifdef DRV2605L | ||||
| #include "DRV2605L.h" | ||||
| #    include "DRV2605L.h" | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #ifndef HAPTIC_FEEDBACK_DEFAULT | ||||
| #define HAPTIC_FEEDBACK_DEFAULT 0 | ||||
| #    define HAPTIC_FEEDBACK_DEFAULT 0 | ||||
| #endif | ||||
| #ifndef HAPTIC_MODE_DEFAULT | ||||
| #define HAPTIC_MODE_DEFAULT DRV_MODE_DEFAULT | ||||
| #    define HAPTIC_MODE_DEFAULT DRV_MODE_DEFAULT | ||||
| #endif | ||||
| 
 | ||||
| /* EEPROM config settings */ | ||||
| typedef union { | ||||
|   uint32_t raw; | ||||
|   struct { | ||||
|     bool     enable    :1; | ||||
|     uint8_t  feedback  :2; | ||||
|     uint8_t  mode      :7; | ||||
|     bool     buzz      :1; | ||||
|     uint8_t  dwell     :7; | ||||
|     uint16_t reserved  :16;  | ||||
|   }; | ||||
|     uint32_t raw; | ||||
|     struct { | ||||
|         bool     enable : 1; | ||||
|         uint8_t  feedback : 2; | ||||
|         uint8_t  mode : 7; | ||||
|         bool     buzz : 1; | ||||
|         uint8_t  dwell : 7; | ||||
|         uint16_t reserved : 16; | ||||
|     }; | ||||
| } haptic_config_t; | ||||
| 
 | ||||
| typedef enum HAPTIC_FEEDBACK{ | ||||
|   KEY_PRESS, | ||||
|   KEY_PRESS_RELEASE, | ||||
|   KEY_RELEASE, | ||||
|   HAPTIC_FEEDBACK_MAX, | ||||
| typedef enum HAPTIC_FEEDBACK { | ||||
|     KEY_PRESS, | ||||
|     KEY_PRESS_RELEASE, | ||||
|     KEY_RELEASE, | ||||
|     HAPTIC_FEEDBACK_MAX, | ||||
| } HAPTIC_FEEDBACK; | ||||
| 
 | ||||
| bool process_haptic(uint16_t keycode, keyrecord_t *record); | ||||
| void haptic_init(void); | ||||
| void haptic_task(void); | ||||
| void eeconfig_debug_haptic(void); | ||||
| void haptic_enable(void); | ||||
| void haptic_disable(void); | ||||
| void haptic_toggle(void); | ||||
| void haptic_feedback_toggle(void); | ||||
| void haptic_mode_increase(void); | ||||
| void haptic_mode_decrease(void); | ||||
| void haptic_mode(uint8_t mode); | ||||
| void haptic_reset(void); | ||||
| void haptic_set_feedback(uint8_t feedback); | ||||
| void haptic_set_mode(uint8_t mode); | ||||
| void haptic_set_dwell(uint8_t dwell); | ||||
| void haptic_set_buzz(uint8_t buzz); | ||||
| void haptic_buzz_toggle(void); | ||||
| bool    process_haptic(uint16_t keycode, keyrecord_t *record); | ||||
| void    haptic_init(void); | ||||
| void    haptic_task(void); | ||||
| void    eeconfig_debug_haptic(void); | ||||
| void    haptic_enable(void); | ||||
| void    haptic_disable(void); | ||||
| void    haptic_toggle(void); | ||||
| void    haptic_feedback_toggle(void); | ||||
| void    haptic_mode_increase(void); | ||||
| void    haptic_mode_decrease(void); | ||||
| void    haptic_mode(uint8_t mode); | ||||
| void    haptic_reset(void); | ||||
| void    haptic_set_feedback(uint8_t feedback); | ||||
| void    haptic_set_mode(uint8_t mode); | ||||
| void    haptic_set_dwell(uint8_t dwell); | ||||
| void    haptic_set_buzz(uint8_t buzz); | ||||
| void    haptic_buzz_toggle(void); | ||||
| uint8_t haptic_get_mode(void); | ||||
| uint8_t haptic_get_feedback(void); | ||||
| void haptic_dwell_increase(void); | ||||
| void haptic_dwell_decrease(void); | ||||
| void    haptic_dwell_increase(void); | ||||
| void    haptic_dwell_decrease(void); | ||||
| 
 | ||||
| void haptic_play(void); | ||||
| void haptic_shutdown(void); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,91 +19,77 @@ | |||
| #include "solenoid.h" | ||||
| #include "haptic.h" | ||||
| 
 | ||||
| bool solenoid_on = false; | ||||
| bool solenoid_buzzing = false; | ||||
| uint16_t solenoid_start = 0; | ||||
| uint8_t solenoid_dwell = SOLENOID_DEFAULT_DWELL; | ||||
| bool     solenoid_on      = false; | ||||
| bool     solenoid_buzzing = false; | ||||
| uint16_t solenoid_start   = 0; | ||||
| uint8_t  solenoid_dwell   = SOLENOID_DEFAULT_DWELL; | ||||
| 
 | ||||
| extern haptic_config_t haptic_config; | ||||
| 
 | ||||
| void solenoid_buzz_on(void) { haptic_set_buzz(1); } | ||||
| 
 | ||||
| void solenoid_buzz_on(void) { | ||||
|   haptic_set_buzz(1); | ||||
| } | ||||
| 
 | ||||
| void solenoid_buzz_off(void) { | ||||
|   haptic_set_buzz(0); | ||||
| } | ||||
| 
 | ||||
| void solenoid_set_buzz(int buzz) { | ||||
|   haptic_set_buzz(buzz); | ||||
| } | ||||
| void solenoid_buzz_off(void) { haptic_set_buzz(0); } | ||||
| 
 | ||||
| void solenoid_set_buzz(int buzz) { haptic_set_buzz(buzz); } | ||||
| 
 | ||||
| void solenoid_dwell_minus(uint8_t solenoid_dwell) { | ||||
|   if (solenoid_dwell > 0) solenoid_dwell--; | ||||
|     if (solenoid_dwell > 0) solenoid_dwell--; | ||||
| } | ||||
| 
 | ||||
| void solenoid_dwell_plus(uint8_t solenoid_dwell) { | ||||
|   if (solenoid_dwell < SOLENOID_MAX_DWELL) solenoid_dwell++; | ||||
|     if (solenoid_dwell < SOLENOID_MAX_DWELL) solenoid_dwell++; | ||||
| } | ||||
| 
 | ||||
| void solenoid_set_dwell(uint8_t dwell) { | ||||
|   solenoid_dwell = dwell; | ||||
| } | ||||
| void solenoid_set_dwell(uint8_t dwell) { solenoid_dwell = dwell; } | ||||
| 
 | ||||
| void solenoid_stop(void) { | ||||
|   writePinLow(SOLENOID_PIN); | ||||
|   solenoid_on = false; | ||||
|   solenoid_buzzing = false; | ||||
|     writePinLow(SOLENOID_PIN); | ||||
|     solenoid_on      = false; | ||||
|     solenoid_buzzing = false; | ||||
| } | ||||
| 
 | ||||
| void solenoid_fire(void) { | ||||
|   if (!haptic_config.buzz && solenoid_on) return; | ||||
|   if (haptic_config.buzz && solenoid_buzzing) return; | ||||
|     if (!haptic_config.buzz && solenoid_on) return; | ||||
|     if (haptic_config.buzz && solenoid_buzzing) return; | ||||
| 
 | ||||
|   solenoid_on = true; | ||||
|   solenoid_buzzing = true; | ||||
|   solenoid_start = timer_read(); | ||||
|   writePinHigh(SOLENOID_PIN); | ||||
|     solenoid_on      = true; | ||||
|     solenoid_buzzing = true; | ||||
|     solenoid_start   = timer_read(); | ||||
|     writePinHigh(SOLENOID_PIN); | ||||
| } | ||||
| 
 | ||||
| void solenoid_check(void) { | ||||
|   uint16_t elapsed = 0; | ||||
|     uint16_t elapsed = 0; | ||||
| 
 | ||||
|   if (!solenoid_on) return; | ||||
|     if (!solenoid_on) return; | ||||
| 
 | ||||
|   elapsed = timer_elapsed(solenoid_start); | ||||
|     elapsed = timer_elapsed(solenoid_start); | ||||
| 
 | ||||
|   //Check if it's time to finish this solenoid click cycle
 | ||||
|   if (elapsed > solenoid_dwell) { | ||||
|     solenoid_stop(); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   //Check whether to buzz the solenoid on and off
 | ||||
|   if (haptic_config.buzz) { | ||||
|     if (elapsed / SOLENOID_MIN_DWELL % 2 == 0){ | ||||
|       if (!solenoid_buzzing) { | ||||
|         solenoid_buzzing = true; | ||||
|         writePinHigh(SOLENOID_PIN); | ||||
|       } | ||||
|     // Check if it's time to finish this solenoid click cycle
 | ||||
|     if (elapsed > solenoid_dwell) { | ||||
|         solenoid_stop(); | ||||
|         return; | ||||
|     } | ||||
|     else { | ||||
|       if (solenoid_buzzing) { | ||||
|         solenoid_buzzing = false; | ||||
|         writePinLow(SOLENOID_PIN); | ||||
|       } | ||||
| 
 | ||||
|     // Check whether to buzz the solenoid on and off
 | ||||
|     if (haptic_config.buzz) { | ||||
|         if (elapsed / SOLENOID_MIN_DWELL % 2 == 0) { | ||||
|             if (!solenoid_buzzing) { | ||||
|                 solenoid_buzzing = true; | ||||
|                 writePinHigh(SOLENOID_PIN); | ||||
|             } | ||||
|         } else { | ||||
|             if (solenoid_buzzing) { | ||||
|                 solenoid_buzzing = false; | ||||
|                 writePinLow(SOLENOID_PIN); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void solenoid_setup(void) { | ||||
|   setPinOutput(SOLENOID_PIN); | ||||
|   solenoid_fire(); | ||||
|     setPinOutput(SOLENOID_PIN); | ||||
|     solenoid_fire(); | ||||
| } | ||||
| 
 | ||||
| void solenoid_shutdown(void) { | ||||
|   writePinLow(SOLENOID_PIN); | ||||
| 
 | ||||
| } | ||||
| void solenoid_shutdown(void) { writePinLow(SOLENOID_PIN); } | ||||
|  |  | |||
|  | @ -18,23 +18,23 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #ifndef SOLENOID_DEFAULT_DWELL | ||||
| #define SOLENOID_DEFAULT_DWELL 12 | ||||
| #    define SOLENOID_DEFAULT_DWELL 12 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef SOLENOID_MAX_DWELL | ||||
| #define SOLENOID_MAX_DWELL 100 | ||||
| #    define SOLENOID_MAX_DWELL 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef SOLENOID_MIN_DWELL | ||||
| #define SOLENOID_MIN_DWELL 4 | ||||
| #    define SOLENOID_MIN_DWELL 4 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef SOLENOID_ACTIVE | ||||
| #define SOLENOID_ACTIVE false | ||||
| #    define SOLENOID_ACTIVE false | ||||
| #endif | ||||
| 
 | ||||
| #ifndef SOLENOID_PIN | ||||
| #define SOLENOID_PIN F6 | ||||
| #    define SOLENOID_PIN F6 | ||||
| #endif | ||||
| 
 | ||||
| void solenoid_buzz_on(void); | ||||
|  |  | |||
|  | @ -35,68 +35,62 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
 | ||||
| // If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB
 | ||||
| uint8_t g_pwm_buffer[18]; | ||||
| bool g_pwm_buffer_update_required = false; | ||||
| bool    g_pwm_buffer_update_required = false; | ||||
| 
 | ||||
| void IS31FL3218_write_register( uint8_t reg, uint8_t data ) | ||||
| { | ||||
| 	g_twi_transfer_buffer[0] = reg; | ||||
| 	g_twi_transfer_buffer[1] = data; | ||||
| 	i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
| void IS31FL3218_write_register(uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
|     i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| void IS31FL3218_write_pwm_buffer( uint8_t *pwm_buffer ) | ||||
| { | ||||
| 	g_twi_transfer_buffer[0] = ISSI_REG_PWM; | ||||
| 	for ( int i=0; i<18; i++ ) { | ||||
| 		g_twi_transfer_buffer[1+i] = pwm_buffer[i]; | ||||
| 	} | ||||
| 	 | ||||
| 	i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT); | ||||
| void IS31FL3218_write_pwm_buffer(uint8_t *pwm_buffer) { | ||||
|     g_twi_transfer_buffer[0] = ISSI_REG_PWM; | ||||
|     for (int i = 0; i < 18; i++) { | ||||
|         g_twi_transfer_buffer[1 + i] = pwm_buffer[i]; | ||||
|     } | ||||
| 
 | ||||
|     i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| void IS31FL3218_init(void) | ||||
| { | ||||
| 	// In case we ever want to reinitialize (?)
 | ||||
| 	IS31FL3218_write_register( ISSI_REG_RESET, 0x00 ); | ||||
| 	 | ||||
| 	// Turn off software shutdown
 | ||||
| 	IS31FL3218_write_register( ISSI_REG_SHUTDOWN, 0x01 ); | ||||
| void IS31FL3218_init(void) { | ||||
|     // In case we ever want to reinitialize (?)
 | ||||
|     IS31FL3218_write_register(ISSI_REG_RESET, 0x00); | ||||
| 
 | ||||
| 	// Set all PWM values to zero
 | ||||
| 	for ( uint8_t i = 0; i < 18; i++ ) { | ||||
| 		IS31FL3218_write_register( ISSI_REG_PWM+i, 0x00 ); | ||||
| 	} | ||||
| 	 | ||||
| 	// Enable all channels
 | ||||
| 	for ( uint8_t i = 0; i < 3; i++ ) { | ||||
| 		IS31FL3218_write_register( ISSI_REG_CONTROL+i, 0b00111111 ); | ||||
| 	} | ||||
| 	 | ||||
| 	// Load PWM registers and LED Control register data
 | ||||
| 	IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 ); | ||||
|     // Turn off software shutdown
 | ||||
|     IS31FL3218_write_register(ISSI_REG_SHUTDOWN, 0x01); | ||||
| 
 | ||||
|     // Set all PWM values to zero
 | ||||
|     for (uint8_t i = 0; i < 18; i++) { | ||||
|         IS31FL3218_write_register(ISSI_REG_PWM + i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Enable all channels
 | ||||
|     for (uint8_t i = 0; i < 3; i++) { | ||||
|         IS31FL3218_write_register(ISSI_REG_CONTROL + i, 0b00111111); | ||||
|     } | ||||
| 
 | ||||
|     // Load PWM registers and LED Control register data
 | ||||
|     IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); | ||||
| } | ||||
| 
 | ||||
| void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
| 	g_pwm_buffer[index * 3 + 0] = red; | ||||
| 	g_pwm_buffer[index * 3 + 1] = green; | ||||
| 	g_pwm_buffer[index * 3 + 2] = blue; | ||||
| 	g_pwm_buffer_update_required = true; | ||||
| void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     g_pwm_buffer[index * 3 + 0]  = red; | ||||
|     g_pwm_buffer[index * 3 + 1]  = green; | ||||
|     g_pwm_buffer[index * 3 + 2]  = blue; | ||||
|     g_pwm_buffer_update_required = true; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
| 	for ( int i = 0; i < 6; i++ ) { | ||||
| 		IS31FL3218_set_color( i, red, green, blue ); | ||||
| 	} | ||||
| void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < 6; i++) { | ||||
|         IS31FL3218_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3218_update_pwm_buffers(void) | ||||
| { | ||||
| 	if ( g_pwm_buffer_update_required ) { | ||||
| 		IS31FL3218_write_pwm_buffer( g_pwm_buffer ); | ||||
| 		// Load PWM registers and LED Control register data
 | ||||
| 		IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 ); | ||||
| 	} | ||||
| 	g_pwm_buffer_update_required = false; | ||||
| void IS31FL3218_update_pwm_buffers(void) { | ||||
|     if (g_pwm_buffer_update_required) { | ||||
|         IS31FL3218_write_pwm_buffer(g_pwm_buffer); | ||||
|         // Load PWM registers and LED Control register data
 | ||||
|         IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); | ||||
|     } | ||||
|     g_pwm_buffer_update_required = false; | ||||
| } | ||||
|  |  | |||
|  | @ -19,6 +19,6 @@ | |||
| #include <stdbool.h> | ||||
| 
 | ||||
| void IS31FL3218_init(void); | ||||
| void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3218_update_pwm_buffers(void); | ||||
|  |  | |||
|  | @ -17,11 +17,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <util/delay.h> | ||||
| #else | ||||
| #include "wait.h" | ||||
| #    include "wait.h" | ||||
| #endif | ||||
| 
 | ||||
| #include <stdint.h> | ||||
|  | @ -41,7 +41,7 @@ | |||
| // 0b1110110 AD <-> SDA
 | ||||
| #define ISSI_ADDR_DEFAULT 0x74 | ||||
| 
 | ||||
| #define ISSI_REG_CONFIG  0x00 | ||||
| #define ISSI_REG_CONFIG 0x00 | ||||
| #define ISSI_REG_CONFIG_PICTUREMODE 0x00 | ||||
| #define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 | ||||
| #define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 | ||||
|  | @ -50,20 +50,20 @@ | |||
| #define ISSI_CONF_AUTOFRAMEMODE 0x04 | ||||
| #define ISSI_CONF_AUDIOMODE 0x08 | ||||
| 
 | ||||
| #define ISSI_REG_PICTUREFRAME  0x01 | ||||
| #define ISSI_REG_PICTUREFRAME 0x01 | ||||
| 
 | ||||
| #define ISSI_REG_SHUTDOWN 0x0A | ||||
| #define ISSI_REG_AUDIOSYNC 0x06 | ||||
| 
 | ||||
| #define ISSI_COMMANDREGISTER 0xFD | ||||
| #define ISSI_BANK_FUNCTIONREG 0x0B    // helpfully called 'page nine'
 | ||||
| #define ISSI_BANK_FUNCTIONREG 0x0B  // helpfully called 'page nine'
 | ||||
| 
 | ||||
| #ifndef ISSI_TIMEOUT | ||||
|   #define ISSI_TIMEOUT 100 | ||||
| #    define ISSI_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ISSI_PERSISTENCE | ||||
|   #define ISSI_PERSISTENCE 0 | ||||
| #    define ISSI_PERSISTENCE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Transfer buffer for TWITransmitData()
 | ||||
|  | @ -75,17 +75,17 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
 | ||||
| // probably not worth the extra complexity.
 | ||||
| uint8_t g_pwm_buffer[LED_DRIVER_COUNT][144]; | ||||
| bool g_pwm_buffer_update_required = false; | ||||
| bool    g_pwm_buffer_update_required = false; | ||||
| 
 | ||||
| /* There's probably a better way to init this... */ | ||||
| #if LED_DRIVER_COUNT == 1 | ||||
|     uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}}; | ||||
| uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}}; | ||||
| #elif LED_DRIVER_COUNT == 2 | ||||
|     uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}}; | ||||
| uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}}; | ||||
| #elif LED_DRIVER_COUNT == 3 | ||||
|     uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}}; | ||||
| uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}}; | ||||
| #elif LED_DRIVER_COUNT == 4 | ||||
|     uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}, {0}}; | ||||
| uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}, {0}}; | ||||
| #endif | ||||
| bool g_led_control_registers_update_required = false; | ||||
| 
 | ||||
|  | @ -103,20 +103,19 @@ bool g_led_control_registers_update_required = false; | |||
| // 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
 | ||||
| // 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
 | ||||
| 
 | ||||
| 
 | ||||
| void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) { | ||||
|               break; | ||||
|             } | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|     for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) { | ||||
|             break; | ||||
|         } | ||||
|     #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
|     #endif | ||||
|     } | ||||
| #else | ||||
|     i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||||
|  | @ -136,14 +135,13 @@ void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | |||
|             g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; | ||||
|         } | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|       for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) | ||||
|           break; | ||||
|       } | ||||
|     #else | ||||
|       i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
|     #endif | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; | ||||
|         } | ||||
| #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -196,7 +194,6 @@ void IS31FL3731_init(uint8_t addr) { | |||
|     // most usage after initialization is just writing PWM buffers in bank 0
 | ||||
|     // as there's not much point in double-buffering
 | ||||
|     IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_set_value(int index, uint8_t value) { | ||||
|  | @ -205,7 +202,7 @@ void IS31FL3731_set_value(int index, uint8_t value) { | |||
| 
 | ||||
|         // Subtract 0x24 to get the second index of g_pwm_buffer
 | ||||
|         g_pwm_buffer[led.driver][led.v - 0x24] = value; | ||||
|         g_pwm_buffer_update_required = true; | ||||
|         g_pwm_buffer_update_required           = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -216,10 +213,10 @@ void IS31FL3731_set_value_all(uint8_t value) { | |||
| } | ||||
| 
 | ||||
| void IS31FL3731_set_led_control_register(uint8_t index, bool value) { | ||||
|   is31_led led = g_is31_leds[index]; | ||||
|     is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|   uint8_t control_register = (led.v - 0x24) / 8; | ||||
|   uint8_t bit_value = (led.v - 0x24) % 8; | ||||
|     uint8_t control_register = (led.v - 0x24) / 8; | ||||
|     uint8_t bit_value        = (led.v - 0x24) % 8; | ||||
| 
 | ||||
|     if (value) { | ||||
|         g_led_control_registers[led.driver][control_register] |= (1 << bit_value); | ||||
|  | @ -239,7 +236,7 @@ void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { | |||
| 
 | ||||
| void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { | ||||
|     if (g_led_control_registers_update_required) { | ||||
|         for (int i=0; i<18; i++) { | ||||
|         for (int i = 0; i < 18; i++) { | ||||
|             IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -16,14 +16,12 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef IS31FL3731_DRIVER_H | ||||
| #define IS31FL3731_DRIVER_H | ||||
| 
 | ||||
| 
 | ||||
| typedef struct is31_led { | ||||
|   uint8_t driver:2; | ||||
|   uint8_t v; | ||||
|     uint8_t driver : 2; | ||||
|     uint8_t v; | ||||
| } __attribute__((packed)) is31_led; | ||||
| 
 | ||||
| extern const is31_led g_is31_leds[LED_DRIVER_LED_COUNT]; | ||||
|  | @ -44,16 +42,16 @@ void IS31FL3731_set_led_control_register(uint8_t index, bool value); | |||
| void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); | ||||
| void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | ||||
| 
 | ||||
| #define C1_1  0x24 | ||||
| #define C1_2  0x25 | ||||
| #define C1_3  0x26 | ||||
| #define C1_4  0x27 | ||||
| #define C1_5  0x28 | ||||
| #define C1_6  0x29 | ||||
| #define C1_7  0x2A | ||||
| #define C1_8  0x2B | ||||
| #define C1_1 0x24 | ||||
| #define C1_2 0x25 | ||||
| #define C1_3 0x26 | ||||
| #define C1_4 0x27 | ||||
| #define C1_5 0x28 | ||||
| #define C1_6 0x29 | ||||
| #define C1_7 0x2A | ||||
| #define C1_8 0x2B | ||||
| 
 | ||||
| #define C1_9  0x2C | ||||
| #define C1_9 0x2C | ||||
| #define C1_10 0x2D | ||||
| #define C1_11 0x2E | ||||
| #define C1_12 0x2F | ||||
|  | @ -62,16 +60,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C1_15 0x32 | ||||
| #define C1_16 0x33 | ||||
| 
 | ||||
| #define C2_1  0x34 | ||||
| #define C2_2  0x35 | ||||
| #define C2_3  0x36 | ||||
| #define C2_4  0x37 | ||||
| #define C2_5  0x38 | ||||
| #define C2_6  0x39 | ||||
| #define C2_7  0x3A | ||||
| #define C2_8  0x3B | ||||
| #define C2_1 0x34 | ||||
| #define C2_2 0x35 | ||||
| #define C2_3 0x36 | ||||
| #define C2_4 0x37 | ||||
| #define C2_5 0x38 | ||||
| #define C2_6 0x39 | ||||
| #define C2_7 0x3A | ||||
| #define C2_8 0x3B | ||||
| 
 | ||||
| #define C2_9  0x3C | ||||
| #define C2_9 0x3C | ||||
| #define C2_10 0x3D | ||||
| #define C2_11 0x3E | ||||
| #define C2_12 0x3F | ||||
|  | @ -80,16 +78,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C2_15 0x42 | ||||
| #define C2_16 0x43 | ||||
| 
 | ||||
| #define C3_1  0x44 | ||||
| #define C3_2  0x45 | ||||
| #define C3_3  0x46 | ||||
| #define C3_4  0x47 | ||||
| #define C3_5  0x48 | ||||
| #define C3_6  0x49 | ||||
| #define C3_7  0x4A | ||||
| #define C3_8  0x4B | ||||
| #define C3_1 0x44 | ||||
| #define C3_2 0x45 | ||||
| #define C3_3 0x46 | ||||
| #define C3_4 0x47 | ||||
| #define C3_5 0x48 | ||||
| #define C3_6 0x49 | ||||
| #define C3_7 0x4A | ||||
| #define C3_8 0x4B | ||||
| 
 | ||||
| #define C3_9  0x4C | ||||
| #define C3_9 0x4C | ||||
| #define C3_10 0x4D | ||||
| #define C3_11 0x4E | ||||
| #define C3_12 0x4F | ||||
|  | @ -98,16 +96,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C3_15 0x52 | ||||
| #define C3_16 0x53 | ||||
| 
 | ||||
| #define C4_1  0x54 | ||||
| #define C4_2  0x55 | ||||
| #define C4_3  0x56 | ||||
| #define C4_4  0x57 | ||||
| #define C4_5  0x58 | ||||
| #define C4_6  0x59 | ||||
| #define C4_7  0x5A | ||||
| #define C4_8  0x5B | ||||
| #define C4_1 0x54 | ||||
| #define C4_2 0x55 | ||||
| #define C4_3 0x56 | ||||
| #define C4_4 0x57 | ||||
| #define C4_5 0x58 | ||||
| #define C4_6 0x59 | ||||
| #define C4_7 0x5A | ||||
| #define C4_8 0x5B | ||||
| 
 | ||||
| #define C4_9  0x5C | ||||
| #define C4_9 0x5C | ||||
| #define C4_10 0x5D | ||||
| #define C4_11 0x5E | ||||
| #define C4_12 0x5F | ||||
|  | @ -116,16 +114,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C4_15 0x62 | ||||
| #define C4_16 0x63 | ||||
| 
 | ||||
| #define C5_1  0x64 | ||||
| #define C5_2  0x65 | ||||
| #define C5_3  0x66 | ||||
| #define C5_4  0x67 | ||||
| #define C5_5  0x68 | ||||
| #define C5_6  0x69 | ||||
| #define C5_7  0x6A | ||||
| #define C5_8  0x6B | ||||
| #define C5_1 0x64 | ||||
| #define C5_2 0x65 | ||||
| #define C5_3 0x66 | ||||
| #define C5_4 0x67 | ||||
| #define C5_5 0x68 | ||||
| #define C5_6 0x69 | ||||
| #define C5_7 0x6A | ||||
| #define C5_8 0x6B | ||||
| 
 | ||||
| #define C5_9  0x6C | ||||
| #define C5_9 0x6C | ||||
| #define C5_10 0x6D | ||||
| #define C5_11 0x6E | ||||
| #define C5_12 0x6F | ||||
|  | @ -134,16 +132,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C5_15 0x72 | ||||
| #define C5_16 0x73 | ||||
| 
 | ||||
| #define C6_1  0x74 | ||||
| #define C6_2  0x75 | ||||
| #define C6_3  0x76 | ||||
| #define C6_4  0x77 | ||||
| #define C6_5  0x78 | ||||
| #define C6_6  0x79 | ||||
| #define C6_7  0x7A | ||||
| #define C6_8  0x7B | ||||
| #define C6_1 0x74 | ||||
| #define C6_2 0x75 | ||||
| #define C6_3 0x76 | ||||
| #define C6_4 0x77 | ||||
| #define C6_5 0x78 | ||||
| #define C6_6 0x79 | ||||
| #define C6_7 0x7A | ||||
| #define C6_8 0x7B | ||||
| 
 | ||||
| #define C6_9  0x7C | ||||
| #define C6_9 0x7C | ||||
| #define C6_10 0x7D | ||||
| #define C6_11 0x7E | ||||
| #define C6_12 0x7F | ||||
|  | @ -152,16 +150,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C6_15 0x82 | ||||
| #define C6_16 0x83 | ||||
| 
 | ||||
| #define C7_1  0x84 | ||||
| #define C7_2  0x85 | ||||
| #define C7_3  0x86 | ||||
| #define C7_4  0x87 | ||||
| #define C7_5  0x88 | ||||
| #define C7_6  0x89 | ||||
| #define C7_7  0x8A | ||||
| #define C7_8  0x8B | ||||
| #define C7_1 0x84 | ||||
| #define C7_2 0x85 | ||||
| #define C7_3 0x86 | ||||
| #define C7_4 0x87 | ||||
| #define C7_5 0x88 | ||||
| #define C7_6 0x89 | ||||
| #define C7_7 0x8A | ||||
| #define C7_8 0x8B | ||||
| 
 | ||||
| #define C7_9  0x8C | ||||
| #define C7_9 0x8C | ||||
| #define C7_10 0x8D | ||||
| #define C7_11 0x8E | ||||
| #define C7_12 0x8F | ||||
|  | @ -170,16 +168,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C7_15 0x92 | ||||
| #define C7_16 0x93 | ||||
| 
 | ||||
| #define C8_1  0x94 | ||||
| #define C8_2  0x95 | ||||
| #define C8_3  0x96 | ||||
| #define C8_4  0x97 | ||||
| #define C8_5  0x98 | ||||
| #define C8_6  0x99 | ||||
| #define C8_7  0x9A | ||||
| #define C8_8  0x9B | ||||
| #define C8_1 0x94 | ||||
| #define C8_2 0x95 | ||||
| #define C8_3 0x96 | ||||
| #define C8_4 0x97 | ||||
| #define C8_5 0x98 | ||||
| #define C8_6 0x99 | ||||
| #define C8_7 0x9A | ||||
| #define C8_8 0x9B | ||||
| 
 | ||||
| #define C8_9  0x9C | ||||
| #define C8_9 0x9C | ||||
| #define C8_10 0x9D | ||||
| #define C8_11 0x9E | ||||
| #define C8_12 0x9F | ||||
|  | @ -188,16 +186,16 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C8_15 0xA2 | ||||
| #define C8_16 0xA3 | ||||
| 
 | ||||
| #define C9_1  0xA4 | ||||
| #define C9_2  0xA5 | ||||
| #define C9_3  0xA6 | ||||
| #define C9_4  0xA7 | ||||
| #define C9_5  0xA8 | ||||
| #define C9_6  0xA9 | ||||
| #define C9_7  0xAA | ||||
| #define C9_8  0xAB | ||||
| #define C9_1 0xA4 | ||||
| #define C9_2 0xA5 | ||||
| #define C9_3 0xA6 | ||||
| #define C9_4 0xA7 | ||||
| #define C9_5 0xA8 | ||||
| #define C9_6 0xA9 | ||||
| #define C9_7 0xAA | ||||
| #define C9_8 0xAB | ||||
| 
 | ||||
| #define C9_9  0xAC | ||||
| #define C9_9 0xAC | ||||
| #define C9_10 0xAD | ||||
| #define C9_11 0xAE | ||||
| #define C9_12 0xAF | ||||
|  | @ -206,5 +204,4 @@ void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | |||
| #define C9_15 0xB2 | ||||
| #define C9_16 0xB3 | ||||
| 
 | ||||
| 
 | ||||
| #endif // IS31FL3731_DRIVER_H
 | ||||
| #endif  // IS31FL3731_DRIVER_H
 | ||||
|  |  | |||
|  | @ -16,11 +16,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <util/delay.h> | ||||
| #else | ||||
| #include "wait.h" | ||||
| #    include "wait.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "is31fl3731.h" | ||||
|  | @ -37,7 +37,7 @@ | |||
| // 0b1110110 AD <-> SDA
 | ||||
| #define ISSI_ADDR_DEFAULT 0x74 | ||||
| 
 | ||||
| #define ISSI_REG_CONFIG  0x00 | ||||
| #define ISSI_REG_CONFIG 0x00 | ||||
| #define ISSI_REG_CONFIG_PICTUREMODE 0x00 | ||||
| #define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 | ||||
| #define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 | ||||
|  | @ -46,20 +46,20 @@ | |||
| #define ISSI_CONF_AUTOFRAMEMODE 0x04 | ||||
| #define ISSI_CONF_AUDIOMODE 0x08 | ||||
| 
 | ||||
| #define ISSI_REG_PICTUREFRAME  0x01 | ||||
| #define ISSI_REG_PICTUREFRAME 0x01 | ||||
| 
 | ||||
| #define ISSI_REG_SHUTDOWN 0x0A | ||||
| #define ISSI_REG_AUDIOSYNC 0x06 | ||||
| 
 | ||||
| #define ISSI_COMMANDREGISTER 0xFD | ||||
| #define ISSI_BANK_FUNCTIONREG 0x0B    // helpfully called 'page nine'
 | ||||
| #define ISSI_BANK_FUNCTIONREG 0x0B  // helpfully called 'page nine'
 | ||||
| 
 | ||||
| #ifndef ISSI_TIMEOUT | ||||
|   #define ISSI_TIMEOUT 100 | ||||
| #    define ISSI_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ISSI_PERSISTENCE | ||||
|   #define ISSI_PERSISTENCE 0 | ||||
| #    define ISSI_PERSISTENCE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Transfer buffer for TWITransmitData()
 | ||||
|  | @ -71,10 +71,10 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
 | ||||
| // probably not worth the extra complexity.
 | ||||
| uint8_t g_pwm_buffer[DRIVER_COUNT][144]; | ||||
| bool g_pwm_buffer_update_required[DRIVER_COUNT] = { false }; | ||||
| bool    g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; | ||||
| 
 | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } }; | ||||
| bool g_led_control_registers_update_required[DRIVER_COUNT] = { false }; | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][18]             = {{0}, {0}}; | ||||
| bool    g_led_control_registers_update_required[DRIVER_COUNT] = {false}; | ||||
| 
 | ||||
| // This is the bit pattern in the LED control registers
 | ||||
| // (for matrix A, add one to register for matrix B)
 | ||||
|  | @ -90,179 +90,159 @@ bool g_led_control_registers_update_required[DRIVER_COUNT] = { false }; | |||
| // 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
 | ||||
| // 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
 | ||||
| 
 | ||||
| 
 | ||||
| void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data ) | ||||
| { | ||||
| void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
| 
 | ||||
|   #if ISSI_PERSISTENCE > 0 | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|     for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|       if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) | ||||
|         break; | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; | ||||
|     } | ||||
|   #else | ||||
| #else | ||||
|     i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) | ||||
| { | ||||
| void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||||
|     // assumes bank is already selected
 | ||||
| 
 | ||||
|     // transmit PWM registers in 9 transfers of 16 bytes
 | ||||
|     // g_twi_transfer_buffer[] is 20 bytes
 | ||||
| 
 | ||||
|     // iterate over the pwm_buffer contents at 16 byte intervals
 | ||||
|     for ( int i = 0; i < 144; i += 16 ) { | ||||
|     for (int i = 0; i < 144; i += 16) { | ||||
|         // set the first register, e.g. 0x24, 0x34, 0x44, etc.
 | ||||
|         g_twi_transfer_buffer[0] = 0x24 + i; | ||||
|         // copy the data from i to i+15
 | ||||
|         // device will auto-increment register for data after the first byte
 | ||||
|         // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
 | ||||
|         for ( int j = 0; j < 16; j++ ) { | ||||
|         for (int j = 0; j < 16; j++) { | ||||
|             g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; | ||||
|         } | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|       for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) | ||||
|           break; | ||||
|       } | ||||
|     #else | ||||
|       i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
|     #endif | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; | ||||
|         } | ||||
| #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_init( uint8_t addr ) | ||||
| { | ||||
| void IS31FL3731_init(uint8_t addr) { | ||||
|     // In order to avoid the LEDs being driven with garbage data
 | ||||
|     // in the LED driver's PWM registers, first enable software shutdown,
 | ||||
|     // then set up the mode and other settings, clear the PWM registers,
 | ||||
|     // then disable software shutdown.
 | ||||
| 
 | ||||
|     // select "function register" bank
 | ||||
|     IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); | ||||
|     IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); | ||||
| 
 | ||||
|     // enable software shutdown
 | ||||
|     IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 ); | ||||
|     // this delay was copied from other drivers, might not be needed
 | ||||
|     #ifdef __AVR__ | ||||
|     _delay_ms( 10 ); | ||||
|     #else | ||||
|     IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00); | ||||
| // this delay was copied from other drivers, might not be needed
 | ||||
| #ifdef __AVR__ | ||||
|     _delay_ms(10); | ||||
| #else | ||||
|     wait_ms(10); | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
|     // picture mode
 | ||||
|     IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE ); | ||||
|     IS31FL3731_write_register(addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE); | ||||
|     // display frame 0
 | ||||
|     IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 ); | ||||
|     IS31FL3731_write_register(addr, ISSI_REG_PICTUREFRAME, 0x00); | ||||
|     // audio sync off
 | ||||
|     IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 ); | ||||
|     IS31FL3731_write_register(addr, ISSI_REG_AUDIOSYNC, 0x00); | ||||
| 
 | ||||
|     // select bank 0
 | ||||
|     IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 ); | ||||
|     IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); | ||||
| 
 | ||||
|     // turn off all LEDs in the LED control register
 | ||||
|     for ( int i = 0x00; i <= 0x11; i++ ) | ||||
|     { | ||||
|         IS31FL3731_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0x11; i++) { | ||||
|         IS31FL3731_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // turn off all LEDs in the blink control register (not really needed)
 | ||||
|     for ( int i = 0x12; i <= 0x23; i++ ) | ||||
|     { | ||||
|         IS31FL3731_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x12; i <= 0x23; i++) { | ||||
|         IS31FL3731_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // set PWM on all LEDs to 0
 | ||||
|     for ( int i = 0x24; i <= 0xB3; i++ ) | ||||
|     { | ||||
|         IS31FL3731_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x24; i <= 0xB3; i++) { | ||||
|         IS31FL3731_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // select "function register" bank
 | ||||
|     IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); | ||||
|     IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); | ||||
| 
 | ||||
|     // disable software shutdown
 | ||||
|     IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 ); | ||||
|     IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x01); | ||||
| 
 | ||||
|     // select bank 0 and leave it selected.
 | ||||
|     // most usage after initialization is just writing PWM buffers in bank 0
 | ||||
|     // as there's not much point in double-buffering
 | ||||
|     IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 ); | ||||
| 
 | ||||
|     IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     if ( index >= 0 && index < DRIVER_LED_TOTAL ) { | ||||
| void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index >= 0 && index < DRIVER_LED_TOTAL) { | ||||
|         is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|         // Subtract 0x24 to get the second index of g_pwm_buffer
 | ||||
|         g_pwm_buffer[led.driver][led.r - 0x24] = red; | ||||
|         g_pwm_buffer[led.driver][led.g - 0x24] = green; | ||||
|         g_pwm_buffer[led.driver][led.b - 0x24] = blue; | ||||
|         g_pwm_buffer[led.driver][led.r - 0x24]   = red; | ||||
|         g_pwm_buffer[led.driver][led.g - 0x24]   = green; | ||||
|         g_pwm_buffer[led.driver][led.b - 0x24]   = blue; | ||||
|         g_pwm_buffer_update_required[led.driver] = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) | ||||
|     { | ||||
|         IS31FL3731_set_color( i, red, green, blue ); | ||||
| void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < DRIVER_LED_TOTAL; i++) { | ||||
|         IS31FL3731_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) | ||||
| { | ||||
| void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { | ||||
|     is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|     uint8_t control_register_r = (led.r - 0x24) / 8; | ||||
|     uint8_t control_register_g = (led.g - 0x24) / 8; | ||||
|     uint8_t control_register_b = (led.b - 0x24) / 8; | ||||
|     uint8_t bit_r = (led.r - 0x24) % 8; | ||||
|     uint8_t bit_g = (led.g - 0x24) % 8; | ||||
|     uint8_t bit_b = (led.b - 0x24) % 8; | ||||
|     uint8_t bit_r              = (led.r - 0x24) % 8; | ||||
|     uint8_t bit_g              = (led.g - 0x24) % 8; | ||||
|     uint8_t bit_b              = (led.b - 0x24) % 8; | ||||
| 
 | ||||
|     if ( red ) { | ||||
|     if (red) { | ||||
|         g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); | ||||
|     } | ||||
|     if ( green ) { | ||||
|     if (green) { | ||||
|         g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); | ||||
|     } | ||||
|     if ( blue ) { | ||||
|     if (blue) { | ||||
|         g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); | ||||
|     } | ||||
| 
 | ||||
|     g_led_control_registers_update_required[led.driver] = true; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_update_pwm_buffers( uint8_t addr, uint8_t index ) | ||||
| { | ||||
|     if ( g_pwm_buffer_update_required[index] ) | ||||
|     { | ||||
|         IS31FL3731_write_pwm_buffer( addr, g_pwm_buffer[index] ); | ||||
| void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { | ||||
|     if (g_pwm_buffer_update_required[index]) { | ||||
|         IS31FL3731_write_pwm_buffer(addr, g_pwm_buffer[index]); | ||||
|     } | ||||
|     g_pwm_buffer_update_required[index] = false; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ) | ||||
| { | ||||
|     if ( g_led_control_registers_update_required[index] ) | ||||
|     { | ||||
|         for ( int i=0; i<18; i++ ) | ||||
|         { | ||||
|             IS31FL3731_write_register( addr, i, g_led_control_registers[index][i] ); | ||||
| void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { | ||||
|     if (g_led_control_registers_update_required[index]) { | ||||
|         for (int i = 0; i < 18; i++) { | ||||
|             IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -15,7 +15,6 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef IS31FL3731_DRIVER_H | ||||
| #define IS31FL3731_DRIVER_H | ||||
| 
 | ||||
|  | @ -23,40 +22,40 @@ | |||
| #include <stdbool.h> | ||||
| 
 | ||||
| typedef struct is31_led { | ||||
|   uint8_t driver:2; | ||||
|   uint8_t r; | ||||
|   uint8_t g; | ||||
|   uint8_t b; | ||||
|     uint8_t driver : 2; | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| } __attribute__((packed)) is31_led; | ||||
| 
 | ||||
| extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; | ||||
| 
 | ||||
| void IS31FL3731_init( uint8_t addr ); | ||||
| void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data ); | ||||
| void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); | ||||
| void IS31FL3731_init(uint8_t addr); | ||||
| void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||||
| void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||||
| 
 | ||||
| void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| 
 | ||||
| void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); | ||||
| void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue); | ||||
| 
 | ||||
| // This should not be called from an interrupt
 | ||||
| // (eg. from a timer interrupt).
 | ||||
| // Call this while idle (in between matrix scans).
 | ||||
| // If the buffer is dirty, it will update the driver with the buffer.
 | ||||
| void IS31FL3731_update_pwm_buffers( uint8_t addr, uint8_t index  ); | ||||
| void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | ||||
| void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); | ||||
| void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); | ||||
| 
 | ||||
| #define C1_1  0x24 | ||||
| #define C1_2  0x25 | ||||
| #define C1_3  0x26 | ||||
| #define C1_4  0x27 | ||||
| #define C1_5  0x28 | ||||
| #define C1_6  0x29 | ||||
| #define C1_7  0x2A | ||||
| #define C1_8  0x2B | ||||
| #define C1_1 0x24 | ||||
| #define C1_2 0x25 | ||||
| #define C1_3 0x26 | ||||
| #define C1_4 0x27 | ||||
| #define C1_5 0x28 | ||||
| #define C1_6 0x29 | ||||
| #define C1_7 0x2A | ||||
| #define C1_8 0x2B | ||||
| 
 | ||||
| #define C1_9  0x2C | ||||
| #define C1_9 0x2C | ||||
| #define C1_10 0x2D | ||||
| #define C1_11 0x2E | ||||
| #define C1_12 0x2F | ||||
|  | @ -65,16 +64,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C1_15 0x32 | ||||
| #define C1_16 0x33 | ||||
| 
 | ||||
| #define C2_1  0x34 | ||||
| #define C2_2  0x35 | ||||
| #define C2_3  0x36 | ||||
| #define C2_4  0x37 | ||||
| #define C2_5  0x38 | ||||
| #define C2_6  0x39 | ||||
| #define C2_7  0x3A | ||||
| #define C2_8  0x3B | ||||
| #define C2_1 0x34 | ||||
| #define C2_2 0x35 | ||||
| #define C2_3 0x36 | ||||
| #define C2_4 0x37 | ||||
| #define C2_5 0x38 | ||||
| #define C2_6 0x39 | ||||
| #define C2_7 0x3A | ||||
| #define C2_8 0x3B | ||||
| 
 | ||||
| #define C2_9  0x3C | ||||
| #define C2_9 0x3C | ||||
| #define C2_10 0x3D | ||||
| #define C2_11 0x3E | ||||
| #define C2_12 0x3F | ||||
|  | @ -83,16 +82,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C2_15 0x42 | ||||
| #define C2_16 0x43 | ||||
| 
 | ||||
| #define C3_1  0x44 | ||||
| #define C3_2  0x45 | ||||
| #define C3_3  0x46 | ||||
| #define C3_4  0x47 | ||||
| #define C3_5  0x48 | ||||
| #define C3_6  0x49 | ||||
| #define C3_7  0x4A | ||||
| #define C3_8  0x4B | ||||
| #define C3_1 0x44 | ||||
| #define C3_2 0x45 | ||||
| #define C3_3 0x46 | ||||
| #define C3_4 0x47 | ||||
| #define C3_5 0x48 | ||||
| #define C3_6 0x49 | ||||
| #define C3_7 0x4A | ||||
| #define C3_8 0x4B | ||||
| 
 | ||||
| #define C3_9  0x4C | ||||
| #define C3_9 0x4C | ||||
| #define C3_10 0x4D | ||||
| #define C3_11 0x4E | ||||
| #define C3_12 0x4F | ||||
|  | @ -101,16 +100,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C3_15 0x52 | ||||
| #define C3_16 0x53 | ||||
| 
 | ||||
| #define C4_1  0x54 | ||||
| #define C4_2  0x55 | ||||
| #define C4_3  0x56 | ||||
| #define C4_4  0x57 | ||||
| #define C4_5  0x58 | ||||
| #define C4_6  0x59 | ||||
| #define C4_7  0x5A | ||||
| #define C4_8  0x5B | ||||
| #define C4_1 0x54 | ||||
| #define C4_2 0x55 | ||||
| #define C4_3 0x56 | ||||
| #define C4_4 0x57 | ||||
| #define C4_5 0x58 | ||||
| #define C4_6 0x59 | ||||
| #define C4_7 0x5A | ||||
| #define C4_8 0x5B | ||||
| 
 | ||||
| #define C4_9  0x5C | ||||
| #define C4_9 0x5C | ||||
| #define C4_10 0x5D | ||||
| #define C4_11 0x5E | ||||
| #define C4_12 0x5F | ||||
|  | @ -119,16 +118,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C4_15 0x62 | ||||
| #define C4_16 0x63 | ||||
| 
 | ||||
| #define C5_1  0x64 | ||||
| #define C5_2  0x65 | ||||
| #define C5_3  0x66 | ||||
| #define C5_4  0x67 | ||||
| #define C5_5  0x68 | ||||
| #define C5_6  0x69 | ||||
| #define C5_7  0x6A | ||||
| #define C5_8  0x6B | ||||
| #define C5_1 0x64 | ||||
| #define C5_2 0x65 | ||||
| #define C5_3 0x66 | ||||
| #define C5_4 0x67 | ||||
| #define C5_5 0x68 | ||||
| #define C5_6 0x69 | ||||
| #define C5_7 0x6A | ||||
| #define C5_8 0x6B | ||||
| 
 | ||||
| #define C5_9  0x6C | ||||
| #define C5_9 0x6C | ||||
| #define C5_10 0x6D | ||||
| #define C5_11 0x6E | ||||
| #define C5_12 0x6F | ||||
|  | @ -137,16 +136,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C5_15 0x72 | ||||
| #define C5_16 0x73 | ||||
| 
 | ||||
| #define C6_1  0x74 | ||||
| #define C6_2  0x75 | ||||
| #define C6_3  0x76 | ||||
| #define C6_4  0x77 | ||||
| #define C6_5  0x78 | ||||
| #define C6_6  0x79 | ||||
| #define C6_7  0x7A | ||||
| #define C6_8  0x7B | ||||
| #define C6_1 0x74 | ||||
| #define C6_2 0x75 | ||||
| #define C6_3 0x76 | ||||
| #define C6_4 0x77 | ||||
| #define C6_5 0x78 | ||||
| #define C6_6 0x79 | ||||
| #define C6_7 0x7A | ||||
| #define C6_8 0x7B | ||||
| 
 | ||||
| #define C6_9  0x7C | ||||
| #define C6_9 0x7C | ||||
| #define C6_10 0x7D | ||||
| #define C6_11 0x7E | ||||
| #define C6_12 0x7F | ||||
|  | @ -155,16 +154,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C6_15 0x82 | ||||
| #define C6_16 0x83 | ||||
| 
 | ||||
| #define C7_1  0x84 | ||||
| #define C7_2  0x85 | ||||
| #define C7_3  0x86 | ||||
| #define C7_4  0x87 | ||||
| #define C7_5  0x88 | ||||
| #define C7_6  0x89 | ||||
| #define C7_7  0x8A | ||||
| #define C7_8  0x8B | ||||
| #define C7_1 0x84 | ||||
| #define C7_2 0x85 | ||||
| #define C7_3 0x86 | ||||
| #define C7_4 0x87 | ||||
| #define C7_5 0x88 | ||||
| #define C7_6 0x89 | ||||
| #define C7_7 0x8A | ||||
| #define C7_8 0x8B | ||||
| 
 | ||||
| #define C7_9  0x8C | ||||
| #define C7_9 0x8C | ||||
| #define C7_10 0x8D | ||||
| #define C7_11 0x8E | ||||
| #define C7_12 0x8F | ||||
|  | @ -173,16 +172,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C7_15 0x92 | ||||
| #define C7_16 0x93 | ||||
| 
 | ||||
| #define C8_1  0x94 | ||||
| #define C8_2  0x95 | ||||
| #define C8_3  0x96 | ||||
| #define C8_4  0x97 | ||||
| #define C8_5  0x98 | ||||
| #define C8_6  0x99 | ||||
| #define C8_7  0x9A | ||||
| #define C8_8  0x9B | ||||
| #define C8_1 0x94 | ||||
| #define C8_2 0x95 | ||||
| #define C8_3 0x96 | ||||
| #define C8_4 0x97 | ||||
| #define C8_5 0x98 | ||||
| #define C8_6 0x99 | ||||
| #define C8_7 0x9A | ||||
| #define C8_8 0x9B | ||||
| 
 | ||||
| #define C8_9  0x9C | ||||
| #define C8_9 0x9C | ||||
| #define C8_10 0x9D | ||||
| #define C8_11 0x9E | ||||
| #define C8_12 0x9F | ||||
|  | @ -191,16 +190,16 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C8_15 0xA2 | ||||
| #define C8_16 0xA3 | ||||
| 
 | ||||
| #define C9_1  0xA4 | ||||
| #define C9_2  0xA5 | ||||
| #define C9_3  0xA6 | ||||
| #define C9_4  0xA7 | ||||
| #define C9_5  0xA8 | ||||
| #define C9_6  0xA9 | ||||
| #define C9_7  0xAA | ||||
| #define C9_8  0xAB | ||||
| #define C9_1 0xA4 | ||||
| #define C9_2 0xA5 | ||||
| #define C9_3 0xA6 | ||||
| #define C9_4 0xA7 | ||||
| #define C9_5 0xA8 | ||||
| #define C9_6 0xA9 | ||||
| #define C9_7 0xAA | ||||
| #define C9_8 0xAB | ||||
| 
 | ||||
| #define C9_9  0xAC | ||||
| #define C9_9 0xAC | ||||
| #define C9_10 0xAD | ||||
| #define C9_11 0xAE | ||||
| #define C9_12 0xAF | ||||
|  | @ -209,6 +208,4 @@ void IS31FL3731_update_led_control_registers( uint8_t addr, uint8_t index ); | |||
| #define C9_15 0xB2 | ||||
| #define C9_16 0xB3 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif // IS31FL3731_DRIVER_H
 | ||||
| #endif  // IS31FL3731_DRIVER_H
 | ||||
|  |  | |||
|  | @ -17,11 +17,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <util/delay.h> | ||||
| #else | ||||
| #include "wait.h" | ||||
| #    include "wait.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "is31fl3733.h" | ||||
|  | @ -46,23 +46,23 @@ | |||
| #define ISSI_INTERRUPTMASKREGISTER 0xF0 | ||||
| #define ISSI_INTERRUPTSTATUSREGISTER 0xF1 | ||||
| 
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00 //PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01        //PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02 //PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03   //PG3
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00  // PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01         // PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02  // PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03    // PG3
 | ||||
| 
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00 //PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01 //PG3
 | ||||
| #define ISSI_REG_RESET 0x11// PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F //PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10 //PG3
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00  // PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01  // PG3
 | ||||
| #define ISSI_REG_RESET 0x11          // PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F       // PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10       // PG3
 | ||||
| 
 | ||||
| #ifndef ISSI_TIMEOUT | ||||
|   #define ISSI_TIMEOUT 100 | ||||
| #    define ISSI_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ISSI_PERSISTENCE | ||||
|   #define ISSI_PERSISTENCE 0 | ||||
| #    define ISSI_PERSISTENCE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Transfer buffer for TWITransmitData()
 | ||||
|  | @ -75,56 +75,51 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
 | ||||
| // probably not worth the extra complexity.
 | ||||
| uint8_t g_pwm_buffer[DRIVER_COUNT][192]; | ||||
| bool g_pwm_buffer_update_required[DRIVER_COUNT] = { false }; | ||||
| bool    g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; | ||||
| 
 | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } }; | ||||
| bool g_led_control_registers_update_required[DRIVER_COUNT] = { false }; | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24]             = {{0}, {0}}; | ||||
| bool    g_led_control_registers_update_required[DRIVER_COUNT] = {false}; | ||||
| 
 | ||||
| void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data ) | ||||
| { | ||||
| void IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
| 
 | ||||
|   #if ISSI_PERSISTENCE > 0 | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|     for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|       if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) | ||||
|         break; | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; | ||||
|     } | ||||
|   #else | ||||
| #else | ||||
|     i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) | ||||
| { | ||||
| void IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||||
|     // assumes PG1 is already selected
 | ||||
| 
 | ||||
|     // transmit PWM registers in 12 transfers of 16 bytes
 | ||||
|     // g_twi_transfer_buffer[] is 20 bytes
 | ||||
| 
 | ||||
|     // iterate over the pwm_buffer contents at 16 byte intervals
 | ||||
|     for ( int i = 0; i < 192; i += 16 ) { | ||||
|     for (int i = 0; i < 192; i += 16) { | ||||
|         g_twi_transfer_buffer[0] = i; | ||||
|         // copy the data from i to i+15
 | ||||
|         // device will auto-increment register for data after the first byte
 | ||||
|         // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
 | ||||
|         for ( int j = 0; j < 16; j++ ) { | ||||
|         for (int j = 0; j < 16; j++) { | ||||
|             g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; | ||||
|         } | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|       for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) | ||||
|           break; | ||||
|       } | ||||
|     #else | ||||
|       i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
|     #endif | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; | ||||
|         } | ||||
| #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_init( uint8_t addr, uint8_t sync) | ||||
| { | ||||
| void IS31FL3733_init(uint8_t addr, uint8_t sync) { | ||||
|     // In order to avoid the LEDs being driven with garbage data
 | ||||
|     // in the LED driver's PWM registers, shutdown is enabled last.
 | ||||
|     // Set up the mode and other settings, clear the PWM registers,
 | ||||
|  | @ -132,120 +127,108 @@ void IS31FL3733_init( uint8_t addr, uint8_t sync) | |||
|     // Sync is passed so set it according to the datasheet.
 | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG0
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|     // Turn off all LEDs.
 | ||||
|     for ( int i = 0x00; i <= 0x17; i++ ) | ||||
|     { | ||||
|         IS31FL3733_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0x17; i++) { | ||||
|         IS31FL3733_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG1
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
|     // Set PWM on all LEDs to 0
 | ||||
|     // No need to setup Breath registers to PWM as that is the default.
 | ||||
|     for ( int i = 0x00; i <= 0xBF; i++ ) | ||||
|     { | ||||
|         IS31FL3733_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0xBF; i++) { | ||||
|         IS31FL3733_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG3
 | ||||
|     IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION ); | ||||
|     IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); | ||||
|     // Set global current to maximum.
 | ||||
|     IS31FL3733_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF ); | ||||
|     IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); | ||||
|     // Disable software shutdown.
 | ||||
|     IS31FL3733_write_register( addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01 ); | ||||
|     IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01); | ||||
| 
 | ||||
|     // Wait 10ms to ensure the device has woken up.
 | ||||
|     #ifdef __AVR__ | ||||
|     _delay_ms( 10 ); | ||||
|     #else | ||||
| // Wait 10ms to ensure the device has woken up.
 | ||||
| #ifdef __AVR__ | ||||
|     _delay_ms(10); | ||||
| #else | ||||
|     wait_ms(10); | ||||
|     #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     if ( index >= 0 && index < DRIVER_LED_TOTAL ) { | ||||
| void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index >= 0 && index < DRIVER_LED_TOTAL) { | ||||
|         is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|         g_pwm_buffer[led.driver][led.r] = red; | ||||
|         g_pwm_buffer[led.driver][led.g] = green; | ||||
|         g_pwm_buffer[led.driver][led.b] = blue; | ||||
|         g_pwm_buffer[led.driver][led.r]          = red; | ||||
|         g_pwm_buffer[led.driver][led.g]          = green; | ||||
|         g_pwm_buffer[led.driver][led.b]          = blue; | ||||
|         g_pwm_buffer_update_required[led.driver] = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) | ||||
|     { | ||||
|         IS31FL3733_set_color( i, red, green, blue ); | ||||
| void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < DRIVER_LED_TOTAL; i++) { | ||||
|         IS31FL3733_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) | ||||
| { | ||||
| void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { | ||||
|     is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|   uint8_t control_register_r = led.r / 8; | ||||
|   uint8_t control_register_g = led.g / 8; | ||||
|   uint8_t control_register_b = led.b / 8; | ||||
|   uint8_t bit_r = led.r % 8; | ||||
|   uint8_t bit_g = led.g % 8; | ||||
|   uint8_t bit_b = led.b % 8; | ||||
|     uint8_t control_register_r = led.r / 8; | ||||
|     uint8_t control_register_g = led.g / 8; | ||||
|     uint8_t control_register_b = led.b / 8; | ||||
|     uint8_t bit_r              = led.r % 8; | ||||
|     uint8_t bit_g              = led.g % 8; | ||||
|     uint8_t bit_b              = led.b % 8; | ||||
| 
 | ||||
|     if ( red ) { | ||||
|     if (red) { | ||||
|         g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); | ||||
|     } | ||||
|     if ( green ) { | ||||
|     if (green) { | ||||
|         g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); | ||||
|     } | ||||
|     if ( blue ) { | ||||
|     if (blue) { | ||||
|         g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); | ||||
|     } | ||||
| 
 | ||||
|     g_led_control_registers_update_required[led.driver] = true; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_update_pwm_buffers( uint8_t addr, uint8_t index ) | ||||
| { | ||||
|     if ( g_pwm_buffer_update_required[index] ) | ||||
|     { | ||||
| void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index) { | ||||
|     if (g_pwm_buffer_update_required[index]) { | ||||
|         // Firstly we need to unlock the command register and select PG1
 | ||||
|         IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|         IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
| 
 | ||||
|         IS31FL3733_write_pwm_buffer( addr, g_pwm_buffer[index] ); | ||||
|         IS31FL3733_write_pwm_buffer(addr, g_pwm_buffer[index]); | ||||
|     } | ||||
|     g_pwm_buffer_update_required[index] = false; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3733_update_led_control_registers( uint8_t addr, uint8_t index ) | ||||
| { | ||||
|     if ( g_led_control_registers_update_required[index] ) | ||||
|     { | ||||
| void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index) { | ||||
|     if (g_led_control_registers_update_required[index]) { | ||||
|         // Firstly we need to unlock the command register and select PG0
 | ||||
|         IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|         for ( int i=0; i<24; i++ ) | ||||
|         { | ||||
|             IS31FL3733_write_register(addr, i, g_led_control_registers[index][i] ); | ||||
|         IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|         for (int i = 0; i < 24; i++) { | ||||
|             IS31FL3733_write_register(addr, i, g_led_control_registers[index][i]); | ||||
|         } | ||||
|     } | ||||
|     g_led_control_registers_update_required[index] = false; | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef IS31FL3733_DRIVER_H | ||||
| #define IS31FL3733_DRIVER_H | ||||
| 
 | ||||
|  | @ -24,232 +23,232 @@ | |||
| #include <stdbool.h> | ||||
| 
 | ||||
| typedef struct is31_led { | ||||
|   uint8_t driver:2; | ||||
|   uint8_t r; | ||||
|   uint8_t g; | ||||
|   uint8_t b; | ||||
|     uint8_t driver : 2; | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| } __attribute__((packed)) is31_led; | ||||
| 
 | ||||
| extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; | ||||
| 
 | ||||
| void IS31FL3733_init( uint8_t addr, uint8_t sync ); | ||||
| void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data ); | ||||
| void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); | ||||
| void IS31FL3733_init(uint8_t addr, uint8_t sync); | ||||
| void IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||||
| void IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||||
| 
 | ||||
| void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| 
 | ||||
| void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); | ||||
| void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue); | ||||
| 
 | ||||
| // This should not be called from an interrupt
 | ||||
| // (eg. from a timer interrupt).
 | ||||
| // Call this while idle (in between matrix scans).
 | ||||
| // If the buffer is dirty, it will update the driver with the buffer.
 | ||||
| void IS31FL3733_update_pwm_buffers( uint8_t addr, uint8_t index ); | ||||
| void IS31FL3733_update_led_control_registers( uint8_t addr, uint8_t index ); | ||||
| void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index); | ||||
| void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index); | ||||
| 
 | ||||
| #define A_1  0x00 | ||||
| #define A_2  0x01 | ||||
| #define A_3  0x02 | ||||
| #define A_4  0x03 | ||||
| #define A_5  0x04 | ||||
| #define A_6  0x05 | ||||
| #define A_7  0x06 | ||||
| #define A_8  0x07 | ||||
| #define A_9  0x08 | ||||
| #define A_10  0x09 | ||||
| #define A_11  0x0A | ||||
| #define A_12  0x0B | ||||
| #define A_13  0x0C | ||||
| #define A_14  0x0D | ||||
| #define A_15  0x0E | ||||
| #define A_16  0x0F | ||||
| #define A_1 0x00 | ||||
| #define A_2 0x01 | ||||
| #define A_3 0x02 | ||||
| #define A_4 0x03 | ||||
| #define A_5 0x04 | ||||
| #define A_6 0x05 | ||||
| #define A_7 0x06 | ||||
| #define A_8 0x07 | ||||
| #define A_9 0x08 | ||||
| #define A_10 0x09 | ||||
| #define A_11 0x0A | ||||
| #define A_12 0x0B | ||||
| #define A_13 0x0C | ||||
| #define A_14 0x0D | ||||
| #define A_15 0x0E | ||||
| #define A_16 0x0F | ||||
| 
 | ||||
| #define B_1  0x10 | ||||
| #define B_2  0x11 | ||||
| #define B_3  0x12 | ||||
| #define B_4  0x13 | ||||
| #define B_5  0x14 | ||||
| #define B_6  0x15 | ||||
| #define B_7  0x16 | ||||
| #define B_8  0x17 | ||||
| #define B_9  0x18 | ||||
| #define B_10  0x19 | ||||
| #define B_11  0x1A | ||||
| #define B_12  0x1B | ||||
| #define B_13  0x1C | ||||
| #define B_14  0x1D | ||||
| #define B_15  0x1E | ||||
| #define B_16  0x1F | ||||
| #define B_1 0x10 | ||||
| #define B_2 0x11 | ||||
| #define B_3 0x12 | ||||
| #define B_4 0x13 | ||||
| #define B_5 0x14 | ||||
| #define B_6 0x15 | ||||
| #define B_7 0x16 | ||||
| #define B_8 0x17 | ||||
| #define B_9 0x18 | ||||
| #define B_10 0x19 | ||||
| #define B_11 0x1A | ||||
| #define B_12 0x1B | ||||
| #define B_13 0x1C | ||||
| #define B_14 0x1D | ||||
| #define B_15 0x1E | ||||
| #define B_16 0x1F | ||||
| 
 | ||||
| #define C_1  0x20 | ||||
| #define C_2  0x21 | ||||
| #define C_3  0x22 | ||||
| #define C_4  0x23 | ||||
| #define C_5  0x24 | ||||
| #define C_6  0x25 | ||||
| #define C_7  0x26 | ||||
| #define C_8  0x27 | ||||
| #define C_9  0x28 | ||||
| #define C_10  0x29 | ||||
| #define C_11  0x2A | ||||
| #define C_12  0x2B | ||||
| #define C_13  0x2C | ||||
| #define C_14  0x2D | ||||
| #define C_15  0x2E | ||||
| #define C_16  0x2F | ||||
| #define C_1 0x20 | ||||
| #define C_2 0x21 | ||||
| #define C_3 0x22 | ||||
| #define C_4 0x23 | ||||
| #define C_5 0x24 | ||||
| #define C_6 0x25 | ||||
| #define C_7 0x26 | ||||
| #define C_8 0x27 | ||||
| #define C_9 0x28 | ||||
| #define C_10 0x29 | ||||
| #define C_11 0x2A | ||||
| #define C_12 0x2B | ||||
| #define C_13 0x2C | ||||
| #define C_14 0x2D | ||||
| #define C_15 0x2E | ||||
| #define C_16 0x2F | ||||
| 
 | ||||
| #define D_1  0x30 | ||||
| #define D_2  0x31 | ||||
| #define D_3  0x32 | ||||
| #define D_4  0x33 | ||||
| #define D_5  0x34 | ||||
| #define D_6  0x35 | ||||
| #define D_7  0x36 | ||||
| #define D_8  0x37 | ||||
| #define D_9  0x38 | ||||
| #define D_10  0x39 | ||||
| #define D_11  0x3A | ||||
| #define D_12  0x3B | ||||
| #define D_13  0x3C | ||||
| #define D_14  0x3D | ||||
| #define D_15  0x3E | ||||
| #define D_16  0x3F | ||||
| #define D_1 0x30 | ||||
| #define D_2 0x31 | ||||
| #define D_3 0x32 | ||||
| #define D_4 0x33 | ||||
| #define D_5 0x34 | ||||
| #define D_6 0x35 | ||||
| #define D_7 0x36 | ||||
| #define D_8 0x37 | ||||
| #define D_9 0x38 | ||||
| #define D_10 0x39 | ||||
| #define D_11 0x3A | ||||
| #define D_12 0x3B | ||||
| #define D_13 0x3C | ||||
| #define D_14 0x3D | ||||
| #define D_15 0x3E | ||||
| #define D_16 0x3F | ||||
| 
 | ||||
| #define E_1  0x40 | ||||
| #define E_2  0x41 | ||||
| #define E_3  0x42 | ||||
| #define E_4  0x43 | ||||
| #define E_5  0x44 | ||||
| #define E_6  0x45 | ||||
| #define E_7  0x46 | ||||
| #define E_8  0x47 | ||||
| #define E_9  0x48 | ||||
| #define E_10  0x49 | ||||
| #define E_11  0x4A | ||||
| #define E_12  0x4B | ||||
| #define E_13  0x4C | ||||
| #define E_14  0x4D | ||||
| #define E_15  0x4E | ||||
| #define E_16  0x4F | ||||
| #define E_1 0x40 | ||||
| #define E_2 0x41 | ||||
| #define E_3 0x42 | ||||
| #define E_4 0x43 | ||||
| #define E_5 0x44 | ||||
| #define E_6 0x45 | ||||
| #define E_7 0x46 | ||||
| #define E_8 0x47 | ||||
| #define E_9 0x48 | ||||
| #define E_10 0x49 | ||||
| #define E_11 0x4A | ||||
| #define E_12 0x4B | ||||
| #define E_13 0x4C | ||||
| #define E_14 0x4D | ||||
| #define E_15 0x4E | ||||
| #define E_16 0x4F | ||||
| 
 | ||||
| #define F_1  0x50 | ||||
| #define F_2  0x51 | ||||
| #define F_3  0x52 | ||||
| #define F_4  0x53 | ||||
| #define F_5  0x54 | ||||
| #define F_6  0x55 | ||||
| #define F_7  0x56 | ||||
| #define F_8  0x57 | ||||
| #define F_9  0x58 | ||||
| #define F_10  0x59 | ||||
| #define F_11  0x5A | ||||
| #define F_12  0x5B | ||||
| #define F_13  0x5C | ||||
| #define F_14  0x5D | ||||
| #define F_15  0x5E | ||||
| #define F_16  0x5F | ||||
| #define F_1 0x50 | ||||
| #define F_2 0x51 | ||||
| #define F_3 0x52 | ||||
| #define F_4 0x53 | ||||
| #define F_5 0x54 | ||||
| #define F_6 0x55 | ||||
| #define F_7 0x56 | ||||
| #define F_8 0x57 | ||||
| #define F_9 0x58 | ||||
| #define F_10 0x59 | ||||
| #define F_11 0x5A | ||||
| #define F_12 0x5B | ||||
| #define F_13 0x5C | ||||
| #define F_14 0x5D | ||||
| #define F_15 0x5E | ||||
| #define F_16 0x5F | ||||
| 
 | ||||
| #define G_1  0x60 | ||||
| #define G_2  0x61 | ||||
| #define G_3  0x62 | ||||
| #define G_4  0x63 | ||||
| #define G_5  0x64 | ||||
| #define G_6  0x65 | ||||
| #define G_7  0x66 | ||||
| #define G_8  0x67 | ||||
| #define G_9  0x68 | ||||
| #define G_10  0x69 | ||||
| #define G_11  0x6A | ||||
| #define G_12  0x6B | ||||
| #define G_13  0x6C | ||||
| #define G_14  0x6D | ||||
| #define G_15  0x6E | ||||
| #define G_16  0x6F | ||||
| #define G_1 0x60 | ||||
| #define G_2 0x61 | ||||
| #define G_3 0x62 | ||||
| #define G_4 0x63 | ||||
| #define G_5 0x64 | ||||
| #define G_6 0x65 | ||||
| #define G_7 0x66 | ||||
| #define G_8 0x67 | ||||
| #define G_9 0x68 | ||||
| #define G_10 0x69 | ||||
| #define G_11 0x6A | ||||
| #define G_12 0x6B | ||||
| #define G_13 0x6C | ||||
| #define G_14 0x6D | ||||
| #define G_15 0x6E | ||||
| #define G_16 0x6F | ||||
| 
 | ||||
| #define H_1  0x70 | ||||
| #define H_2  0x71 | ||||
| #define H_3  0x72 | ||||
| #define H_4  0x73 | ||||
| #define H_5  0x74 | ||||
| #define H_6  0x75 | ||||
| #define H_7  0x76 | ||||
| #define H_8  0x77 | ||||
| #define H_9  0x78 | ||||
| #define H_10  0x79 | ||||
| #define H_11  0x7A | ||||
| #define H_12  0x7B | ||||
| #define H_13  0x7C | ||||
| #define H_14  0x7D | ||||
| #define H_15  0x7E | ||||
| #define H_16  0x7F | ||||
| #define H_1 0x70 | ||||
| #define H_2 0x71 | ||||
| #define H_3 0x72 | ||||
| #define H_4 0x73 | ||||
| #define H_5 0x74 | ||||
| #define H_6 0x75 | ||||
| #define H_7 0x76 | ||||
| #define H_8 0x77 | ||||
| #define H_9 0x78 | ||||
| #define H_10 0x79 | ||||
| #define H_11 0x7A | ||||
| #define H_12 0x7B | ||||
| #define H_13 0x7C | ||||
| #define H_14 0x7D | ||||
| #define H_15 0x7E | ||||
| #define H_16 0x7F | ||||
| 
 | ||||
| #define I_1  0x80 | ||||
| #define I_2  0x81 | ||||
| #define I_3  0x82 | ||||
| #define I_4  0x83 | ||||
| #define I_5  0x84 | ||||
| #define I_6  0x85 | ||||
| #define I_7  0x86 | ||||
| #define I_8  0x87 | ||||
| #define I_9  0x88 | ||||
| #define I_10  0x89 | ||||
| #define I_11  0x8A | ||||
| #define I_12  0x8B | ||||
| #define I_13  0x8C | ||||
| #define I_14  0x8D | ||||
| #define I_15  0x8E | ||||
| #define I_16  0x8F | ||||
| #define I_1 0x80 | ||||
| #define I_2 0x81 | ||||
| #define I_3 0x82 | ||||
| #define I_4 0x83 | ||||
| #define I_5 0x84 | ||||
| #define I_6 0x85 | ||||
| #define I_7 0x86 | ||||
| #define I_8 0x87 | ||||
| #define I_9 0x88 | ||||
| #define I_10 0x89 | ||||
| #define I_11 0x8A | ||||
| #define I_12 0x8B | ||||
| #define I_13 0x8C | ||||
| #define I_14 0x8D | ||||
| #define I_15 0x8E | ||||
| #define I_16 0x8F | ||||
| 
 | ||||
| #define J_1  0x90 | ||||
| #define J_2  0x91 | ||||
| #define J_3  0x92 | ||||
| #define J_4  0x93 | ||||
| #define J_5  0x94 | ||||
| #define J_6  0x95 | ||||
| #define J_7  0x96 | ||||
| #define J_8  0x97 | ||||
| #define J_9  0x98 | ||||
| #define J_10  0x99 | ||||
| #define J_11  0x9A | ||||
| #define J_12  0x9B | ||||
| #define J_13  0x9C | ||||
| #define J_14  0x9D | ||||
| #define J_15  0x9E | ||||
| #define J_16  0x9F | ||||
| #define J_1 0x90 | ||||
| #define J_2 0x91 | ||||
| #define J_3 0x92 | ||||
| #define J_4 0x93 | ||||
| #define J_5 0x94 | ||||
| #define J_6 0x95 | ||||
| #define J_7 0x96 | ||||
| #define J_8 0x97 | ||||
| #define J_9 0x98 | ||||
| #define J_10 0x99 | ||||
| #define J_11 0x9A | ||||
| #define J_12 0x9B | ||||
| #define J_13 0x9C | ||||
| #define J_14 0x9D | ||||
| #define J_15 0x9E | ||||
| #define J_16 0x9F | ||||
| 
 | ||||
| #define K_1  0xA0 | ||||
| #define K_2  0xA1 | ||||
| #define K_3  0xA2 | ||||
| #define K_4  0xA3 | ||||
| #define K_5  0xA4 | ||||
| #define K_6  0xA5 | ||||
| #define K_7  0xA6 | ||||
| #define K_8  0xA7 | ||||
| #define K_9  0xA8 | ||||
| #define K_10  0xA9 | ||||
| #define K_11  0xAA | ||||
| #define K_12  0xAB | ||||
| #define K_13  0xAC | ||||
| #define K_14  0xAD | ||||
| #define K_15  0xAE | ||||
| #define K_16  0xAF | ||||
| #define K_1 0xA0 | ||||
| #define K_2 0xA1 | ||||
| #define K_3 0xA2 | ||||
| #define K_4 0xA3 | ||||
| #define K_5 0xA4 | ||||
| #define K_6 0xA5 | ||||
| #define K_7 0xA6 | ||||
| #define K_8 0xA7 | ||||
| #define K_9 0xA8 | ||||
| #define K_10 0xA9 | ||||
| #define K_11 0xAA | ||||
| #define K_12 0xAB | ||||
| #define K_13 0xAC | ||||
| #define K_14 0xAD | ||||
| #define K_15 0xAE | ||||
| #define K_16 0xAF | ||||
| 
 | ||||
| #define L_1  0xB0 | ||||
| #define L_2  0xB1 | ||||
| #define L_3  0xB2 | ||||
| #define L_4  0xB3 | ||||
| #define L_5  0xB4 | ||||
| #define L_6  0xB5 | ||||
| #define L_7  0xB6 | ||||
| #define L_8  0xB7 | ||||
| #define L_9  0xB8 | ||||
| #define L_10  0xB9 | ||||
| #define L_11  0xBA | ||||
| #define L_12  0xBB | ||||
| #define L_13  0xBC | ||||
| #define L_14  0xBD | ||||
| #define L_15  0xBE | ||||
| #define L_16  0xBF | ||||
| #define L_1 0xB0 | ||||
| #define L_2 0xB1 | ||||
| #define L_3 0xB2 | ||||
| #define L_4 0xB3 | ||||
| #define L_5 0xB4 | ||||
| #define L_6 0xB5 | ||||
| #define L_7 0xB6 | ||||
| #define L_8 0xB7 | ||||
| #define L_9 0xB8 | ||||
| #define L_10 0xB9 | ||||
| #define L_11 0xBA | ||||
| #define L_12 0xBB | ||||
| #define L_13 0xBC | ||||
| #define L_14 0xBD | ||||
| #define L_15 0xBE | ||||
| #define L_16 0xBF | ||||
| 
 | ||||
| #endif // IS31FL3733_DRIVER_H
 | ||||
| #endif  // IS31FL3733_DRIVER_H
 | ||||
|  |  | |||
|  | @ -14,13 +14,12 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <util/delay.h> | ||||
| #else | ||||
| #include "wait.h" | ||||
| #    include "wait.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "is31fl3736.h" | ||||
|  | @ -28,8 +27,6 @@ | |||
| #include "i2c_master.h" | ||||
| #include "progmem.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // This is a 7-bit address, that gets left-shifted and bit 0
 | ||||
| // set to 0 for write, 1 for read (as per I2C protocol)
 | ||||
| // The address will vary depending on your wiring:
 | ||||
|  | @ -47,23 +44,23 @@ | |||
| #define ISSI_INTERRUPTMASKREGISTER 0xF0 | ||||
| #define ISSI_INTERRUPTSTATUSREGISTER 0xF1 | ||||
| 
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00 //PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01        //PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02 //PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03   //PG3
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00  // PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01         // PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02  // PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03    // PG3
 | ||||
| 
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00 //PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01 //PG3
 | ||||
| #define ISSI_REG_RESET 0x11// PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F //PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10 //PG3
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00  // PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01  // PG3
 | ||||
| #define ISSI_REG_RESET 0x11          // PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F       // PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10       // PG3
 | ||||
| 
 | ||||
| #ifndef ISSI_TIMEOUT | ||||
|   #define ISSI_TIMEOUT 100 | ||||
| #    define ISSI_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ISSI_PERSISTENCE | ||||
|   #define ISSI_PERSISTENCE 0 | ||||
| #    define ISSI_PERSISTENCE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Transfer buffer for TWITransmitData()
 | ||||
|  | @ -76,124 +73,113 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // buffers and the transfers in IS31FL3736_write_pwm_buffer() but it's
 | ||||
| // probably not worth the extra complexity.
 | ||||
| uint8_t g_pwm_buffer[DRIVER_COUNT][192]; | ||||
| bool g_pwm_buffer_update_required = false; | ||||
| bool    g_pwm_buffer_update_required = false; | ||||
| 
 | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } }; | ||||
| bool g_led_control_registers_update_required = false; | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24] = {{0}, {0}}; | ||||
| bool    g_led_control_registers_update_required   = false; | ||||
| 
 | ||||
| void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data ) | ||||
| { | ||||
| void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
| 
 | ||||
|   #if ISSI_PERSISTENCE > 0 | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|     for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|       if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) | ||||
|         break; | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; | ||||
|     } | ||||
|   #else | ||||
| #else | ||||
|     i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) | ||||
| { | ||||
| void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||||
|     // assumes PG1 is already selected
 | ||||
| 
 | ||||
|     // transmit PWM registers in 12 transfers of 16 bytes
 | ||||
|     // g_twi_transfer_buffer[] is 20 bytes
 | ||||
| 
 | ||||
|     // iterate over the pwm_buffer contents at 16 byte intervals
 | ||||
|     for ( int i = 0; i < 192; i += 16 ) { | ||||
|     for (int i = 0; i < 192; i += 16) { | ||||
|         g_twi_transfer_buffer[0] = i; | ||||
|         // copy the data from i to i+15
 | ||||
|         // device will auto-increment register for data after the first byte
 | ||||
|         // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
 | ||||
|         for ( int j = 0; j < 16; j++ ) { | ||||
|         for (int j = 0; j < 16; j++) { | ||||
|             g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; | ||||
|         } | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|       for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) | ||||
|           break; | ||||
|       } | ||||
|     #else | ||||
|       i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
|     #endif | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; | ||||
|         } | ||||
| #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_init( uint8_t addr ) | ||||
| { | ||||
| void IS31FL3736_init(uint8_t addr) { | ||||
|     // In order to avoid the LEDs being driven with garbage data
 | ||||
|     // in the LED driver's PWM registers, shutdown is enabled last.
 | ||||
|     // Set up the mode and other settings, clear the PWM registers,
 | ||||
|     // then disable software shutdown.
 | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG0
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|     // Turn off all LEDs.
 | ||||
|     for ( int i = 0x00; i <= 0x17; i++ ) | ||||
|     { | ||||
|         IS31FL3736_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0x17; i++) { | ||||
|         IS31FL3736_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG1
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
|     // Set PWM on all LEDs to 0
 | ||||
|     // No need to setup Breath registers to PWM as that is the default.
 | ||||
|     for ( int i = 0x00; i <= 0xBF; i++ ) | ||||
|     { | ||||
|         IS31FL3736_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0xBF; i++) { | ||||
|         IS31FL3736_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG3
 | ||||
|     IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION ); | ||||
|     IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); | ||||
|     // Set global current to maximum.
 | ||||
|     IS31FL3736_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF ); | ||||
|     IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); | ||||
|     // Disable software shutdown.
 | ||||
|     IS31FL3736_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 ); | ||||
|     IS31FL3736_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); | ||||
| 
 | ||||
|     // Wait 10ms to ensure the device has woken up.
 | ||||
|     #ifdef __AVR__ | ||||
|     _delay_ms( 10 ); | ||||
|     #else | ||||
| // Wait 10ms to ensure the device has woken up.
 | ||||
| #ifdef __AVR__ | ||||
|     _delay_ms(10); | ||||
| #else | ||||
|     wait_ms(10); | ||||
|     #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     if ( index >= 0 && index < DRIVER_LED_TOTAL ) { | ||||
| void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index >= 0 && index < DRIVER_LED_TOTAL) { | ||||
|         is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|         g_pwm_buffer[led.driver][led.r] = red; | ||||
|         g_pwm_buffer[led.driver][led.g] = green; | ||||
|         g_pwm_buffer[led.driver][led.b] = blue; | ||||
|         g_pwm_buffer_update_required = true; | ||||
|         g_pwm_buffer_update_required    = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) | ||||
|     { | ||||
|         IS31FL3736_set_color( i, red, green, blue ); | ||||
| void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < DRIVER_LED_TOTAL; i++) { | ||||
|         IS31FL3736_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) | ||||
| { | ||||
| void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { | ||||
|     is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|     // IS31FL3733
 | ||||
|  | @ -209,64 +195,59 @@ void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, b | |||
|     // A1-A4=0x00 A5-A8=0x01
 | ||||
|     // So, the same math applies.
 | ||||
| 
 | ||||
| 	uint8_t control_register_r = led.r / 8; | ||||
| 	uint8_t control_register_g = led.g / 8; | ||||
| 	uint8_t control_register_b = led.b / 8; | ||||
|     uint8_t control_register_r = led.r / 8; | ||||
|     uint8_t control_register_g = led.g / 8; | ||||
|     uint8_t control_register_b = led.b / 8; | ||||
| 
 | ||||
| 	uint8_t bit_r = led.r % 8; | ||||
| 	uint8_t bit_g = led.g % 8; | ||||
| 	uint8_t bit_b = led.b % 8; | ||||
|     uint8_t bit_r = led.r % 8; | ||||
|     uint8_t bit_g = led.g % 8; | ||||
|     uint8_t bit_b = led.b % 8; | ||||
| 
 | ||||
|     if ( red ) { | ||||
|     if (red) { | ||||
|         g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); | ||||
|     } | ||||
|     if ( green ) { | ||||
|     if (green) { | ||||
|         g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); | ||||
|     } | ||||
|     if ( blue ) { | ||||
|     if (blue) { | ||||
|         g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); | ||||
|     } | ||||
| 
 | ||||
|     g_led_control_registers_update_required = true; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_mono_set_brightness( int index, uint8_t value ) | ||||
| { | ||||
|     if ( index >= 0 && index < 96 ) { | ||||
|     	// Index in range 0..95 -> A1..A8, B1..B8, etc.
 | ||||
|     	// Map index 0..95 to registers 0x00..0xBE (interleaved)
 | ||||
|     	uint8_t pwm_register = index * 2; | ||||
| void IS31FL3736_mono_set_brightness(int index, uint8_t value) { | ||||
|     if (index >= 0 && index < 96) { | ||||
|         // Index in range 0..95 -> A1..A8, B1..B8, etc.
 | ||||
|         // Map index 0..95 to registers 0x00..0xBE (interleaved)
 | ||||
|         uint8_t pwm_register          = index * 2; | ||||
|         g_pwm_buffer[0][pwm_register] = value; | ||||
|         g_pwm_buffer_update_required = true; | ||||
|         g_pwm_buffer_update_required  = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_mono_set_brightness_all( uint8_t value ) | ||||
| { | ||||
|     for ( int i = 0; i < 96; i++ ) | ||||
|     { | ||||
|     	IS31FL3736_mono_set_brightness( i, value ); | ||||
| void IS31FL3736_mono_set_brightness_all(uint8_t value) { | ||||
|     for (int i = 0; i < 96; i++) { | ||||
|         IS31FL3736_mono_set_brightness(i, value); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled ) | ||||
| { | ||||
| 	// Index in range 0..95 -> A1..A8, B1..B8, etc.
 | ||||
| void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled) { | ||||
|     // Index in range 0..95 -> A1..A8, B1..B8, etc.
 | ||||
| 
 | ||||
| 	// Map index 0..95 to registers 0x00..0xBE (interleaved)
 | ||||
| 	uint8_t pwm_register = index * 2; | ||||
| 	// Map register 0x00..0xBE (interleaved) into control register and bit
 | ||||
| 	uint8_t control_register = pwm_register / 8; | ||||
| 	uint8_t bit = pwm_register % 8; | ||||
|     // Map index 0..95 to registers 0x00..0xBE (interleaved)
 | ||||
|     uint8_t pwm_register = index * 2; | ||||
|     // Map register 0x00..0xBE (interleaved) into control register and bit
 | ||||
|     uint8_t control_register = pwm_register / 8; | ||||
|     uint8_t bit              = pwm_register % 8; | ||||
| 
 | ||||
|     if ( enabled ) { | ||||
|     if (enabled) { | ||||
|         g_led_control_registers[0][control_register] |= (1 << bit); | ||||
|     } else { | ||||
|         g_led_control_registers[0][control_register] &= ~(1 << bit); | ||||
|  | @ -275,32 +256,26 @@ void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled ) | |||
|     g_led_control_registers_update_required = true; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) | ||||
| { | ||||
|     if ( g_pwm_buffer_update_required ) | ||||
|     { | ||||
| void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { | ||||
|     if (g_pwm_buffer_update_required) { | ||||
|         // Firstly we need to unlock the command register and select PG1
 | ||||
|         IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|         IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
| 
 | ||||
|         IS31FL3736_write_pwm_buffer( addr1, g_pwm_buffer[0] ); | ||||
|         //IS31FL3736_write_pwm_buffer( addr2, g_pwm_buffer[1] );
 | ||||
|         IS31FL3736_write_pwm_buffer(addr1, g_pwm_buffer[0]); | ||||
|         // IS31FL3736_write_pwm_buffer( addr2, g_pwm_buffer[1] );
 | ||||
|     } | ||||
|     g_pwm_buffer_update_required = false; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) | ||||
| { | ||||
|     if ( g_led_control_registers_update_required ) | ||||
|     { | ||||
| void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2) { | ||||
|     if (g_led_control_registers_update_required) { | ||||
|         // Firstly we need to unlock the command register and select PG0
 | ||||
|         IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|         for ( int i=0; i<24; i++ ) | ||||
|         { | ||||
|             IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i] ); | ||||
|             //IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i] );
 | ||||
|         IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|         for (int i = 0; i < 24; i++) { | ||||
|             IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i]); | ||||
|             // IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i] );
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,154 +19,150 @@ | |||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| 
 | ||||
| // Simple interface option.
 | ||||
| // If these aren't defined, just define them to make it compile
 | ||||
| 
 | ||||
| 
 | ||||
| #ifndef DRIVER_COUNT | ||||
| #define DRIVER_COUNT 2 | ||||
| #    define DRIVER_COUNT 2 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef DRIVER_LED_TOTAL | ||||
| #define DRIVER_LED_TOTAL 96 | ||||
| #    define DRIVER_LED_TOTAL 96 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| typedef struct is31_led { | ||||
|   uint8_t driver:2; | ||||
|   uint8_t r; | ||||
|   uint8_t g; | ||||
|   uint8_t b; | ||||
|     uint8_t driver : 2; | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| } __attribute__((packed)) is31_led; | ||||
| 
 | ||||
| extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; | ||||
| 
 | ||||
| void IS31FL3736_init( uint8_t addr ); | ||||
| void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data ); | ||||
| void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); | ||||
| void IS31FL3736_init(uint8_t addr); | ||||
| void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||||
| void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||||
| 
 | ||||
| void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| 
 | ||||
| void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); | ||||
| void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue); | ||||
| 
 | ||||
| void IS31FL3736_mono_set_brightness( int index, uint8_t value ); | ||||
| void IS31FL3736_mono_set_brightness_all( uint8_t value ); | ||||
| void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled ); | ||||
| void IS31FL3736_mono_set_brightness(int index, uint8_t value); | ||||
| void IS31FL3736_mono_set_brightness_all(uint8_t value); | ||||
| void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled); | ||||
| 
 | ||||
| // This should not be called from an interrupt
 | ||||
| // (eg. from a timer interrupt).
 | ||||
| // Call this while idle (in between matrix scans).
 | ||||
| // If the buffer is dirty, it will update the driver with the buffer.
 | ||||
| void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); | ||||
| void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); | ||||
| void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2); | ||||
| void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2); | ||||
| 
 | ||||
| #define A_1  0x00 | ||||
| #define A_2  0x02 | ||||
| #define A_3  0x04 | ||||
| #define A_4  0x06 | ||||
| #define A_5  0x08 | ||||
| #define A_6  0x0A | ||||
| #define A_7  0x0C | ||||
| #define A_8  0x0E | ||||
| #define A_1 0x00 | ||||
| #define A_2 0x02 | ||||
| #define A_3 0x04 | ||||
| #define A_4 0x06 | ||||
| #define A_5 0x08 | ||||
| #define A_6 0x0A | ||||
| #define A_7 0x0C | ||||
| #define A_8 0x0E | ||||
| 
 | ||||
| #define B_1  0x10 | ||||
| #define B_2  0x12 | ||||
| #define B_3  0x14 | ||||
| #define B_4  0x16 | ||||
| #define B_5  0x18 | ||||
| #define B_6  0x1A | ||||
| #define B_7  0x1C | ||||
| #define B_8  0x1E | ||||
| #define B_1 0x10 | ||||
| #define B_2 0x12 | ||||
| #define B_3 0x14 | ||||
| #define B_4 0x16 | ||||
| #define B_5 0x18 | ||||
| #define B_6 0x1A | ||||
| #define B_7 0x1C | ||||
| #define B_8 0x1E | ||||
| 
 | ||||
| #define C_1  0x20 | ||||
| #define C_2  0x22 | ||||
| #define C_3  0x24 | ||||
| #define C_4  0x26 | ||||
| #define C_5  0x28 | ||||
| #define C_6  0x2A | ||||
| #define C_7  0x2C | ||||
| #define C_8  0x2E | ||||
| #define C_1 0x20 | ||||
| #define C_2 0x22 | ||||
| #define C_3 0x24 | ||||
| #define C_4 0x26 | ||||
| #define C_5 0x28 | ||||
| #define C_6 0x2A | ||||
| #define C_7 0x2C | ||||
| #define C_8 0x2E | ||||
| 
 | ||||
| #define D_1  0x30 | ||||
| #define D_2  0x32 | ||||
| #define D_3  0x34 | ||||
| #define D_4  0x36 | ||||
| #define D_5  0x38 | ||||
| #define D_6  0x3A | ||||
| #define D_7  0x3C | ||||
| #define D_8  0x3E | ||||
| #define D_1 0x30 | ||||
| #define D_2 0x32 | ||||
| #define D_3 0x34 | ||||
| #define D_4 0x36 | ||||
| #define D_5 0x38 | ||||
| #define D_6 0x3A | ||||
| #define D_7 0x3C | ||||
| #define D_8 0x3E | ||||
| 
 | ||||
| #define E_1  0x40 | ||||
| #define E_2  0x42 | ||||
| #define E_3  0x44 | ||||
| #define E_4  0x46 | ||||
| #define E_5  0x48 | ||||
| #define E_6  0x4A | ||||
| #define E_7  0x4C | ||||
| #define E_8  0x4E | ||||
| #define E_1 0x40 | ||||
| #define E_2 0x42 | ||||
| #define E_3 0x44 | ||||
| #define E_4 0x46 | ||||
| #define E_5 0x48 | ||||
| #define E_6 0x4A | ||||
| #define E_7 0x4C | ||||
| #define E_8 0x4E | ||||
| 
 | ||||
| #define F_1  0x50 | ||||
| #define F_2  0x52 | ||||
| #define F_3  0x54 | ||||
| #define F_4  0x56 | ||||
| #define F_5  0x58 | ||||
| #define F_6  0x5A | ||||
| #define F_7  0x5C | ||||
| #define F_8  0x5E | ||||
| #define F_1 0x50 | ||||
| #define F_2 0x52 | ||||
| #define F_3 0x54 | ||||
| #define F_4 0x56 | ||||
| #define F_5 0x58 | ||||
| #define F_6 0x5A | ||||
| #define F_7 0x5C | ||||
| #define F_8 0x5E | ||||
| 
 | ||||
| #define G_1  0x60 | ||||
| #define G_2  0x62 | ||||
| #define G_3  0x64 | ||||
| #define G_4  0x66 | ||||
| #define G_5  0x68 | ||||
| #define G_6  0x6A | ||||
| #define G_7  0x6C | ||||
| #define G_8  0x6E | ||||
| #define G_1 0x60 | ||||
| #define G_2 0x62 | ||||
| #define G_3 0x64 | ||||
| #define G_4 0x66 | ||||
| #define G_5 0x68 | ||||
| #define G_6 0x6A | ||||
| #define G_7 0x6C | ||||
| #define G_8 0x6E | ||||
| 
 | ||||
| #define H_1  0x70 | ||||
| #define H_2  0x72 | ||||
| #define H_3  0x74 | ||||
| #define H_4  0x76 | ||||
| #define H_5  0x78 | ||||
| #define H_6  0x7A | ||||
| #define H_7  0x7C | ||||
| #define H_8  0x7E | ||||
| #define H_1 0x70 | ||||
| #define H_2 0x72 | ||||
| #define H_3 0x74 | ||||
| #define H_4 0x76 | ||||
| #define H_5 0x78 | ||||
| #define H_6 0x7A | ||||
| #define H_7 0x7C | ||||
| #define H_8 0x7E | ||||
| 
 | ||||
| #define I_1  0x80 | ||||
| #define I_2  0x82 | ||||
| #define I_3  0x84 | ||||
| #define I_4  0x86 | ||||
| #define I_5  0x88 | ||||
| #define I_6  0x8A | ||||
| #define I_7  0x8C | ||||
| #define I_8  0x8E | ||||
| #define I_1 0x80 | ||||
| #define I_2 0x82 | ||||
| #define I_3 0x84 | ||||
| #define I_4 0x86 | ||||
| #define I_5 0x88 | ||||
| #define I_6 0x8A | ||||
| #define I_7 0x8C | ||||
| #define I_8 0x8E | ||||
| 
 | ||||
| #define J_1  0x90 | ||||
| #define J_2  0x92 | ||||
| #define J_3  0x94 | ||||
| #define J_4  0x96 | ||||
| #define J_5  0x98 | ||||
| #define J_6  0x9A | ||||
| #define J_7  0x9C | ||||
| #define J_8  0x9E | ||||
| #define J_1 0x90 | ||||
| #define J_2 0x92 | ||||
| #define J_3 0x94 | ||||
| #define J_4 0x96 | ||||
| #define J_5 0x98 | ||||
| #define J_6 0x9A | ||||
| #define J_7 0x9C | ||||
| #define J_8 0x9E | ||||
| 
 | ||||
| #define K_1  0xA0 | ||||
| #define K_2  0xA2 | ||||
| #define K_3  0xA4 | ||||
| #define K_4  0xA6 | ||||
| #define K_5  0xA8 | ||||
| #define K_6  0xAA | ||||
| #define K_7  0xAC | ||||
| #define K_8  0xAE | ||||
| 
 | ||||
| #define L_1  0xB0 | ||||
| #define L_2  0xB2 | ||||
| #define L_3  0xB4 | ||||
| #define L_4  0xB6 | ||||
| #define L_5  0xB8 | ||||
| #define L_6  0xBA | ||||
| #define L_7  0xBC | ||||
| #define L_8  0xBE | ||||
| #define K_1 0xA0 | ||||
| #define K_2 0xA2 | ||||
| #define K_3 0xA4 | ||||
| #define K_4 0xA6 | ||||
| #define K_5 0xA8 | ||||
| #define K_6 0xAA | ||||
| #define K_7 0xAC | ||||
| #define K_8 0xAE | ||||
| 
 | ||||
| #define L_1 0xB0 | ||||
| #define L_2 0xB2 | ||||
| #define L_3 0xB4 | ||||
| #define L_4 0xB6 | ||||
| #define L_5 0xB8 | ||||
| #define L_6 0xBA | ||||
| #define L_7 0xBC | ||||
| #define L_8 0xBE | ||||
|  |  | |||
|  | @ -17,11 +17,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <util/delay.h> | ||||
| #else | ||||
| #include "wait.h" | ||||
| #    include "wait.h" | ||||
| #endif | ||||
| 
 | ||||
| #include <string.h> | ||||
|  | @ -46,23 +46,23 @@ | |||
| #define ISSI_INTERRUPTMASKREGISTER 0xF0 | ||||
| #define ISSI_INTERRUPTSTATUSREGISTER 0xF1 | ||||
| 
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00 //PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01        //PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02 //PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03   //PG3
 | ||||
| #define ISSI_PAGE_LEDCONTROL 0x00  // PG0
 | ||||
| #define ISSI_PAGE_PWM 0x01         // PG1
 | ||||
| #define ISSI_PAGE_AUTOBREATH 0x02  // PG2
 | ||||
| #define ISSI_PAGE_FUNCTION 0x03    // PG3
 | ||||
| 
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00 //PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01 //PG3
 | ||||
| #define ISSI_REG_RESET 0x11// PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F //PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10 //PG3
 | ||||
| #define ISSI_REG_CONFIGURATION 0x00  // PG3
 | ||||
| #define ISSI_REG_GLOBALCURRENT 0x01  // PG3
 | ||||
| #define ISSI_REG_RESET 0x11          // PG3
 | ||||
| #define ISSI_REG_SWPULLUP 0x0F       // PG3
 | ||||
| #define ISSI_REG_CSPULLUP 0x10       // PG3
 | ||||
| 
 | ||||
| #ifndef ISSI_TIMEOUT | ||||
|   #define ISSI_TIMEOUT 100 | ||||
| #    define ISSI_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ISSI_PERSISTENCE | ||||
|   #define ISSI_PERSISTENCE 0 | ||||
| #    define ISSI_PERSISTENCE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Transfer buffer for TWITransmitData()
 | ||||
|  | @ -75,178 +75,161 @@ uint8_t g_twi_transfer_buffer[20]; | |||
| // buffers and the transfers in IS31FL3737_write_pwm_buffer() but it's
 | ||||
| // probably not worth the extra complexity.
 | ||||
| uint8_t g_pwm_buffer[DRIVER_COUNT][192]; | ||||
| bool g_pwm_buffer_update_required = false; | ||||
| bool    g_pwm_buffer_update_required = false; | ||||
| 
 | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 } }; | ||||
| bool g_led_control_registers_update_required = false; | ||||
| uint8_t g_led_control_registers[DRIVER_COUNT][24] = {{0}}; | ||||
| bool    g_led_control_registers_update_required   = false; | ||||
| 
 | ||||
| void IS31FL3737_write_register( uint8_t addr, uint8_t reg, uint8_t data ) | ||||
| { | ||||
| void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||||
|     g_twi_transfer_buffer[0] = reg; | ||||
|     g_twi_transfer_buffer[1] = data; | ||||
| 
 | ||||
|   #if ISSI_PERSISTENCE > 0 | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|     for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|       if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) | ||||
|         break; | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; | ||||
|     } | ||||
|   #else | ||||
| #else | ||||
|     i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) | ||||
| { | ||||
| void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||||
|     // assumes PG1 is already selected
 | ||||
| 
 | ||||
|     // transmit PWM registers in 12 transfers of 16 bytes
 | ||||
|     // g_twi_transfer_buffer[] is 20 bytes
 | ||||
| 
 | ||||
|     // iterate over the pwm_buffer contents at 16 byte intervals
 | ||||
|     for ( int i = 0; i < 192; i += 16 ) { | ||||
|     for (int i = 0; i < 192; i += 16) { | ||||
|         g_twi_transfer_buffer[0] = i; | ||||
|         // copy the data from i to i+15
 | ||||
|         // device will auto-increment register for data after the first byte
 | ||||
|         // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
 | ||||
|         for ( int j = 0; j < 16; j++ ) { | ||||
|         for (int j = 0; j < 16; j++) { | ||||
|             g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; | ||||
|         } | ||||
| 
 | ||||
|     #if ISSI_PERSISTENCE > 0 | ||||
|       for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|         if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) | ||||
|           break; | ||||
|       } | ||||
|     #else | ||||
|       i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
|     #endif | ||||
| #if ISSI_PERSISTENCE > 0 | ||||
|         for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { | ||||
|             if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; | ||||
|         } | ||||
| #else | ||||
|         i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_init( uint8_t addr ) | ||||
| { | ||||
| void IS31FL3737_init(uint8_t addr) { | ||||
|     // In order to avoid the LEDs being driven with garbage data
 | ||||
|     // in the LED driver's PWM registers, shutdown is enabled last.
 | ||||
|     // Set up the mode and other settings, clear the PWM registers,
 | ||||
|     // then disable software shutdown.
 | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG0
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|     // Turn off all LEDs.
 | ||||
|     for ( int i = 0x00; i <= 0x17; i++ ) | ||||
|     { | ||||
|         IS31FL3737_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0x17; i++) { | ||||
|         IS31FL3737_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG1
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
|     // Set PWM on all LEDs to 0
 | ||||
|     // No need to setup Breath registers to PWM as that is the default.
 | ||||
|     for ( int i = 0x00; i <= 0xBF; i++ ) | ||||
|     { | ||||
|         IS31FL3737_write_register( addr, i, 0x00 ); | ||||
|     for (int i = 0x00; i <= 0xBF; i++) { | ||||
|         IS31FL3737_write_register(addr, i, 0x00); | ||||
|     } | ||||
| 
 | ||||
|     // Unlock the command register.
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
| 
 | ||||
|     // Select PG3
 | ||||
|     IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION ); | ||||
|     IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); | ||||
|     // Set global current to maximum.
 | ||||
|     IS31FL3737_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF ); | ||||
|     IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); | ||||
|     // Disable software shutdown.
 | ||||
|     IS31FL3737_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 ); | ||||
|     IS31FL3737_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); | ||||
| 
 | ||||
|     // Wait 10ms to ensure the device has woken up.
 | ||||
|     #ifdef __AVR__ | ||||
|     _delay_ms( 10 ); | ||||
|     #else | ||||
| // Wait 10ms to ensure the device has woken up.
 | ||||
| #ifdef __AVR__ | ||||
|     _delay_ms(10); | ||||
| #else | ||||
|     wait_ms(10); | ||||
|     #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     if ( index >= 0 && index < DRIVER_LED_TOTAL ) { | ||||
| void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index >= 0 && index < DRIVER_LED_TOTAL) { | ||||
|         is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|         g_pwm_buffer[led.driver][led.r] = red; | ||||
|         g_pwm_buffer[led.driver][led.g] = green; | ||||
|         g_pwm_buffer[led.driver][led.b] = blue; | ||||
|         g_pwm_buffer_update_required = true; | ||||
|         g_pwm_buffer_update_required    = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | ||||
| { | ||||
|     for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) | ||||
|     { | ||||
|         IS31FL3737_set_color( i, red, green, blue ); | ||||
| void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < DRIVER_LED_TOTAL; i++) { | ||||
|         IS31FL3737_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) | ||||
| { | ||||
| void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { | ||||
|     is31_led led = g_is31_leds[index]; | ||||
| 
 | ||||
|   uint8_t control_register_r = led.r / 8; | ||||
|   uint8_t control_register_g = led.g / 8; | ||||
|   uint8_t control_register_b = led.b / 8; | ||||
|   uint8_t bit_r = led.r % 8; | ||||
|   uint8_t bit_g = led.g % 8; | ||||
|   uint8_t bit_b = led.b % 8; | ||||
|     uint8_t control_register_r = led.r / 8; | ||||
|     uint8_t control_register_g = led.g / 8; | ||||
|     uint8_t control_register_b = led.b / 8; | ||||
|     uint8_t bit_r              = led.r % 8; | ||||
|     uint8_t bit_g              = led.g % 8; | ||||
|     uint8_t bit_b              = led.b % 8; | ||||
| 
 | ||||
|     if ( red ) { | ||||
|     if (red) { | ||||
|         g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); | ||||
|     } | ||||
|     if ( green ) { | ||||
|     if (green) { | ||||
|         g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); | ||||
|     } | ||||
|     if ( blue ) { | ||||
|     if (blue) { | ||||
|         g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); | ||||
|     } else { | ||||
|         g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); | ||||
|     } | ||||
| 
 | ||||
|     g_led_control_registers_update_required = true; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) | ||||
| { | ||||
|     if ( g_pwm_buffer_update_required ) | ||||
|     { | ||||
| void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { | ||||
|     if (g_pwm_buffer_update_required) { | ||||
|         // Firstly we need to unlock the command register and select PG1
 | ||||
|         IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); | ||||
|         IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); | ||||
| 
 | ||||
|         IS31FL3737_write_pwm_buffer( addr1, g_pwm_buffer[0] ); | ||||
|         //IS31FL3737_write_pwm_buffer( addr2, g_pwm_buffer[1] );
 | ||||
|         IS31FL3737_write_pwm_buffer(addr1, g_pwm_buffer[0]); | ||||
|         // IS31FL3737_write_pwm_buffer( addr2, g_pwm_buffer[1] );
 | ||||
|     } | ||||
|     g_pwm_buffer_update_required = false; | ||||
| } | ||||
| 
 | ||||
| void IS31FL3737_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) | ||||
| { | ||||
|     if ( g_led_control_registers_update_required ) | ||||
|     { | ||||
| void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2) { | ||||
|     if (g_led_control_registers_update_required) { | ||||
|         // Firstly we need to unlock the command register and select PG0
 | ||||
|         IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); | ||||
|         IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); | ||||
|         for ( int i=0; i<24; i++ ) | ||||
|         { | ||||
|             IS31FL3737_write_register(addr1, i, g_led_control_registers[0][i] ); | ||||
|             //IS31FL3737_write_register(addr2, i, g_led_control_registers[1][i] );
 | ||||
|         IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); | ||||
|         IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); | ||||
|         for (int i = 0; i < 24; i++) { | ||||
|             IS31FL3737_write_register(addr1, i, g_led_control_registers[0][i]); | ||||
|             // IS31FL3737_write_register(addr2, i, g_led_control_registers[1][i] );
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef IS31FL3737_DRIVER_H | ||||
| #define IS31FL3737_DRIVER_H | ||||
| 
 | ||||
|  | @ -24,184 +23,184 @@ | |||
| #include <stdbool.h> | ||||
| 
 | ||||
| typedef struct is31_led { | ||||
|   uint8_t driver:2; | ||||
|   uint8_t r; | ||||
|   uint8_t g; | ||||
|   uint8_t b; | ||||
|     uint8_t driver : 2; | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| } __attribute__((packed)) is31_led; | ||||
| 
 | ||||
| extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; | ||||
| 
 | ||||
| void IS31FL3737_init( uint8_t addr ); | ||||
| void IS31FL3737_write_register( uint8_t addr, uint8_t reg, uint8_t data ); | ||||
| void IS31FL3737_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); | ||||
| void IS31FL3737_init(uint8_t addr); | ||||
| void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||||
| void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||||
| 
 | ||||
| void IS31FL3737_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3737_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); | ||||
| void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| 
 | ||||
| void IS31FL3737_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); | ||||
| void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue); | ||||
| 
 | ||||
| // This should not be called from an interrupt
 | ||||
| // (eg. from a timer interrupt).
 | ||||
| // Call this while idle (in between matrix scans).
 | ||||
| // If the buffer is dirty, it will update the driver with the buffer.
 | ||||
| void IS31FL3737_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); | ||||
| void IS31FL3737_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); | ||||
| void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2); | ||||
| void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2); | ||||
| 
 | ||||
| #define A_1   0x00 | ||||
| #define A_2   0x01 | ||||
| #define A_3   0x02 | ||||
| #define A_4   0x03 | ||||
| #define A_5   0x04 | ||||
| #define A_6   0x05 | ||||
| #define A_7   0x08 | ||||
| #define A_8   0x09 | ||||
| #define A_9   0x0A | ||||
| #define A_10  0x0B | ||||
| #define A_11  0x0C | ||||
| #define A_12  0x0D | ||||
| #define A_1 0x00 | ||||
| #define A_2 0x01 | ||||
| #define A_3 0x02 | ||||
| #define A_4 0x03 | ||||
| #define A_5 0x04 | ||||
| #define A_6 0x05 | ||||
| #define A_7 0x08 | ||||
| #define A_8 0x09 | ||||
| #define A_9 0x0A | ||||
| #define A_10 0x0B | ||||
| #define A_11 0x0C | ||||
| #define A_12 0x0D | ||||
| 
 | ||||
| #define B_1   0x10 | ||||
| #define B_2   0x11 | ||||
| #define B_3   0x12 | ||||
| #define B_4   0x13 | ||||
| #define B_5   0x14 | ||||
| #define B_6   0x15 | ||||
| #define B_7   0x18 | ||||
| #define B_8   0x19 | ||||
| #define B_9   0x1A | ||||
| #define B_10  0x1B | ||||
| #define B_11  0x1C | ||||
| #define B_12  0x1D | ||||
| #define B_1 0x10 | ||||
| #define B_2 0x11 | ||||
| #define B_3 0x12 | ||||
| #define B_4 0x13 | ||||
| #define B_5 0x14 | ||||
| #define B_6 0x15 | ||||
| #define B_7 0x18 | ||||
| #define B_8 0x19 | ||||
| #define B_9 0x1A | ||||
| #define B_10 0x1B | ||||
| #define B_11 0x1C | ||||
| #define B_12 0x1D | ||||
| 
 | ||||
| #define C_1   0x20 | ||||
| #define C_2   0x21 | ||||
| #define C_3   0x22 | ||||
| #define C_4   0x23 | ||||
| #define C_5   0x24 | ||||
| #define C_6   0x25 | ||||
| #define C_7   0x28 | ||||
| #define C_8   0x29 | ||||
| #define C_9   0x2A | ||||
| #define C_10  0x2B | ||||
| #define C_11  0x2C | ||||
| #define C_12  0x2D | ||||
| #define C_1 0x20 | ||||
| #define C_2 0x21 | ||||
| #define C_3 0x22 | ||||
| #define C_4 0x23 | ||||
| #define C_5 0x24 | ||||
| #define C_6 0x25 | ||||
| #define C_7 0x28 | ||||
| #define C_8 0x29 | ||||
| #define C_9 0x2A | ||||
| #define C_10 0x2B | ||||
| #define C_11 0x2C | ||||
| #define C_12 0x2D | ||||
| 
 | ||||
| #define D_1   0x30 | ||||
| #define D_2   0x31 | ||||
| #define D_3   0x32 | ||||
| #define D_4   0x33 | ||||
| #define D_5   0x34 | ||||
| #define D_6   0x35 | ||||
| #define D_7   0x38 | ||||
| #define D_8   0x39 | ||||
| #define D_9   0x3A | ||||
| #define D_10  0x3B | ||||
| #define D_11  0x3C | ||||
| #define D_12  0x3D | ||||
| #define D_1 0x30 | ||||
| #define D_2 0x31 | ||||
| #define D_3 0x32 | ||||
| #define D_4 0x33 | ||||
| #define D_5 0x34 | ||||
| #define D_6 0x35 | ||||
| #define D_7 0x38 | ||||
| #define D_8 0x39 | ||||
| #define D_9 0x3A | ||||
| #define D_10 0x3B | ||||
| #define D_11 0x3C | ||||
| #define D_12 0x3D | ||||
| 
 | ||||
| #define E_1   0x40 | ||||
| #define E_2   0x41 | ||||
| #define E_3   0x42 | ||||
| #define E_4   0x43 | ||||
| #define E_5   0x44 | ||||
| #define E_6   0x45 | ||||
| #define E_7   0x48 | ||||
| #define E_8   0x49 | ||||
| #define E_9   0x4A | ||||
| #define E_10  0x4B | ||||
| #define E_11  0x4C | ||||
| #define E_12  0x4D | ||||
| #define E_1 0x40 | ||||
| #define E_2 0x41 | ||||
| #define E_3 0x42 | ||||
| #define E_4 0x43 | ||||
| #define E_5 0x44 | ||||
| #define E_6 0x45 | ||||
| #define E_7 0x48 | ||||
| #define E_8 0x49 | ||||
| #define E_9 0x4A | ||||
| #define E_10 0x4B | ||||
| #define E_11 0x4C | ||||
| #define E_12 0x4D | ||||
| 
 | ||||
| #define F_1   0x50 | ||||
| #define F_2   0x51 | ||||
| #define F_3   0x52 | ||||
| #define F_4   0x53 | ||||
| #define F_5   0x54 | ||||
| #define F_6   0x55 | ||||
| #define F_7   0x58 | ||||
| #define F_8   0x59 | ||||
| #define F_9   0x5A | ||||
| #define F_10  0x5B | ||||
| #define F_11  0x5C | ||||
| #define F_12  0x5D | ||||
| #define F_1 0x50 | ||||
| #define F_2 0x51 | ||||
| #define F_3 0x52 | ||||
| #define F_4 0x53 | ||||
| #define F_5 0x54 | ||||
| #define F_6 0x55 | ||||
| #define F_7 0x58 | ||||
| #define F_8 0x59 | ||||
| #define F_9 0x5A | ||||
| #define F_10 0x5B | ||||
| #define F_11 0x5C | ||||
| #define F_12 0x5D | ||||
| 
 | ||||
| #define G_1   0x60 | ||||
| #define G_2   0x61 | ||||
| #define G_3   0x62 | ||||
| #define G_4   0x63 | ||||
| #define G_5   0x64 | ||||
| #define G_6   0x65 | ||||
| #define G_7   0x68 | ||||
| #define G_8   0x69 | ||||
| #define G_9   0x6A | ||||
| #define G_10  0x6B | ||||
| #define G_11  0x6C | ||||
| #define G_12  0x6D | ||||
| #define G_1 0x60 | ||||
| #define G_2 0x61 | ||||
| #define G_3 0x62 | ||||
| #define G_4 0x63 | ||||
| #define G_5 0x64 | ||||
| #define G_6 0x65 | ||||
| #define G_7 0x68 | ||||
| #define G_8 0x69 | ||||
| #define G_9 0x6A | ||||
| #define G_10 0x6B | ||||
| #define G_11 0x6C | ||||
| #define G_12 0x6D | ||||
| 
 | ||||
| #define H_1   0x70 | ||||
| #define H_2   0x71 | ||||
| #define H_3   0x72 | ||||
| #define H_4   0x73 | ||||
| #define H_5   0x74 | ||||
| #define H_6   0x75 | ||||
| #define H_7   0x78 | ||||
| #define H_8   0x79 | ||||
| #define H_9   0x7A | ||||
| #define H_10  0x7B | ||||
| #define H_11  0x7C | ||||
| #define H_12  0x7D | ||||
| #define H_1 0x70 | ||||
| #define H_2 0x71 | ||||
| #define H_3 0x72 | ||||
| #define H_4 0x73 | ||||
| #define H_5 0x74 | ||||
| #define H_6 0x75 | ||||
| #define H_7 0x78 | ||||
| #define H_8 0x79 | ||||
| #define H_9 0x7A | ||||
| #define H_10 0x7B | ||||
| #define H_11 0x7C | ||||
| #define H_12 0x7D | ||||
| 
 | ||||
| #define I_1   0x80 | ||||
| #define I_2   0x81 | ||||
| #define I_3   0x82 | ||||
| #define I_4   0x83 | ||||
| #define I_5   0x84 | ||||
| #define I_6   0x85 | ||||
| #define I_7   0x88 | ||||
| #define I_8   0x89 | ||||
| #define I_9   0x8A | ||||
| #define I_10  0x8B | ||||
| #define I_11  0x8C | ||||
| #define I_12  0x8D | ||||
| #define I_1 0x80 | ||||
| #define I_2 0x81 | ||||
| #define I_3 0x82 | ||||
| #define I_4 0x83 | ||||
| #define I_5 0x84 | ||||
| #define I_6 0x85 | ||||
| #define I_7 0x88 | ||||
| #define I_8 0x89 | ||||
| #define I_9 0x8A | ||||
| #define I_10 0x8B | ||||
| #define I_11 0x8C | ||||
| #define I_12 0x8D | ||||
| 
 | ||||
| #define J_1   0x90 | ||||
| #define J_2   0x91 | ||||
| #define J_3   0x92 | ||||
| #define J_4   0x93 | ||||
| #define J_5   0x94 | ||||
| #define J_6   0x95 | ||||
| #define J_7   0x98 | ||||
| #define J_8   0x99 | ||||
| #define J_9   0x9A | ||||
| #define J_10  0x9B | ||||
| #define J_11  0x9C | ||||
| #define J_12  0x9D | ||||
| #define J_1 0x90 | ||||
| #define J_2 0x91 | ||||
| #define J_3 0x92 | ||||
| #define J_4 0x93 | ||||
| #define J_5 0x94 | ||||
| #define J_6 0x95 | ||||
| #define J_7 0x98 | ||||
| #define J_8 0x99 | ||||
| #define J_9 0x9A | ||||
| #define J_10 0x9B | ||||
| #define J_11 0x9C | ||||
| #define J_12 0x9D | ||||
| 
 | ||||
| #define K_1   0xA0 | ||||
| #define K_2   0xA1 | ||||
| #define K_3   0xA2 | ||||
| #define K_4   0xA3 | ||||
| #define K_5   0xA4 | ||||
| #define K_6   0xA5 | ||||
| #define K_7   0xA8 | ||||
| #define K_8   0xA9 | ||||
| #define K_9   0xAA | ||||
| #define K_10  0xAB | ||||
| #define K_11  0xAC | ||||
| #define K_12  0xAD | ||||
| #define K_1 0xA0 | ||||
| #define K_2 0xA1 | ||||
| #define K_3 0xA2 | ||||
| #define K_4 0xA3 | ||||
| #define K_5 0xA4 | ||||
| #define K_6 0xA5 | ||||
| #define K_7 0xA8 | ||||
| #define K_8 0xA9 | ||||
| #define K_9 0xAA | ||||
| #define K_10 0xAB | ||||
| #define K_11 0xAC | ||||
| #define K_12 0xAD | ||||
| 
 | ||||
| #define L_1   0xB0 | ||||
| #define L_2   0xB1 | ||||
| #define L_3   0xB2 | ||||
| #define L_4   0xB3 | ||||
| #define L_5   0xB4 | ||||
| #define L_6   0xB5 | ||||
| #define L_7   0xB8 | ||||
| #define L_8   0xB9 | ||||
| #define L_9   0xBA | ||||
| #define L_10  0xBB | ||||
| #define L_11  0xBC | ||||
| #define L_12  0xBD | ||||
| #define L_1 0xB0 | ||||
| #define L_2 0xB1 | ||||
| #define L_3 0xB2 | ||||
| #define L_4 0xB3 | ||||
| #define L_5 0xB4 | ||||
| #define L_6 0xB5 | ||||
| #define L_7 0xB8 | ||||
| #define L_8 0xB9 | ||||
| #define L_9 0xBA | ||||
| #define L_10 0xBB | ||||
| #define L_11 0xBC | ||||
| #define L_12 0xBD | ||||
| 
 | ||||
| #endif // IS31FL3737_DRIVER_H
 | ||||
| #endif  // IS31FL3737_DRIVER_H
 | ||||
|  |  | |||
|  | @ -1,240 +1,25 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #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 | ||||
| 
 | ||||
| // Helidox 8x6 font with QMK Firmware Logo
 | ||||
| // Online editor: http://teripom.x0.com/
 | ||||
| 
 | ||||
| static const unsigned char font[] PROGMEM = { | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, | ||||
|   0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, | ||||
|   0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, | ||||
|   0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, | ||||
|   0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, | ||||
|   0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, | ||||
|   0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, | ||||
|   0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, | ||||
|   0x00, 0x18, 0x24, 0x18, 0x00, 0x00, | ||||
|   0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, | ||||
|   0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, | ||||
|   0x26, 0x29, 0x79, 0x29, 0x26, 0x00, | ||||
|   0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, | ||||
|   0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, | ||||
|   0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, | ||||
|   0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, | ||||
|   0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, | ||||
|   0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, | ||||
|   0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, | ||||
|   0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, | ||||
|   0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, | ||||
|   0x60, 0x60, 0x60, 0x60, 0x60, 0x00, | ||||
|   0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, | ||||
|   0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, | ||||
|   0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, | ||||
|   0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, | ||||
|   0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, | ||||
|   0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, | ||||
|   0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, | ||||
|   0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, | ||||
|   0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||||
|   0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, | ||||
|   0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, | ||||
|   0x23, 0x13, 0x08, 0x64, 0x62, 0x00, | ||||
|   0x36, 0x49, 0x56, 0x20, 0x50, 0x00, | ||||
|   0x00, 0x08, 0x07, 0x03, 0x00, 0x00, | ||||
|   0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, | ||||
|   0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, | ||||
|   0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, | ||||
|   0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, | ||||
|   0x00, 0x80, 0x70, 0x30, 0x00, 0x00, | ||||
|   0x08, 0x08, 0x08, 0x08, 0x08, 0x00, | ||||
|   0x00, 0x00, 0x60, 0x60, 0x00, 0x00, | ||||
|   0x20, 0x10, 0x08, 0x04, 0x02, 0x00, | ||||
|   0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, | ||||
|   0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, | ||||
|   0x72, 0x49, 0x49, 0x49, 0x46, 0x00, | ||||
|   0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, | ||||
|   0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, | ||||
|   0x27, 0x45, 0x45, 0x45, 0x39, 0x00, | ||||
|   0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, | ||||
|   0x41, 0x21, 0x11, 0x09, 0x07, 0x00, | ||||
|   0x36, 0x49, 0x49, 0x49, 0x36, 0x00, | ||||
|   0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, | ||||
|   0x00, 0x00, 0x14, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x40, 0x34, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x08, 0x14, 0x22, 0x41, 0x00, | ||||
|   0x14, 0x14, 0x14, 0x14, 0x14, 0x00, | ||||
|   0x00, 0x41, 0x22, 0x14, 0x08, 0x00, | ||||
|   0x02, 0x01, 0x59, 0x09, 0x06, 0x00, | ||||
|   0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, | ||||
|   0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, | ||||
|   0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, | ||||
|   0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, | ||||
|   0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, | ||||
|   0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, | ||||
|   0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, | ||||
|   0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, | ||||
|   0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, | ||||
|   0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, | ||||
|   0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, | ||||
|   0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, | ||||
|   0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, | ||||
|   0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, | ||||
|   0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, | ||||
|   0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, | ||||
|   0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, | ||||
|   0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, | ||||
|   0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, | ||||
|   0x26, 0x49, 0x49, 0x49, 0x32, 0x00, | ||||
|   0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, | ||||
|   0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, | ||||
|   0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, | ||||
|   0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, | ||||
|   0x63, 0x14, 0x08, 0x14, 0x63, 0x00, | ||||
|   0x03, 0x04, 0x78, 0x04, 0x03, 0x00, | ||||
|   0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, | ||||
|   0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, | ||||
|   0x02, 0x04, 0x08, 0x10, 0x20, 0x00, | ||||
|   0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, | ||||
|   0x04, 0x02, 0x01, 0x02, 0x04, 0x00, | ||||
|   0x40, 0x40, 0x40, 0x40, 0x40, 0x00, | ||||
|   0x00, 0x03, 0x07, 0x08, 0x00, 0x00, | ||||
|   0x20, 0x54, 0x54, 0x78, 0x40, 0x00, | ||||
|   0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, | ||||
|   0x38, 0x44, 0x44, 0x44, 0x28, 0x00, | ||||
|   0x38, 0x44, 0x44, 0x28, 0x7F, 0x00, | ||||
|   0x38, 0x54, 0x54, 0x54, 0x18, 0x00, | ||||
|   0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, | ||||
|   0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00, | ||||
|   0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, | ||||
|   0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, | ||||
|   0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, | ||||
|   0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, | ||||
|   0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, | ||||
|   0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, | ||||
|   0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, | ||||
|   0x38, 0x44, 0x44, 0x44, 0x38, 0x00, | ||||
|   0xFC, 0x18, 0x24, 0x24, 0x18, 0x00, | ||||
|   0x18, 0x24, 0x24, 0x18, 0xFC, 0x00, | ||||
|   0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, | ||||
|   0x48, 0x54, 0x54, 0x54, 0x24, 0x00, | ||||
|   0x04, 0x04, 0x3F, 0x44, 0x24, 0x00, | ||||
|   0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, | ||||
|   0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, | ||||
|   0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, | ||||
|   0x44, 0x28, 0x10, 0x28, 0x44, 0x00, | ||||
|   0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00, | ||||
|   0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, | ||||
|   0x00, 0x08, 0x36, 0x41, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x77, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x41, 0x36, 0x08, 0x00, 0x00, | ||||
|   0x02, 0x01, 0x02, 0x04, 0x02, 0x00, | ||||
|   0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x40, 0x40, 0x40, 0xF0, 0xF8, 0xF8, | ||||
|   0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0x3F, | ||||
|   0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8, | ||||
|   0xF8, 0xF0, 0x40, 0x40, 0x40, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||||
|   0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, | ||||
|   0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, | ||||
|   0x80, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, | ||||
|   0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, | ||||
|   0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0xC0, 0xF0, 0xF8, 0xFC, 0x3E, | ||||
|   0x1E, 0x06, 0x01, 0x00, 0x00, 0x00, | ||||
|   0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, | ||||
|   0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, | ||||
|   0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B, | ||||
|   0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00, | ||||
|   0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE, | ||||
|   0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF, | ||||
|   0xFF, 0xE0, 0xDF, 0xBF, 0xBF, 0x00, | ||||
|   0xBF, 0xBF, 0xDF, 0xE0, 0xFF, 0xFF, | ||||
|   0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, | ||||
|   0x60, 0x60, 0xE0, 0xBF, 0x1F, 0x00, | ||||
|   0x7F, 0x7F, 0x07, 0x1E, 0x38, 0x1E, | ||||
|   0x07, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, | ||||
|   0x0E, 0x1F, 0x3B, 0x71, 0x60, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, | ||||
|   0x0C, 0x0C, 0x0C, 0x00, 0x7E, 0x7E, | ||||
|   0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00, | ||||
|   0x7F, 0x7E, 0x03, 0x03, 0x7E, 0x7E, | ||||
|   0x03, 0x03, 0x7F, 0x7E, 0x00, 0x0F, | ||||
|   0x3E, 0x70, 0x3C, 0x06, 0x3C, 0x70, | ||||
|   0x3E, 0x0F, 0x00, 0x32, 0x7B, 0x49, | ||||
|   0x49, 0x3F, 0x7E, 0x00, 0x7F, 0x7E, | ||||
|   0x03, 0x03, 0x00, 0x1E, 0x3F, 0x69, | ||||
|   0x69, 0x6F, 0x26, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x3C, | ||||
|   0x78, 0x70, 0x60, 0x00, 0x00, 0x00, | ||||
|   0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, | ||||
|   0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, | ||||
|   0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, | ||||
|   0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, | ||||
|   0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, | ||||
|   0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x01, 0x01, 0x01, 0x07, 0x0F, 0x0F, | ||||
|   0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x7E, | ||||
|   0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F, | ||||
|   0x0F, 0x07, 0x01, 0x01, 0x01, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x01, 0x01, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, 0x26, 0x29, 0x79, 0x29, 0x26, 0x00, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, | ||||
|     0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x80, 0x70, 0x30, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, | ||||
|     0x72, 0x49, 0x49, 0x49, 0x46, 0x00, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, 0x41, 0x21, 0x11, 0x09, 0x07, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x02, 0x01, 0x59, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, | ||||
|     0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x03, 0x04, 0x78, 0x04, 0x03, 0x00, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x03, 0x07, 0x08, 0x00, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x00, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, | ||||
|     0x38, 0x44, 0x44, 0x28, 0x7F, 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x48, 0x54, 0x54, 0x54, 0x24, 0x00, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x00, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xF0, 0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0x3F, 0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0xF0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xF8, 0xFC, 0x3E, | ||||
|     0x1E, 0x06, 0x01, 0x00, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B, 0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE, 0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xDF, 0xBF, 0xBF, 0x00, 0xBF, 0xBF, 0xDF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x60, 0x60, 0xE0, 0xBF, 0x1F, 0x00, 0x7F, 0x7F, 0x07, 0x1E, 0x38, 0x1E, 0x07, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x0E, 0x1F, 0x3B, 0x71, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x0C, 0x0C, 0x0C, 0x00, 0x7E, 0x7E, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x7E, 0x7E, 0x03, 0x03, 0x7F, 0x7E, 0x00, 0x0F, | ||||
|     0x3E, 0x70, 0x3C, 0x06, 0x3C, 0x70, 0x3E, 0x0F, 0x00, 0x32, 0x7B, 0x49, 0x49, 0x3F, 0x7E, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00, 0x1E, 0x3F, 0x69, 0x69, 0x6F, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x3C, 0x78, 0x70, 0x60, 0x00, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x07, 0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x7E, 0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| }; | ||||
|  |  | |||
|  | @ -23,64 +23,64 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include <string.h> | ||||
| 
 | ||||
| #if defined(__AVR__) | ||||
|   #include <avr/io.h> | ||||
|   #include <avr/pgmspace.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <avr/pgmspace.h> | ||||
| #elif defined(ESP8266) | ||||
|   #include <pgmspace.h> | ||||
| #else // defined(ESP8266)
 | ||||
|   #define PROGMEM | ||||
|   #define memcpy_P(des, src, len) memcpy(des, src, len) | ||||
| #endif // defined(__AVR__)
 | ||||
| #    include <pgmspace.h> | ||||
| #else  // defined(ESP8266)
 | ||||
| #    define PROGMEM | ||||
| #    define memcpy_P(des, src, len) memcpy(des, src, len) | ||||
| #endif  // defined(__AVR__)
 | ||||
| 
 | ||||
| // Used commands from spec sheet: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
 | ||||
| // for SH1106: https://www.velleman.eu/downloads/29/infosheets/sh1106_datasheet.pdf
 | ||||
| 
 | ||||
| // Fundamental Commands
 | ||||
| #define CONTRAST                0x81 | ||||
| #define DISPLAY_ALL_ON          0xA5 | ||||
| #define DISPLAY_ALL_ON_RESUME   0xA4 | ||||
| #define NORMAL_DISPLAY          0xA6 | ||||
| #define DISPLAY_ON              0xAF | ||||
| #define DISPLAY_OFF             0xAE | ||||
| #define NOP                     0xE3 | ||||
| #define CONTRAST 0x81 | ||||
| #define DISPLAY_ALL_ON 0xA5 | ||||
| #define DISPLAY_ALL_ON_RESUME 0xA4 | ||||
| #define NORMAL_DISPLAY 0xA6 | ||||
| #define DISPLAY_ON 0xAF | ||||
| #define DISPLAY_OFF 0xAE | ||||
| #define NOP 0xE3 | ||||
| 
 | ||||
| // Scrolling Commands
 | ||||
| #define ACTIVATE_SCROLL         0x2F | ||||
| #define DEACTIVATE_SCROLL       0x2E | ||||
| #define SCROLL_RIGHT            0x26 | ||||
| #define SCROLL_LEFT             0x27 | ||||
| #define SCROLL_RIGHT_UP         0x29 | ||||
| #define SCROLL_LEFT_UP          0x2A | ||||
| #define ACTIVATE_SCROLL 0x2F | ||||
| #define DEACTIVATE_SCROLL 0x2E | ||||
| #define SCROLL_RIGHT 0x26 | ||||
| #define SCROLL_LEFT 0x27 | ||||
| #define SCROLL_RIGHT_UP 0x29 | ||||
| #define SCROLL_LEFT_UP 0x2A | ||||
| 
 | ||||
| // Addressing Setting Commands
 | ||||
| #define MEMORY_MODE             0x20 | ||||
| #define COLUMN_ADDR             0x21 | ||||
| #define PAGE_ADDR               0x22 | ||||
| #define PAM_SETCOLUMN_LSB       0x00 | ||||
| #define PAM_SETCOLUMN_MSB       0x10 | ||||
| #define PAM_PAGE_ADDR           0xB0 // 0xb0 -- 0xb7
 | ||||
| #define MEMORY_MODE 0x20 | ||||
| #define COLUMN_ADDR 0x21 | ||||
| #define PAGE_ADDR 0x22 | ||||
| #define PAM_SETCOLUMN_LSB 0x00 | ||||
| #define PAM_SETCOLUMN_MSB 0x10 | ||||
| #define PAM_PAGE_ADDR 0xB0  // 0xb0 -- 0xb7
 | ||||
| 
 | ||||
| // Hardware Configuration Commands
 | ||||
| #define DISPLAY_START_LINE      0x40 | ||||
| #define SEGMENT_REMAP           0xA0 | ||||
| #define SEGMENT_REMAP_INV       0xA1 | ||||
| #define MULTIPLEX_RATIO         0xA8 | ||||
| #define COM_SCAN_INC            0xC0 | ||||
| #define COM_SCAN_DEC            0xC8 | ||||
| #define DISPLAY_OFFSET          0xD3 | ||||
| #define COM_PINS                0xDA | ||||
| #define COM_PINS_SEQ            0x02 | ||||
| #define COM_PINS_ALT            0x12 | ||||
| #define COM_PINS_SEQ_LR         0x22 | ||||
| #define COM_PINS_ALT_LR         0x32 | ||||
| #define DISPLAY_START_LINE 0x40 | ||||
| #define SEGMENT_REMAP 0xA0 | ||||
| #define SEGMENT_REMAP_INV 0xA1 | ||||
| #define MULTIPLEX_RATIO 0xA8 | ||||
| #define COM_SCAN_INC 0xC0 | ||||
| #define COM_SCAN_DEC 0xC8 | ||||
| #define DISPLAY_OFFSET 0xD3 | ||||
| #define COM_PINS 0xDA | ||||
| #define COM_PINS_SEQ 0x02 | ||||
| #define COM_PINS_ALT 0x12 | ||||
| #define COM_PINS_SEQ_LR 0x22 | ||||
| #define COM_PINS_ALT_LR 0x32 | ||||
| 
 | ||||
| // Timing & Driving Commands
 | ||||
| #define DISPLAY_CLOCK           0xD5 | ||||
| #define PRE_CHARGE_PERIOD       0xD9 | ||||
| #define VCOM_DETECT             0xDB | ||||
| #define DISPLAY_CLOCK 0xD5 | ||||
| #define PRE_CHARGE_PERIOD 0xD9 | ||||
| #define VCOM_DETECT 0xDB | ||||
| 
 | ||||
| // Charge Pump Commands
 | ||||
| #define CHARGE_PUMP             0x8D | ||||
| #define CHARGE_PUMP 0x8D | ||||
| 
 | ||||
| // Misc defines
 | ||||
| #define OLED_TIMEOUT 60000 | ||||
|  | @ -91,12 +91,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #define I2C_CMD 0x00 | ||||
| #define I2C_DATA 0x40 | ||||
| #if defined(__AVR__) | ||||
|   // already defined on ARM
 | ||||
|   #define I2C_TIMEOUT 100 | ||||
|   #define I2C_TRANSMIT_P(data) i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), I2C_TIMEOUT) | ||||
| #else // defined(__AVR__)
 | ||||
|   #define I2C_TRANSMIT_P(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), I2C_TIMEOUT) | ||||
| #endif // defined(__AVR__)
 | ||||
| // already defined on ARM
 | ||||
| #    define I2C_TIMEOUT 100 | ||||
| #    define I2C_TRANSMIT_P(data) i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), I2C_TIMEOUT) | ||||
| #else  // defined(__AVR__)
 | ||||
| #    define I2C_TRANSMIT_P(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), I2C_TIMEOUT) | ||||
| #endif  // defined(__AVR__)
 | ||||
| #define I2C_TRANSMIT(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), I2C_TIMEOUT) | ||||
| #define I2C_WRITE_REG(mode, data, size) i2c_writeReg((OLED_DISPLAY_ADDRESS << 1), mode, data, size, I2C_TIMEOUT) | ||||
| 
 | ||||
|  | @ -106,19 +106,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| // this is so we don't end up with rounding errors with
 | ||||
| // parts of the display unusable or don't get cleared correctly
 | ||||
| // and also allows for drawing & inverting
 | ||||
| uint8_t          oled_buffer[OLED_MATRIX_SIZE]; | ||||
| uint8_t*         oled_cursor; | ||||
| OLED_BLOCK_TYPE  oled_dirty = 0; | ||||
| bool             oled_initialized = false; | ||||
| bool             oled_active = false; | ||||
| bool             oled_scrolling = false; | ||||
| uint8_t          oled_rotation = 0; | ||||
| uint8_t          oled_rotation_width = 0; | ||||
| uint8_t         oled_buffer[OLED_MATRIX_SIZE]; | ||||
| uint8_t *       oled_cursor; | ||||
| OLED_BLOCK_TYPE oled_dirty          = 0; | ||||
| bool            oled_initialized    = false; | ||||
| bool            oled_active         = false; | ||||
| bool            oled_scrolling      = false; | ||||
| uint8_t         oled_rotation       = 0; | ||||
| uint8_t         oled_rotation_width = 0; | ||||
| #if OLED_TIMEOUT > 0 | ||||
|   uint32_t         oled_timeout; | ||||
| uint32_t oled_timeout; | ||||
| #endif | ||||
| #if OLED_SCROLL_TIMEOUT > 0 | ||||
|   uint32_t         oled_scroll_timeout; | ||||
| uint32_t oled_scroll_timeout; | ||||
| #endif | ||||
| 
 | ||||
| // Internal variables to reduce math instructions
 | ||||
|  | @ -126,468 +126,445 @@ uint8_t          oled_rotation_width = 0; | |||
| #if defined(__AVR__) | ||||
| // identical to i2c_transmit, but for PROGMEM since all initialization is in PROGMEM arrays currently
 | ||||
| // probably should move this into i2c_master...
 | ||||
| static i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { | ||||
|   i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); | ||||
| static i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) { | ||||
|     i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); | ||||
| 
 | ||||
|   for (uint16_t i = 0; i < length && status >= 0; i++) { | ||||
|     status = i2c_write(pgm_read_byte((const char*)data++), timeout); | ||||
|     if (status) break; | ||||
|   } | ||||
|     for (uint16_t i = 0; i < length && status >= 0; i++) { | ||||
|         status = i2c_write(pgm_read_byte((const char *)data++), timeout); | ||||
|         if (status) break; | ||||
|     } | ||||
| 
 | ||||
|   i2c_stop(); | ||||
|     i2c_stop(); | ||||
| 
 | ||||
|   return status; | ||||
|     return status; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // Flips the rendering bits for a character at the current cursor position
 | ||||
| static void InvertCharacter(uint8_t *cursor) | ||||
| { | ||||
|   const uint8_t *end = cursor + OLED_FONT_WIDTH; | ||||
|   while (cursor < end) { | ||||
|     *cursor = ~(*cursor); | ||||
|     cursor++; | ||||
|   } | ||||
| static void InvertCharacter(uint8_t *cursor) { | ||||
|     const uint8_t *end = cursor + OLED_FONT_WIDTH; | ||||
|     while (cursor < end) { | ||||
|         *cursor = ~(*cursor); | ||||
|         cursor++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool oled_init(uint8_t rotation) { | ||||
|   oled_rotation = oled_init_user(rotation); | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|     oled_rotation_width = OLED_DISPLAY_WIDTH; | ||||
|   } else { | ||||
|     oled_rotation_width = OLED_DISPLAY_HEIGHT; | ||||
|   } | ||||
|   i2c_init(); | ||||
|     oled_rotation = oled_init_user(rotation); | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|         oled_rotation_width = OLED_DISPLAY_WIDTH; | ||||
|     } else { | ||||
|         oled_rotation_width = OLED_DISPLAY_HEIGHT; | ||||
|     } | ||||
|     i2c_init(); | ||||
| 
 | ||||
|   static const uint8_t PROGMEM display_setup1[] = { | ||||
|     I2C_CMD, | ||||
|     DISPLAY_OFF, | ||||
|     DISPLAY_CLOCK, 0x80, | ||||
|     MULTIPLEX_RATIO, OLED_DISPLAY_HEIGHT - 1, | ||||
|     DISPLAY_OFFSET, 0x00, | ||||
|     DISPLAY_START_LINE | 0x00, | ||||
|     CHARGE_PUMP, 0x14, | ||||
|     static const uint8_t PROGMEM display_setup1[] = { | ||||
|         I2C_CMD, | ||||
|         DISPLAY_OFF, | ||||
|         DISPLAY_CLOCK, | ||||
|         0x80, | ||||
|         MULTIPLEX_RATIO, | ||||
|         OLED_DISPLAY_HEIGHT - 1, | ||||
|         DISPLAY_OFFSET, | ||||
|         0x00, | ||||
|         DISPLAY_START_LINE | 0x00, | ||||
|         CHARGE_PUMP, | ||||
|         0x14, | ||||
| #if (OLED_IC != OLED_IC_SH1106) | ||||
|     // MEMORY_MODE is unsupported on SH1106 (Page Addressing only)
 | ||||
|     MEMORY_MODE, 0x00, // Horizontal addressing mode
 | ||||
|         // MEMORY_MODE is unsupported on SH1106 (Page Addressing only)
 | ||||
|         MEMORY_MODE, | ||||
|         0x00,  // Horizontal addressing mode
 | ||||
| #endif | ||||
|   }; | ||||
|   if (I2C_TRANSMIT_P(display_setup1) != I2C_STATUS_SUCCESS) { | ||||
|     print("oled_init cmd set 1 failed\n"); | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_180)) { | ||||
|     static const uint8_t PROGMEM display_normal[] = { | ||||
|       I2C_CMD, | ||||
|       SEGMENT_REMAP_INV, | ||||
|       COM_SCAN_DEC }; | ||||
|     if (I2C_TRANSMIT_P(display_normal) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_init cmd normal rotation failed\n"); | ||||
|       return false; | ||||
|     }; | ||||
|     if (I2C_TRANSMIT_P(display_setup1) != I2C_STATUS_SUCCESS) { | ||||
|         print("oled_init cmd set 1 failed\n"); | ||||
|         return false; | ||||
|     } | ||||
|   } else { | ||||
|     static const uint8_t PROGMEM display_flipped[] = { | ||||
|       I2C_CMD, | ||||
|       SEGMENT_REMAP, | ||||
|       COM_SCAN_INC }; | ||||
|     if (I2C_TRANSMIT_P(display_flipped) != I2C_STATUS_SUCCESS) { | ||||
|       print("display_flipped failed\n"); | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   static const uint8_t PROGMEM display_setup2[] = { | ||||
|     I2C_CMD, | ||||
|     COM_PINS, OLED_COM_PINS, | ||||
|     CONTRAST, 0x8F, | ||||
|     PRE_CHARGE_PERIOD, 0xF1, | ||||
|     VCOM_DETECT, 0x40, | ||||
|     DISPLAY_ALL_ON_RESUME, | ||||
|     NORMAL_DISPLAY, | ||||
|     DEACTIVATE_SCROLL, | ||||
|     DISPLAY_ON }; | ||||
|   if (I2C_TRANSMIT_P(display_setup2) != I2C_STATUS_SUCCESS) { | ||||
|     print("display_setup2 failed\n"); | ||||
|     return false; | ||||
|   } | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_180)) { | ||||
|         static const uint8_t PROGMEM display_normal[] = {I2C_CMD, SEGMENT_REMAP_INV, COM_SCAN_DEC}; | ||||
|         if (I2C_TRANSMIT_P(display_normal) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_init cmd normal rotation failed\n"); | ||||
|             return false; | ||||
|         } | ||||
|     } else { | ||||
|         static const uint8_t PROGMEM display_flipped[] = {I2C_CMD, SEGMENT_REMAP, COM_SCAN_INC}; | ||||
|         if (I2C_TRANSMIT_P(display_flipped) != I2C_STATUS_SUCCESS) { | ||||
|             print("display_flipped failed\n"); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static const uint8_t PROGMEM display_setup2[] = {I2C_CMD, COM_PINS, OLED_COM_PINS, CONTRAST, 0x8F, PRE_CHARGE_PERIOD, 0xF1, VCOM_DETECT, 0x40, DISPLAY_ALL_ON_RESUME, NORMAL_DISPLAY, DEACTIVATE_SCROLL, DISPLAY_ON}; | ||||
|     if (I2C_TRANSMIT_P(display_setup2) != I2C_STATUS_SUCCESS) { | ||||
|         print("display_setup2 failed\n"); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| #if OLED_TIMEOUT > 0 | ||||
|   oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||
|     oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||
| #endif | ||||
| #if OLED_SCROLL_TIMEOUT > 0 | ||||
|   oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||
|     oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||
| #endif | ||||
| 
 | ||||
|   oled_clear(); | ||||
|   oled_initialized = true; | ||||
|   oled_active = true; | ||||
|   oled_scrolling = false; | ||||
|   return true; | ||||
|     oled_clear(); | ||||
|     oled_initialized = true; | ||||
|     oled_active      = true; | ||||
|     oled_scrolling   = false; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) | ||||
| oled_rotation_t oled_init_user(oled_rotation_t rotation) { | ||||
|   return rotation; | ||||
| } | ||||
| __attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) { return rotation; } | ||||
| 
 | ||||
| void oled_clear(void) { | ||||
|   memset(oled_buffer, 0, sizeof(oled_buffer)); | ||||
|   oled_cursor = &oled_buffer[0]; | ||||
|   oled_dirty = -1; // -1 will be max value as long as display_dirty is unsigned type
 | ||||
|     memset(oled_buffer, 0, sizeof(oled_buffer)); | ||||
|     oled_cursor = &oled_buffer[0]; | ||||
|     oled_dirty  = -1;  // -1 will be max value as long as display_dirty is unsigned type
 | ||||
| } | ||||
| 
 | ||||
| static void calc_bounds(uint8_t update_start, uint8_t* cmd_array) | ||||
| { | ||||
|   // Calculate commands to set memory addressing bounds.
 | ||||
|   uint8_t start_page = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH; | ||||
|   uint8_t start_column = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH; | ||||
| static void calc_bounds(uint8_t update_start, uint8_t *cmd_array) { | ||||
|     // Calculate commands to set memory addressing bounds.
 | ||||
|     uint8_t start_page   = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH; | ||||
|     uint8_t start_column = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH; | ||||
| #if (OLED_IC == OLED_IC_SH1106) | ||||
|   // Commands for Page Addressing Mode. Sets starting page and column; has no end bound.
 | ||||
|   // Column value must be split into high and low nybble and sent as two commands.
 | ||||
|   cmd_array[0] = PAM_PAGE_ADDR | start_page; | ||||
|   cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f); | ||||
|   cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f); | ||||
|   cmd_array[3] = NOP; | ||||
|   cmd_array[4] = NOP; | ||||
|   cmd_array[5] = NOP; | ||||
|     // Commands for Page Addressing Mode. Sets starting page and column; has no end bound.
 | ||||
|     // Column value must be split into high and low nybble and sent as two commands.
 | ||||
|     cmd_array[0] = PAM_PAGE_ADDR | start_page; | ||||
|     cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f); | ||||
|     cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f); | ||||
|     cmd_array[3] = NOP; | ||||
|     cmd_array[4] = NOP; | ||||
|     cmd_array[5] = NOP; | ||||
| #else | ||||
|   // Commands for use in Horizontal Addressing mode.
 | ||||
|   cmd_array[1] = start_column; | ||||
|   cmd_array[4] = start_page; | ||||
|   cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) % OLED_DISPLAY_WIDTH + cmd_array[1]; | ||||
|   cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) / OLED_DISPLAY_WIDTH - 1; | ||||
|     // Commands for use in Horizontal Addressing mode.
 | ||||
|     cmd_array[1] = start_column; | ||||
|     cmd_array[4] = start_page; | ||||
|     cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) % OLED_DISPLAY_WIDTH + cmd_array[1]; | ||||
|     cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) / OLED_DISPLAY_WIDTH - 1; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void calc_bounds_90(uint8_t update_start, uint8_t* cmd_array) | ||||
| { | ||||
|   cmd_array[1] = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_HEIGHT * 8; | ||||
|   cmd_array[4] = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_HEIGHT; | ||||
|   cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) / OLED_DISPLAY_HEIGHT * 8 - 1 + cmd_array[1];; | ||||
|   cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) % OLED_DISPLAY_HEIGHT / 8; | ||||
| static void calc_bounds_90(uint8_t update_start, uint8_t *cmd_array) { | ||||
|     cmd_array[1] = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_HEIGHT * 8; | ||||
|     cmd_array[4] = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_HEIGHT; | ||||
|     cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) / OLED_DISPLAY_HEIGHT * 8 - 1 + cmd_array[1]; | ||||
|     ; | ||||
|     cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) % OLED_DISPLAY_HEIGHT / 8; | ||||
| } | ||||
| 
 | ||||
| uint8_t crot(uint8_t a, int8_t n) | ||||
| { | ||||
|   const uint8_t mask = 0x7; | ||||
|   n &= mask; | ||||
|   return a << n | a >> (-n & mask); | ||||
| uint8_t crot(uint8_t a, int8_t n) { | ||||
|     const uint8_t mask = 0x7; | ||||
|     n &= mask; | ||||
|     return a << n | a >> (-n & mask); | ||||
| } | ||||
| 
 | ||||
| static void rotate_90(const uint8_t* src, uint8_t* dest) | ||||
| { | ||||
|   for (uint8_t i = 0, shift = 7; i < 8; ++i, --shift) { | ||||
|     uint8_t selector = (1 << i); | ||||
|     for (uint8_t j = 0; j < 8; ++j) { | ||||
|       dest[i] |= crot(src[j] & selector, shift - (int8_t)j); | ||||
| static void rotate_90(const uint8_t *src, uint8_t *dest) { | ||||
|     for (uint8_t i = 0, shift = 7; i < 8; ++i, --shift) { | ||||
|         uint8_t selector = (1 << i); | ||||
|         for (uint8_t j = 0; j < 8; ++j) { | ||||
|             dest[i] |= crot(src[j] & selector, shift - (int8_t)j); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void oled_render(void) { | ||||
|   // Do we have work to do?
 | ||||
|   if (!oled_dirty || oled_scrolling) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Find first dirty block
 | ||||
|   uint8_t update_start = 0; | ||||
|   while (!(oled_dirty & (1 << update_start))) { ++update_start; } | ||||
| 
 | ||||
|   // Set column & page position
 | ||||
|   static uint8_t display_start[] = { | ||||
|     I2C_CMD, | ||||
|     COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, | ||||
|     PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1 }; | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|     calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
 | ||||
|   } else { | ||||
|     calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
 | ||||
|   } | ||||
| 
 | ||||
|   // Send column & page position
 | ||||
|   if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) { | ||||
|     print("oled_render offset command failed\n"); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|     // Send render data chunk as is
 | ||||
|     if (I2C_WRITE_REG(I2C_DATA, &oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_render data failed\n"); | ||||
|       return; | ||||
|     } | ||||
|   } else { | ||||
|     // Rotate the render chunks
 | ||||
|     const static uint8_t source_map[] = OLED_SOURCE_MAP; | ||||
|     const static uint8_t target_map[] = OLED_TARGET_MAP; | ||||
| 
 | ||||
|     static uint8_t temp_buffer[OLED_BLOCK_SIZE]; | ||||
|     memset(temp_buffer, 0, sizeof(temp_buffer)); | ||||
|     for(uint8_t i = 0; i < sizeof(source_map); ++i) { | ||||
|       rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]); | ||||
|     // Do we have work to do?
 | ||||
|     if (!oled_dirty || oled_scrolling) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Send render data chunk after rotating
 | ||||
|     if (I2C_WRITE_REG(I2C_DATA, &temp_buffer[0], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_render90 data failed\n"); | ||||
|       return; | ||||
|     // Find first dirty block
 | ||||
|     uint8_t update_start = 0; | ||||
|     while (!(oled_dirty & (1 << update_start))) { | ||||
|         ++update_start; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Turn on display if it is off
 | ||||
|   oled_on(); | ||||
|     // Set column & page position
 | ||||
|     static uint8_t display_start[] = {I2C_CMD, COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1}; | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|         calc_bounds(update_start, &display_start[1]);  // Offset from I2C_CMD byte at the start
 | ||||
|     } else { | ||||
|         calc_bounds_90(update_start, &display_start[1]);  // Offset from I2C_CMD byte at the start
 | ||||
|     } | ||||
| 
 | ||||
|   // Clear dirty flag
 | ||||
|   oled_dirty &= ~(1 << update_start); | ||||
|     // Send column & page position
 | ||||
|     if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) { | ||||
|         print("oled_render offset command failed\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|         // Send render data chunk as is
 | ||||
|         if (I2C_WRITE_REG(I2C_DATA, &oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_render data failed\n"); | ||||
|             return; | ||||
|         } | ||||
|     } else { | ||||
|         // Rotate the render chunks
 | ||||
|         const static uint8_t source_map[] = OLED_SOURCE_MAP; | ||||
|         const static uint8_t target_map[] = OLED_TARGET_MAP; | ||||
| 
 | ||||
|         static uint8_t temp_buffer[OLED_BLOCK_SIZE]; | ||||
|         memset(temp_buffer, 0, sizeof(temp_buffer)); | ||||
|         for (uint8_t i = 0; i < sizeof(source_map); ++i) { | ||||
|             rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]); | ||||
|         } | ||||
| 
 | ||||
|         // Send render data chunk after rotating
 | ||||
|         if (I2C_WRITE_REG(I2C_DATA, &temp_buffer[0], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_render90 data failed\n"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Turn on display if it is off
 | ||||
|     oled_on(); | ||||
| 
 | ||||
|     // Clear dirty flag
 | ||||
|     oled_dirty &= ~(1 << update_start); | ||||
| } | ||||
| 
 | ||||
| void oled_set_cursor(uint8_t col, uint8_t line) { | ||||
|   uint16_t index = line * oled_rotation_width + col * OLED_FONT_WIDTH; | ||||
|     uint16_t index = line * oled_rotation_width + col * OLED_FONT_WIDTH; | ||||
| 
 | ||||
|   // Out of bounds?
 | ||||
|   if (index >= OLED_MATRIX_SIZE) { | ||||
|     index = 0; | ||||
|   } | ||||
|     // Out of bounds?
 | ||||
|     if (index >= OLED_MATRIX_SIZE) { | ||||
|         index = 0; | ||||
|     } | ||||
| 
 | ||||
|   oled_cursor = &oled_buffer[index]; | ||||
|     oled_cursor = &oled_buffer[index]; | ||||
| } | ||||
| 
 | ||||
| void oled_advance_page(bool clearPageRemainder) { | ||||
|   uint16_t index = oled_cursor - &oled_buffer[0]; | ||||
|   uint8_t remaining = oled_rotation_width - (index % oled_rotation_width); | ||||
|     uint16_t index     = oled_cursor - &oled_buffer[0]; | ||||
|     uint8_t  remaining = oled_rotation_width - (index % oled_rotation_width); | ||||
| 
 | ||||
|   if (clearPageRemainder) { | ||||
|     // Remaining Char count
 | ||||
|     remaining = remaining / OLED_FONT_WIDTH; | ||||
|     if (clearPageRemainder) { | ||||
|         // Remaining Char count
 | ||||
|         remaining = remaining / OLED_FONT_WIDTH; | ||||
| 
 | ||||
|     // Write empty character until next line
 | ||||
|     while (remaining--) | ||||
|       oled_write_char(' ', false); | ||||
|   } else { | ||||
|     // Next page index out of bounds?
 | ||||
|     if (index + remaining >= OLED_MATRIX_SIZE) { | ||||
|       index = 0; | ||||
|       remaining = 0; | ||||
|         // Write empty character until next line
 | ||||
|         while (remaining--) oled_write_char(' ', false); | ||||
|     } else { | ||||
|         // Next page index out of bounds?
 | ||||
|         if (index + remaining >= OLED_MATRIX_SIZE) { | ||||
|             index     = 0; | ||||
|             remaining = 0; | ||||
|         } | ||||
| 
 | ||||
|         oled_cursor = &oled_buffer[index + remaining]; | ||||
|     } | ||||
| 
 | ||||
|     oled_cursor = &oled_buffer[index + remaining]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void oled_advance_char(void) { | ||||
|   uint16_t nextIndex = oled_cursor - &oled_buffer[0] + OLED_FONT_WIDTH; | ||||
|   uint8_t remainingSpace = oled_rotation_width - (nextIndex % oled_rotation_width); | ||||
|     uint16_t nextIndex      = oled_cursor - &oled_buffer[0] + OLED_FONT_WIDTH; | ||||
|     uint8_t  remainingSpace = oled_rotation_width - (nextIndex % oled_rotation_width); | ||||
| 
 | ||||
|   // Do we have enough space on the current line for the next character
 | ||||
|   if (remainingSpace < OLED_FONT_WIDTH) { | ||||
|     nextIndex += remainingSpace; | ||||
|   } | ||||
|     // Do we have enough space on the current line for the next character
 | ||||
|     if (remainingSpace < OLED_FONT_WIDTH) { | ||||
|         nextIndex += remainingSpace; | ||||
|     } | ||||
| 
 | ||||
|   // Did we go out of bounds
 | ||||
|   if (nextIndex >= OLED_MATRIX_SIZE) { | ||||
|     nextIndex = 0; | ||||
|   } | ||||
|     // Did we go out of bounds
 | ||||
|     if (nextIndex >= OLED_MATRIX_SIZE) { | ||||
|         nextIndex = 0; | ||||
|     } | ||||
| 
 | ||||
|   // Update cursor position
 | ||||
|   oled_cursor = &oled_buffer[nextIndex]; | ||||
|     // Update cursor position
 | ||||
|     oled_cursor = &oled_buffer[nextIndex]; | ||||
| } | ||||
| 
 | ||||
| // Main handler that writes character data to the display buffer
 | ||||
| void oled_write_char(const char data, bool invert) { | ||||
|   // Advance to the next line if newline
 | ||||
|   if (data == '\n') { | ||||
|     // Old source wrote ' ' until end of line...
 | ||||
|     oled_advance_page(true); | ||||
|     return; | ||||
|   } | ||||
|     // Advance to the next line if newline
 | ||||
|     if (data == '\n') { | ||||
|         // Old source wrote ' ' until end of line...
 | ||||
|         oled_advance_page(true); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|   if (data == '\r') { | ||||
|     oled_advance_page(false); | ||||
|     return; | ||||
|   } | ||||
|     if (data == '\r') { | ||||
|         oled_advance_page(false); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|   // copy the current render buffer to check for dirty after
 | ||||
|   static uint8_t oled_temp_buffer[OLED_FONT_WIDTH]; | ||||
|   memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH); | ||||
|     // copy the current render buffer to check for dirty after
 | ||||
|     static uint8_t oled_temp_buffer[OLED_FONT_WIDTH]; | ||||
|     memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH); | ||||
| 
 | ||||
|   // set the reder buffer data
 | ||||
|   uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
 | ||||
|   if (cast_data < OLED_FONT_START || cast_data > OLED_FONT_END) { | ||||
|     memset(oled_cursor, 0x00, OLED_FONT_WIDTH); | ||||
|   } else { | ||||
|     const uint8_t *glyph = &font[(cast_data - OLED_FONT_START) * OLED_FONT_WIDTH]; | ||||
|     memcpy_P(oled_cursor, glyph, OLED_FONT_WIDTH); | ||||
|   } | ||||
|     // set the reder buffer data
 | ||||
|     uint8_t cast_data = (uint8_t)data;  // font based on unsigned type for index
 | ||||
|     if (cast_data < OLED_FONT_START || cast_data > OLED_FONT_END) { | ||||
|         memset(oled_cursor, 0x00, OLED_FONT_WIDTH); | ||||
|     } else { | ||||
|         const uint8_t *glyph = &font[(cast_data - OLED_FONT_START) * OLED_FONT_WIDTH]; | ||||
|         memcpy_P(oled_cursor, glyph, OLED_FONT_WIDTH); | ||||
|     } | ||||
| 
 | ||||
|   // Invert if needed
 | ||||
|   if (invert) { | ||||
|     InvertCharacter(oled_cursor); | ||||
|   } | ||||
|     // Invert if needed
 | ||||
|     if (invert) { | ||||
|         InvertCharacter(oled_cursor); | ||||
|     } | ||||
| 
 | ||||
|   // Dirty check
 | ||||
|   if (memcmp(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH)) { | ||||
|     uint16_t index = oled_cursor - &oled_buffer[0]; | ||||
|     oled_dirty |= (1 << (index / OLED_BLOCK_SIZE)); | ||||
|     // Edgecase check if the written data spans the 2 chunks
 | ||||
|     oled_dirty |= (1 << ((index + OLED_FONT_WIDTH) / OLED_BLOCK_SIZE)); | ||||
|   } | ||||
|     // Dirty check
 | ||||
|     if (memcmp(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH)) { | ||||
|         uint16_t index = oled_cursor - &oled_buffer[0]; | ||||
|         oled_dirty |= (1 << (index / OLED_BLOCK_SIZE)); | ||||
|         // Edgecase check if the written data spans the 2 chunks
 | ||||
|         oled_dirty |= (1 << ((index + OLED_FONT_WIDTH) / OLED_BLOCK_SIZE)); | ||||
|     } | ||||
| 
 | ||||
|   // Finally move to the next char
 | ||||
|   oled_advance_char(); | ||||
|     // Finally move to the next char
 | ||||
|     oled_advance_char(); | ||||
| } | ||||
| 
 | ||||
| void oled_write(const char *data, bool invert) { | ||||
|   const char *end = data + strlen(data); | ||||
|   while (data < end) { | ||||
|     oled_write_char(*data, invert); | ||||
|     data++; | ||||
|   } | ||||
|     const char *end = data + strlen(data); | ||||
|     while (data < end) { | ||||
|         oled_write_char(*data, invert); | ||||
|         data++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void oled_write_ln(const char *data, bool invert) { | ||||
|   oled_write(data, invert); | ||||
|   oled_advance_page(true); | ||||
|     oled_write(data, invert); | ||||
|     oled_advance_page(true); | ||||
| } | ||||
| 
 | ||||
| #if defined(__AVR__) | ||||
| void oled_write_P(const char *data, bool invert) { | ||||
|   uint8_t c = pgm_read_byte(data); | ||||
|   while (c != 0) { | ||||
|     oled_write_char(c, invert); | ||||
|     c = pgm_read_byte(++data); | ||||
|   } | ||||
|     uint8_t c = pgm_read_byte(data); | ||||
|     while (c != 0) { | ||||
|         oled_write_char(c, invert); | ||||
|         c = pgm_read_byte(++data); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void oled_write_ln_P(const char *data, bool invert) { | ||||
|   oled_write_P(data, invert); | ||||
|   oled_advance_page(true); | ||||
|     oled_write_P(data, invert); | ||||
|     oled_advance_page(true); | ||||
| } | ||||
| #endif // defined(__AVR__)
 | ||||
| #endif  // defined(__AVR__)
 | ||||
| 
 | ||||
| bool oled_on(void) { | ||||
| #if OLED_TIMEOUT > 0 | ||||
|   oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||
|     oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||
| #endif | ||||
| 
 | ||||
|   static const uint8_t PROGMEM display_on[] = { I2C_CMD, DISPLAY_ON }; | ||||
|   if (!oled_active) { | ||||
|     if (I2C_TRANSMIT_P(display_on) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_on cmd failed\n"); | ||||
|       return oled_active; | ||||
|     static const uint8_t PROGMEM display_on[] = {I2C_CMD, DISPLAY_ON}; | ||||
|     if (!oled_active) { | ||||
|         if (I2C_TRANSMIT_P(display_on) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_on cmd failed\n"); | ||||
|             return oled_active; | ||||
|         } | ||||
|         oled_active = true; | ||||
|     } | ||||
|     oled_active = true; | ||||
|   } | ||||
|   return oled_active; | ||||
|     return oled_active; | ||||
| } | ||||
| 
 | ||||
| bool oled_off(void) { | ||||
|   static const uint8_t PROGMEM display_off[] = { I2C_CMD, DISPLAY_OFF }; | ||||
|   if (oled_active) { | ||||
|     if (I2C_TRANSMIT_P(display_off) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_off cmd failed\n"); | ||||
|       return oled_active; | ||||
|     static const uint8_t PROGMEM display_off[] = {I2C_CMD, DISPLAY_OFF}; | ||||
|     if (oled_active) { | ||||
|         if (I2C_TRANSMIT_P(display_off) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_off cmd failed\n"); | ||||
|             return oled_active; | ||||
|         } | ||||
|         oled_active = false; | ||||
|     } | ||||
|     oled_active = false; | ||||
|   } | ||||
|   return !oled_active; | ||||
|     return !oled_active; | ||||
| } | ||||
| 
 | ||||
| bool oled_scroll_right(void) { | ||||
|   // Dont enable scrolling if we need to update the display
 | ||||
|   // This prevents scrolling of bad data from starting the scroll too early after init
 | ||||
|   if (!oled_dirty && !oled_scrolling) { | ||||
|     static const uint8_t PROGMEM display_scroll_right[] = { | ||||
|       I2C_CMD, SCROLL_RIGHT, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xFF, ACTIVATE_SCROLL }; | ||||
|     if (I2C_TRANSMIT_P(display_scroll_right) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_scroll_right cmd failed\n"); | ||||
|       return oled_scrolling; | ||||
|     // Dont enable scrolling if we need to update the display
 | ||||
|     // This prevents scrolling of bad data from starting the scroll too early after init
 | ||||
|     if (!oled_dirty && !oled_scrolling) { | ||||
|         static const uint8_t PROGMEM display_scroll_right[] = {I2C_CMD, SCROLL_RIGHT, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xFF, ACTIVATE_SCROLL}; | ||||
|         if (I2C_TRANSMIT_P(display_scroll_right) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_scroll_right cmd failed\n"); | ||||
|             return oled_scrolling; | ||||
|         } | ||||
|         oled_scrolling = true; | ||||
|     } | ||||
|     oled_scrolling = true; | ||||
|   } | ||||
|   return oled_scrolling; | ||||
|     return oled_scrolling; | ||||
| } | ||||
| 
 | ||||
| bool oled_scroll_left(void) { | ||||
|   // Dont enable scrolling if we need to update the display
 | ||||
|   // This prevents scrolling of bad data from starting the scroll too early after init
 | ||||
|   if (!oled_dirty && !oled_scrolling) { | ||||
|     static const uint8_t PROGMEM display_scroll_left[] = { | ||||
|       I2C_CMD, SCROLL_LEFT, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xFF, ACTIVATE_SCROLL }; | ||||
|     if (I2C_TRANSMIT_P(display_scroll_left) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_scroll_left cmd failed\n"); | ||||
|       return oled_scrolling; | ||||
|     // Dont enable scrolling if we need to update the display
 | ||||
|     // This prevents scrolling of bad data from starting the scroll too early after init
 | ||||
|     if (!oled_dirty && !oled_scrolling) { | ||||
|         static const uint8_t PROGMEM display_scroll_left[] = {I2C_CMD, SCROLL_LEFT, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xFF, ACTIVATE_SCROLL}; | ||||
|         if (I2C_TRANSMIT_P(display_scroll_left) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_scroll_left cmd failed\n"); | ||||
|             return oled_scrolling; | ||||
|         } | ||||
|         oled_scrolling = true; | ||||
|     } | ||||
|     oled_scrolling = true; | ||||
|   } | ||||
|   return oled_scrolling; | ||||
|     return oled_scrolling; | ||||
| } | ||||
| 
 | ||||
| bool oled_scroll_off(void) { | ||||
|   if (oled_scrolling) { | ||||
|     static const uint8_t PROGMEM display_scroll_off[] = { I2C_CMD, DEACTIVATE_SCROLL }; | ||||
|     if (I2C_TRANSMIT_P(display_scroll_off) != I2C_STATUS_SUCCESS) { | ||||
|       print("oled_scroll_off cmd failed\n"); | ||||
|       return oled_scrolling; | ||||
|     if (oled_scrolling) { | ||||
|         static const uint8_t PROGMEM display_scroll_off[] = {I2C_CMD, DEACTIVATE_SCROLL}; | ||||
|         if (I2C_TRANSMIT_P(display_scroll_off) != I2C_STATUS_SUCCESS) { | ||||
|             print("oled_scroll_off cmd failed\n"); | ||||
|             return oled_scrolling; | ||||
|         } | ||||
|         oled_scrolling = false; | ||||
|         oled_dirty     = -1; | ||||
|     } | ||||
|     oled_scrolling = false; | ||||
|     oled_dirty = -1; | ||||
|   } | ||||
|   return !oled_scrolling; | ||||
|     return !oled_scrolling; | ||||
| } | ||||
| 
 | ||||
| uint8_t oled_max_chars(void) { | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|     return OLED_DISPLAY_WIDTH / OLED_FONT_WIDTH; | ||||
|   } | ||||
|   return OLED_DISPLAY_HEIGHT / OLED_FONT_WIDTH; | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|         return OLED_DISPLAY_WIDTH / OLED_FONT_WIDTH; | ||||
|     } | ||||
|     return OLED_DISPLAY_HEIGHT / OLED_FONT_WIDTH; | ||||
| } | ||||
| 
 | ||||
| uint8_t oled_max_lines(void) { | ||||
|   if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|     return OLED_DISPLAY_HEIGHT / OLED_FONT_HEIGHT; | ||||
|   } | ||||
|   return OLED_DISPLAY_WIDTH / OLED_FONT_HEIGHT; | ||||
|     if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) { | ||||
|         return OLED_DISPLAY_HEIGHT / OLED_FONT_HEIGHT; | ||||
|     } | ||||
|     return OLED_DISPLAY_WIDTH / OLED_FONT_HEIGHT; | ||||
| } | ||||
| 
 | ||||
| void oled_task(void) { | ||||
|   if (!oled_initialized) { | ||||
|     return; | ||||
|   } | ||||
|     if (!oled_initialized) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|   oled_set_cursor(0, 0); | ||||
|     oled_set_cursor(0, 0); | ||||
| 
 | ||||
|   oled_task_user(); | ||||
|     oled_task_user(); | ||||
| 
 | ||||
| #if OLED_SCROLL_TIMEOUT > 0 | ||||
|   if (oled_dirty && oled_scrolling) { | ||||
|     oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||
|     oled_scroll_off(); | ||||
|   } | ||||
|     if (oled_dirty && oled_scrolling) { | ||||
|         oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||
|         oled_scroll_off(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|   // Smart render system, no need to check for dirty
 | ||||
|   oled_render(); | ||||
|     // Smart render system, no need to check for dirty
 | ||||
|     oled_render(); | ||||
| 
 | ||||
|   // Display timeout check
 | ||||
|     // Display timeout check
 | ||||
| #if OLED_TIMEOUT > 0 | ||||
|   if (oled_active && timer_expired32(timer_read32(), oled_timeout)) { | ||||
|     oled_off(); | ||||
|   } | ||||
|     if (oled_active && timer_expired32(timer_read32(), oled_timeout)) { | ||||
|         oled_off(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #if OLED_SCROLL_TIMEOUT > 0 | ||||
|   if (!oled_scrolling && timer_expired32(timer_read32(), oled_scroll_timeout)) { | ||||
| #ifdef OLED_SCROLL_TIMEOUT_RIGHT | ||||
|     oled_scroll_right(); | ||||
| #else | ||||
|     oled_scroll_left(); | ||||
| #endif | ||||
|   } | ||||
|     if (!oled_scrolling && timer_expired32(timer_read32(), oled_scroll_timeout)) { | ||||
| #    ifdef OLED_SCROLL_TIMEOUT_RIGHT | ||||
|         oled_scroll_right(); | ||||
| #    else | ||||
|         oled_scroll_left(); | ||||
| #    endif | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) | ||||
| void oled_task_user(void) { | ||||
| } | ||||
| __attribute__((weak)) void oled_task_user(void) {} | ||||
|  |  | |||
|  | @ -21,129 +21,133 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| 
 | ||||
| // an enumeration of the chips this driver supports
 | ||||
| #define OLED_IC_SSD1306 0 | ||||
| #define OLED_IC_SH1106  1 | ||||
| #define OLED_IC_SH1106 1 | ||||
| 
 | ||||
| #if defined(OLED_DISPLAY_CUSTOM) | ||||
|   // Expected user to implement the necessary defines
 | ||||
| // Expected user to implement the necessary defines
 | ||||
| #elif defined(OLED_DISPLAY_128X64) | ||||
|   // Double height 128x64
 | ||||
| #ifndef OLED_DISPLAY_WIDTH | ||||
|   #define OLED_DISPLAY_WIDTH 128 | ||||
| #endif | ||||
| #ifndef OLED_DISPLAY_HEIGHT | ||||
|   #define OLED_DISPLAY_HEIGHT 64 | ||||
| #endif | ||||
| #ifndef OLED_MATRIX_SIZE | ||||
|   #define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 1024 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_TYPE | ||||
|   #define OLED_BLOCK_TYPE uint16_t | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_COUNT | ||||
|   #define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 32 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_SIZE | ||||
|   #define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_COM_PINS | ||||
|   #define OLED_COM_PINS COM_PINS_ALT | ||||
| #endif | ||||
| // Double height 128x64
 | ||||
| #    ifndef OLED_DISPLAY_WIDTH | ||||
| #        define OLED_DISPLAY_WIDTH 128 | ||||
| #    endif | ||||
| #    ifndef OLED_DISPLAY_HEIGHT | ||||
| #        define OLED_DISPLAY_HEIGHT 64 | ||||
| #    endif | ||||
| #    ifndef OLED_MATRIX_SIZE | ||||
| #        define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)  // 1024 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_TYPE | ||||
| #        define OLED_BLOCK_TYPE uint16_t | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_COUNT | ||||
| #        define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8)  // 32 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_SIZE | ||||
| #        define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)  // 32 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_COM_PINS | ||||
| #        define OLED_COM_PINS COM_PINS_ALT | ||||
| #    endif | ||||
| 
 | ||||
|   // For 90 degree rotation, we map our internal matrix to oled matrix using fixed arrays
 | ||||
|   // The OLED writes to it's memory horizontally, starting top left, but our memory starts bottom left in this mode
 | ||||
| #ifndef OLED_SOURCE_MAP | ||||
|   #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 } | ||||
| #endif | ||||
| #ifndef OLED_TARGET_MAP | ||||
|   #define OLED_TARGET_MAP { 56, 48, 40, 32, 24, 16, 8, 0 } | ||||
| #endif | ||||
|   // If OLED_BLOCK_TYPE is uint32_t, these tables would look like:
 | ||||
|   // #define OLED_SOURCE_MAP { 32, 40, 48, 56 }
 | ||||
|   // #define OLED_TARGET_MAP { 24, 16, 8, 0 }
 | ||||
|   // If OLED_BLOCK_TYPE is uint16_t, these tables would look like:
 | ||||
|   // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 }
 | ||||
|   // #define OLED_TARGET_MAP { 56, 48, 40, 32, 24, 16, 8, 0 }
 | ||||
|   // If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
 | ||||
|   // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }
 | ||||
|   // #define OLED_TARGET_MAP { 56, 120, 48, 112, 40, 104, 32, 96, 24, 88, 16, 80, 8, 72, 0, 64 }
 | ||||
| #else // defined(OLED_DISPLAY_128X64)
 | ||||
|   // Default 128x32
 | ||||
| #ifndef OLED_DISPLAY_WIDTH | ||||
|   #define OLED_DISPLAY_WIDTH 128 | ||||
| #endif | ||||
| #ifndef OLED_DISPLAY_HEIGHT | ||||
|   #define OLED_DISPLAY_HEIGHT 32 | ||||
| #endif | ||||
| #ifndef OLED_MATRIX_SIZE | ||||
|   #define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 512 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_TYPE | ||||
|   #define OLED_BLOCK_TYPE uint16_t // Type to use for segmenting the oled display for smart rendering, use unsigned types only
 | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_COUNT | ||||
|   #define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 16 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_BLOCK_SIZE | ||||
|   #define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
 | ||||
| #endif | ||||
| #ifndef OLED_COM_PINS | ||||
|   #define OLED_COM_PINS COM_PINS_SEQ | ||||
| #endif | ||||
| // For 90 degree rotation, we map our internal matrix to oled matrix using fixed arrays
 | ||||
| // The OLED writes to it's memory horizontally, starting top left, but our memory starts bottom left in this mode
 | ||||
| #    ifndef OLED_SOURCE_MAP | ||||
| #        define OLED_SOURCE_MAP \ | ||||
|             { 0, 8, 16, 24, 32, 40, 48, 56 } | ||||
| #    endif | ||||
| #    ifndef OLED_TARGET_MAP | ||||
| #        define OLED_TARGET_MAP \ | ||||
|             { 56, 48, 40, 32, 24, 16, 8, 0 } | ||||
| #    endif | ||||
| // If OLED_BLOCK_TYPE is uint32_t, these tables would look like:
 | ||||
| // #define OLED_SOURCE_MAP { 32, 40, 48, 56 }
 | ||||
| // #define OLED_TARGET_MAP { 24, 16, 8, 0 }
 | ||||
| // If OLED_BLOCK_TYPE is uint16_t, these tables would look like:
 | ||||
| // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 }
 | ||||
| // #define OLED_TARGET_MAP { 56, 48, 40, 32, 24, 16, 8, 0 }
 | ||||
| // If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
 | ||||
| // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }
 | ||||
| // #define OLED_TARGET_MAP { 56, 120, 48, 112, 40, 104, 32, 96, 24, 88, 16, 80, 8, 72, 0, 64 }
 | ||||
| #else  // defined(OLED_DISPLAY_128X64)
 | ||||
| // Default 128x32
 | ||||
| #    ifndef OLED_DISPLAY_WIDTH | ||||
| #        define OLED_DISPLAY_WIDTH 128 | ||||
| #    endif | ||||
| #    ifndef OLED_DISPLAY_HEIGHT | ||||
| #        define OLED_DISPLAY_HEIGHT 32 | ||||
| #    endif | ||||
| #    ifndef OLED_MATRIX_SIZE | ||||
| #        define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)  // 512 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_TYPE | ||||
| #        define OLED_BLOCK_TYPE uint16_t  // Type to use for segmenting the oled display for smart rendering, use unsigned types only
 | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_COUNT | ||||
| #        define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8)  // 16 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_BLOCK_SIZE | ||||
| #        define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)  // 32 (compile time mathed)
 | ||||
| #    endif | ||||
| #    ifndef OLED_COM_PINS | ||||
| #        define OLED_COM_PINS COM_PINS_SEQ | ||||
| #    endif | ||||
| 
 | ||||
|   // For 90 degree rotation, we map our internal matrix to oled matrix using fixed arrays
 | ||||
|   // The OLED writes to it's memory horizontally, starting top left, but our memory starts bottom left in this mode
 | ||||
| #ifndef OLED_SOURCE_MAP | ||||
|   #define OLED_SOURCE_MAP { 0, 8, 16, 24 } | ||||
| #endif | ||||
| #ifndef OLED_TARGET_MAP | ||||
|   #define OLED_TARGET_MAP { 24, 16, 8, 0 } | ||||
| #endif | ||||
|   // If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
 | ||||
|   // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 }
 | ||||
|   // #define OLED_TARGET_MAP { 48, 32, 16, 0, 56, 40, 24, 8 }
 | ||||
| #endif // defined(OLED_DISPLAY_CUSTOM)
 | ||||
| // For 90 degree rotation, we map our internal matrix to oled matrix using fixed arrays
 | ||||
| // The OLED writes to it's memory horizontally, starting top left, but our memory starts bottom left in this mode
 | ||||
| #    ifndef OLED_SOURCE_MAP | ||||
| #        define OLED_SOURCE_MAP \ | ||||
|             { 0, 8, 16, 24 } | ||||
| #    endif | ||||
| #    ifndef OLED_TARGET_MAP | ||||
| #        define OLED_TARGET_MAP \ | ||||
|             { 24, 16, 8, 0 } | ||||
| #    endif | ||||
| // If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
 | ||||
| // #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 }
 | ||||
| // #define OLED_TARGET_MAP { 48, 32, 16, 0, 56, 40, 24, 8 }
 | ||||
| #endif  // defined(OLED_DISPLAY_CUSTOM)
 | ||||
| 
 | ||||
| #if !defined(OLED_IC) | ||||
|   #define OLED_IC OLED_IC_SSD1306 | ||||
| #    define OLED_IC OLED_IC_SSD1306 | ||||
| #endif | ||||
| 
 | ||||
| // the column address corresponding to the first column in the display hardware
 | ||||
| #if !defined(OLED_COLUMN_OFFSET) | ||||
|   #define OLED_COLUMN_OFFSET 0 | ||||
| #    define OLED_COLUMN_OFFSET 0 | ||||
| #endif | ||||
| 
 | ||||
| // Address to use for the i2c oled communication
 | ||||
| #if !defined(OLED_DISPLAY_ADDRESS) | ||||
|   #define OLED_DISPLAY_ADDRESS 0x3C | ||||
| #    define OLED_DISPLAY_ADDRESS 0x3C | ||||
| #endif | ||||
| 
 | ||||
| // Custom font file to use
 | ||||
| #if !defined(OLED_FONT_H) | ||||
|   #define OLED_FONT_H "glcdfont.c" | ||||
| #    define OLED_FONT_H "glcdfont.c" | ||||
| #endif | ||||
| // unsigned char value of the first character in the font file
 | ||||
| #if !defined(OLED_FONT_START) | ||||
|   #define OLED_FONT_START 0 | ||||
| #    define OLED_FONT_START 0 | ||||
| #endif | ||||
| // unsigned char value of the last character in the font file
 | ||||
| #if !defined(OLED_FONT_END) | ||||
|   #define OLED_FONT_END 224 | ||||
| #    define OLED_FONT_END 224 | ||||
| #endif | ||||
| // Font render width
 | ||||
| #if !defined(OLED_FONT_WIDTH) | ||||
|   #define OLED_FONT_WIDTH 6 | ||||
| #    define OLED_FONT_WIDTH 6 | ||||
| #endif | ||||
| // Font render height
 | ||||
| #if !defined(OLED_FONT_HEIGHT) | ||||
|   #define OLED_FONT_HEIGHT 8 | ||||
| #    define OLED_FONT_HEIGHT 8 | ||||
| #endif | ||||
| 
 | ||||
| #if !defined(OLED_TIMEOUT) | ||||
|   #if defined(OLED_DISABLE_TIMEOUT) | ||||
|     #define OLED_TIMEOUT 0 | ||||
|   #else | ||||
|     #define OLED_TIMEOUT 60000 | ||||
|   #endif | ||||
| #    if defined(OLED_DISABLE_TIMEOUT) | ||||
| #        define OLED_TIMEOUT 0 | ||||
| #    else | ||||
| #        define OLED_TIMEOUT 60000 | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| // OLED Rotation enum values are flags
 | ||||
|  | @ -151,7 +155,7 @@ typedef enum { | |||
|     OLED_ROTATION_0   = 0, | ||||
|     OLED_ROTATION_90  = 1, | ||||
|     OLED_ROTATION_180 = 2, | ||||
|     OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180
 | ||||
|     OLED_ROTATION_270 = 3,  // OLED_ROTATION_90 | OLED_ROTATION_180
 | ||||
| } oled_rotation_t; | ||||
| 
 | ||||
| // Initialize the oled display, rotating the rendered output based on the define passed in.
 | ||||
|  | @ -208,15 +212,15 @@ void oled_write_P(const char *data, bool invert); | |||
| // Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM
 | ||||
| void oled_write_ln_P(const char *data, bool invert); | ||||
| #else | ||||
|   // Writes a string to the buffer at current cursor position
 | ||||
|   // Advances the cursor while writing, inverts the pixels if true
 | ||||
|   #define oled_write_P(data, invert) oled_write(data, invert) | ||||
| // Writes a string to the buffer at current cursor position
 | ||||
| // Advances the cursor while writing, inverts the pixels if true
 | ||||
| #    define oled_write_P(data, invert) oled_write(data, invert) | ||||
| 
 | ||||
|   // Writes a string to the buffer at current cursor position
 | ||||
|   // Advances the cursor while writing, inverts the pixels if true
 | ||||
|   // Advances the cursor to the next page, wiring ' ' to the remainder of the current page
 | ||||
|   #define oled_write_ln_P(data, invert) oled_write(data, invert) | ||||
| #endif // defined(__AVR__)
 | ||||
| // Writes a string to the buffer at current cursor position
 | ||||
| // Advances the cursor while writing, inverts the pixels if true
 | ||||
| // Advances the cursor to the next page, wiring ' ' to the remainder of the current page
 | ||||
| #    define oled_write_ln_P(data, invert) oled_write(data, invert) | ||||
| #endif  // defined(__AVR__)
 | ||||
| 
 | ||||
| // Can be used to manually turn on the screen if it is off
 | ||||
| // Returns true if the screen was on or turns on
 | ||||
|  |  | |||
|  | @ -35,16 +35,21 @@ | |||
| #include "string.h" | ||||
| 
 | ||||
| #define TOTALFONTS 2 | ||||
| const unsigned char * fonts_pointer[]= { font5x7, font8x16 }; | ||||
| const unsigned char* fonts_pointer[] = {font5x7, font8x16}; | ||||
| 
 | ||||
| uint8_t foreColor,drawMode,fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY; | ||||
| uint8_t  foreColor, drawMode, fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY; | ||||
| uint16_t fontMapWidth; | ||||
| 
 | ||||
| #define _BV(x) (1 << (x)) | ||||
| #define swap(a, b) { uint8_t t = a; a = b; b = t; } | ||||
| #define swap(a, b)     \ | ||||
|     {                  \ | ||||
|         uint8_t t = a; \ | ||||
|         a         = b; \ | ||||
|         b         = t; \ | ||||
|     } | ||||
| 
 | ||||
| uint8_t micro_oled_transfer_buffer[20]; | ||||
| static uint8_t micro_oled_screen_current[LCDWIDTH*LCDWIDTH/8] = { 0 }; | ||||
| uint8_t        micro_oled_transfer_buffer[20]; | ||||
| static uint8_t micro_oled_screen_current[LCDWIDTH * LCDWIDTH / 8] = {0}; | ||||
| 
 | ||||
| /* LCD Memory organised in 64 horizontal pixel and 6 rows of byte
 | ||||
|    B  B .............B  ----- | ||||
|  | @ -64,628 +69,399 @@ static uint8_t micro_oled_screen_current[LCDWIDTH*LCDWIDTH/8] = { 0 }; | |||
|   */ | ||||
| 
 | ||||
| #if LCDWIDTH == 64 | ||||
|   #if LCDWIDTH == 48 | ||||
| #    if LCDWIDTH == 48 | ||||
| static uint8_t micro_oled_screen_buffer[] = { | ||||
| // QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php
 | ||||
| //64x48 image
 | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, | ||||
| 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, | ||||
| 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, | ||||
| 0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, | ||||
| 0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, | ||||
| 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF, | ||||
| 0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7, | ||||
| 0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, | ||||
| 0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, | ||||
| 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, | ||||
| 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00 | ||||
| }; | ||||
|   #endif | ||||
|     // QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php
 | ||||
|     // 64x48 image
 | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF, 0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7, 0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
| #    endif | ||||
| #elif LCDWIDTH == 128 | ||||
|   #if LCDHEIGHT == 32 | ||||
|      static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = { | ||||
| //128x32 qmk image
 | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC, | ||||
| 0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC, | ||||
| 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00, | ||||
| 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, | ||||
| 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, | ||||
| 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, | ||||
| 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, | ||||
| 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03, | ||||
| 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10, | ||||
| 0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01, | ||||
| 0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12, | ||||
| 0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12, | ||||
| 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3, | ||||
| 0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, | ||||
| 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0, | ||||
| 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C, | ||||
| 0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C, | ||||
| 0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00, | ||||
| 0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F, | ||||
| 0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F, | ||||
| 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, | ||||
| 0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04, | ||||
| 0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, | ||||
| 0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, | ||||
| 0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00 | ||||
|     }; | ||||
|   #elif LCDHEIGHT == 64 | ||||
|     static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = { | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, | ||||
| 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, | ||||
| 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, | ||||
| 0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE, | ||||
| 0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, | ||||
| 0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00, | ||||
| 0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF, | ||||
| 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F, | ||||
| 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, | ||||
| 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, | ||||
| 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, | ||||
| 0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01, | ||||
| 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70, | ||||
| 0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0, | ||||
| 0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24, | ||||
| 0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8, | ||||
| 0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04, | ||||
| 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, | ||||
| 0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0, | ||||
| 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01, | ||||
| 0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70, | ||||
| 0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18, | ||||
| 0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, | ||||
| 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, | ||||
| 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, | ||||
| 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||||
| 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, | ||||
| 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||
|     }; | ||||
| //TODO: generate bitmap of QMK logo here
 | ||||
|   #endif | ||||
| #    if LCDHEIGHT == 32 | ||||
| static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDWIDTH / 8] = { | ||||
|     // 128x32 qmk image
 | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC, 0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01, 0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3, 0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C, 0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
| #    elif LCDHEIGHT == 64 | ||||
| static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDWIDTH / 8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00, 0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70, 0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04, 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01, 0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70, 0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18, 0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
| // TODO: generate bitmap of QMK logo here
 | ||||
| #    endif | ||||
| #else | ||||
| //catchall for custom screen szies
 | ||||
|     static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = {0}; | ||||
| // catchall for custom screen szies
 | ||||
| static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDWIDTH / 8] = {0}; | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void micro_oled_init(void) { | ||||
|   i2c_init(); | ||||
|   i2c_start(I2C_ADDRESS_SA0_1); | ||||
|     i2c_init(); | ||||
|     i2c_start(I2C_ADDRESS_SA0_1); | ||||
| 
 | ||||
|   // Display Init sequence for 64x48 OLED module
 | ||||
|   send_command(DISPLAYOFF);      // 0xAE
 | ||||
|     // Display Init sequence for 64x48 OLED module
 | ||||
|     send_command(DISPLAYOFF);  // 0xAE
 | ||||
| 
 | ||||
|   send_command(SETDISPLAYCLOCKDIV);  // 0xD5
 | ||||
|   send_command(0x80);          // the suggested ratio 0x80
 | ||||
|     send_command(SETDISPLAYCLOCKDIV);  // 0xD5
 | ||||
|     send_command(0x80);                // the suggested ratio 0x80
 | ||||
| 
 | ||||
|   send_command(SETMULTIPLEX);      // 0xA8
 | ||||
|   send_command(LCDHEIGHT - 1); | ||||
|     send_command(SETMULTIPLEX);  // 0xA8
 | ||||
|     send_command(LCDHEIGHT - 1); | ||||
| 
 | ||||
|   send_command(SETDISPLAYOFFSET);    // 0xD3
 | ||||
|   send_command(0x00);         // no offset
 | ||||
|     send_command(SETDISPLAYOFFSET);  // 0xD3
 | ||||
|     send_command(0x00);              // no offset
 | ||||
| 
 | ||||
|   send_command(SETSTARTLINE | 0x00);  // line #0
 | ||||
|     send_command(SETSTARTLINE | 0x00);  // line #0
 | ||||
| 
 | ||||
|   send_command(CHARGEPUMP);      // enable charge pump
 | ||||
|   send_command(0x14); | ||||
|     send_command(CHARGEPUMP);  // enable charge pump
 | ||||
|     send_command(0x14); | ||||
| 
 | ||||
|   send_command(NORMALDISPLAY);     // 0xA6
 | ||||
|   send_command(DISPLAYALLONRESUME);  // 0xA4
 | ||||
|     send_command(NORMALDISPLAY);       // 0xA6
 | ||||
|     send_command(DISPLAYALLONRESUME);  // 0xA4
 | ||||
| 
 | ||||
| //display at regular orientation
 | ||||
|   send_command(SEGREMAP | 0x1); | ||||
|   send_command(COMSCANDEC); | ||||
|     // display at regular orientation
 | ||||
|     send_command(SEGREMAP | 0x1); | ||||
|     send_command(COMSCANDEC); | ||||
| 
 | ||||
| //rotate display 180
 | ||||
| // rotate display 180
 | ||||
| #ifdef micro_oled_rotate_180 | ||||
|   send_command(SEGREMAP); | ||||
|   send_command(COMSCANINC); | ||||
|     send_command(SEGREMAP); | ||||
|     send_command(COMSCANINC); | ||||
| #endif | ||||
| 
 | ||||
|   send_command(MEMORYMODE); | ||||
|   send_command(0x10); | ||||
|     send_command(MEMORYMODE); | ||||
|     send_command(0x10); | ||||
| 
 | ||||
|   send_command(SETCOMPINS);      // 0xDA
 | ||||
| if (LCDHEIGHT > 32) { | ||||
|   send_command(0x12); | ||||
| } else { | ||||
|   send_command(0x02); | ||||
| } | ||||
|   send_command(SETCONTRAST);     // 0x81
 | ||||
|   send_command(0x8F); | ||||
|     send_command(SETCOMPINS);  // 0xDA
 | ||||
|     if (LCDHEIGHT > 32) { | ||||
|         send_command(0x12); | ||||
|     } else { | ||||
|         send_command(0x02); | ||||
|     } | ||||
|     send_command(SETCONTRAST);  // 0x81
 | ||||
|     send_command(0x8F); | ||||
| 
 | ||||
|   send_command(SETPRECHARGE);      // 0xd9
 | ||||
|   send_command(0xF1); | ||||
|     send_command(SETPRECHARGE);  // 0xd9
 | ||||
|     send_command(0xF1); | ||||
| 
 | ||||
|   send_command(SETVCOMDESELECT);     // 0xDB
 | ||||
|   send_command(0x40); | ||||
|     send_command(SETVCOMDESELECT);  // 0xDB
 | ||||
|     send_command(0x40); | ||||
| 
 | ||||
|   send_command(DISPLAYON);       //--turn on oled panel
 | ||||
|   clear_screen();           // Erase hardware memory inside the OLED controller to avoid random data in memory.
 | ||||
|   send_buffer(); | ||||
|     send_command(DISPLAYON);  //--turn on oled panel
 | ||||
|     clear_screen();           // Erase hardware memory inside the OLED controller to avoid random data in memory.
 | ||||
|     send_buffer(); | ||||
| } | ||||
| 
 | ||||
| void send_command(uint8_t command) { | ||||
|   micro_oled_transfer_buffer[0] = I2C_COMMAND; | ||||
|   micro_oled_transfer_buffer[1] = command; | ||||
|   i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); | ||||
|     micro_oled_transfer_buffer[0] = I2C_COMMAND; | ||||
|     micro_oled_transfer_buffer[1] = command; | ||||
|     i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); | ||||
| } | ||||
| 
 | ||||
| void send_data(uint8_t data) { | ||||
|   micro_oled_transfer_buffer[0] = I2C_DATA; | ||||
|   micro_oled_transfer_buffer[1] = data; | ||||
|   i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); | ||||
|     micro_oled_transfer_buffer[0] = I2C_DATA; | ||||
|     micro_oled_transfer_buffer[1] = data; | ||||
|     i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); | ||||
| } | ||||
| 
 | ||||
| /** \brief Set SSD1306 page address.
 | ||||
|     Send page address command and address to the SSD1306 OLED controller. | ||||
| */ | ||||
| void set_page_address(uint8_t address) { | ||||
|   address = (0xB0 | address); | ||||
|   send_command(address); | ||||
|     address = (0xB0 | address); | ||||
|     send_command(address); | ||||
| } | ||||
| 
 | ||||
| /** \brief Set SSD1306 column address.
 | ||||
|     Send column address command and address to the SSD1306 OLED controller. | ||||
| */ | ||||
| void set_column_address(uint8_t address) { | ||||
|   send_command( ( 0x10 | (address >> 4) ) + ((128 - LCDWIDTH) >> 8) ); | ||||
|   send_command( 0x0F & address ); | ||||
|     send_command((0x10 | (address >> 4)) + ((128 - LCDWIDTH) >> 8)); | ||||
|     send_command(0x0F & address); | ||||
| } | ||||
| 
 | ||||
| /** \brief Clear SSD1306's memory.
 | ||||
|     To clear GDRAM inside the LCD controller. | ||||
| */ | ||||
| void clear_screen(void) { | ||||
|   for (int i=0;i<8; i++) { | ||||
|     set_page_address(i); | ||||
|     set_column_address(0); | ||||
|     for (int j=0; j<0x80; j++) { | ||||
|       send_data(0); | ||||
|     for (int i = 0; i < 8; i++) { | ||||
|         set_page_address(i); | ||||
|         set_column_address(0); | ||||
|         for (int j = 0; j < 0x80; j++) { | ||||
|             send_data(0); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** \brief Clear SSD1306's memory.
 | ||||
|     To clear GDRAM inside the LCD controller. | ||||
| */ | ||||
| void clear_buffer(void) { | ||||
| //384
 | ||||
|   memset(micro_oled_screen_buffer, 0, LCDWIDTH*LCDWIDTH/8); | ||||
|     // 384
 | ||||
|     memset(micro_oled_screen_buffer, 0, LCDWIDTH * LCDWIDTH / 8); | ||||
| } | ||||
| 
 | ||||
| /** \brief Invert display.
 | ||||
|     The PIXEL_ON color of the display will turn to PIXEL_OFF and the PIXEL_OFF will turn to PIXEL_ON. | ||||
| */ | ||||
| void invert_screen(bool invert) { | ||||
|   if (invert) { | ||||
|     send_command(INVERTDISPLAY); | ||||
|   } else { | ||||
|     send_command(NORMALDISPLAY); | ||||
|   } | ||||
|     if (invert) { | ||||
|         send_command(INVERTDISPLAY); | ||||
|     } else { | ||||
|         send_command(NORMALDISPLAY); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** \brief Set contrast.
 | ||||
|     OLED contract value from 0 to 255. Note: Contrast level is not very obvious. | ||||
| */ | ||||
| void set_contrast(uint8_t contrast) { | ||||
|   send_command(SETCONTRAST);     // 0x81
 | ||||
|   send_command(contrast); | ||||
|     send_command(SETCONTRAST);  // 0x81
 | ||||
|     send_command(contrast); | ||||
| } | ||||
| 
 | ||||
| /** \brief Transfer display buffer.
 | ||||
|   Sends the updated buffer to the controller - the current status is checked before to save i2c exectution time | ||||
| */ | ||||
| void send_buffer(void) { | ||||
|   uint8_t i, j; | ||||
|     uint8_t i, j; | ||||
| 
 | ||||
|   uint8_t page_addr = 0xFF; | ||||
|   for (i = 0; i < LCDHEIGHT/8; i++) { | ||||
|     uint8_t col_addr = 0xFF; | ||||
|     for (j = 0; j < LCDWIDTH; j++) { | ||||
|       if (micro_oled_screen_buffer[i*LCDWIDTH+j] != micro_oled_screen_current[i*LCDWIDTH+j]) { | ||||
|         if (page_addr != i) { | ||||
|           set_page_address(i); | ||||
|     uint8_t page_addr = 0xFF; | ||||
|     for (i = 0; i < LCDHEIGHT / 8; i++) { | ||||
|         uint8_t col_addr = 0xFF; | ||||
|         for (j = 0; j < LCDWIDTH; j++) { | ||||
|             if (micro_oled_screen_buffer[i * LCDWIDTH + j] != micro_oled_screen_current[i * LCDWIDTH + j]) { | ||||
|                 if (page_addr != i) { | ||||
|                     set_page_address(i); | ||||
|                 } | ||||
|                 if (col_addr != j) { | ||||
|                     set_column_address(j); | ||||
|                 } | ||||
|                 send_data(micro_oled_screen_buffer[i * LCDWIDTH + j]); | ||||
|                 micro_oled_screen_current[i * LCDWIDTH + j] = micro_oled_screen_buffer[i * LCDWIDTH + j]; | ||||
|                 col_addr                                    = j + 1; | ||||
|             } | ||||
|         } | ||||
|         if (col_addr != j) { | ||||
|           set_column_address(j); | ||||
|         } | ||||
|         send_data(micro_oled_screen_buffer[i*LCDWIDTH+j]); | ||||
|         micro_oled_screen_current[i*LCDWIDTH+j] = micro_oled_screen_buffer[i*LCDWIDTH+j]; | ||||
|         col_addr = j + 1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw pixel with color and mode.
 | ||||
|   Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode. | ||||
| */ | ||||
| void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) { | ||||
|   if ((x<0) ||  (x>=LCDWIDTH) || (y<0) || (y>=LCDHEIGHT)) | ||||
|     return; | ||||
|     if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT)) return; | ||||
| 
 | ||||
|   if (mode == XOR) { | ||||
|     if (color == PIXEL_ON) | ||||
|       micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] ^= _BV((y%8)); | ||||
|   } else { | ||||
|     if (color == PIXEL_ON) | ||||
|       micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] |= _BV((y%8)); | ||||
|     else | ||||
|       micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] &= ~_BV((y%8)); | ||||
|   } | ||||
|     if (mode == XOR) { | ||||
|         if (color == PIXEL_ON) micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] ^= _BV((y % 8)); | ||||
|     } else { | ||||
|         if (color == PIXEL_ON) | ||||
|             micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] |= _BV((y % 8)); | ||||
|         else | ||||
|             micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] &= ~_BV((y % 8)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw line with color and mode.
 | ||||
| Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer. | ||||
| */ | ||||
| void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) { | ||||
|   uint8_t steep = abs(y1 - y0) > abs(x1 - x0); | ||||
|   if (steep) { | ||||
|     swap(x0, y0); | ||||
|     swap(x1, y1); | ||||
|   } | ||||
| 
 | ||||
|   if (x0 > x1) { | ||||
|     swap(x0, x1); | ||||
|     swap(y0, y1); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t dx, dy; | ||||
|   dx = x1 - x0; | ||||
|   dy = abs(y1 - y0); | ||||
| 
 | ||||
|   int8_t err = dx / 2; | ||||
|   int8_t ystep; | ||||
| 
 | ||||
|   if (y0 < y1) { | ||||
|     ystep = 1; | ||||
|   } else { | ||||
|     ystep = -1;} | ||||
| 
 | ||||
|   for (; x0<x1; x0++) { | ||||
|     uint8_t steep = abs(y1 - y0) > abs(x1 - x0); | ||||
|     if (steep) { | ||||
|       draw_pixel(y0, x0, color, mode); | ||||
|         swap(x0, y0); | ||||
|         swap(x1, y1); | ||||
|     } | ||||
| 
 | ||||
|     if (x0 > x1) { | ||||
|         swap(x0, x1); | ||||
|         swap(y0, y1); | ||||
|     } | ||||
| 
 | ||||
|     uint8_t dx, dy; | ||||
|     dx = x1 - x0; | ||||
|     dy = abs(y1 - y0); | ||||
| 
 | ||||
|     int8_t err = dx / 2; | ||||
|     int8_t ystep; | ||||
| 
 | ||||
|     if (y0 < y1) { | ||||
|         ystep = 1; | ||||
|     } else { | ||||
|       draw_pixel(x0, y0, color, mode); | ||||
|         ystep = -1; | ||||
|     } | ||||
|     err -= dy; | ||||
|     if (err < 0) { | ||||
|       y0 += ystep; | ||||
|       err += dx; | ||||
| 
 | ||||
|     for (; x0 < x1; x0++) { | ||||
|         if (steep) { | ||||
|             draw_pixel(y0, x0, color, mode); | ||||
|         } else { | ||||
|             draw_pixel(x0, y0, color, mode); | ||||
|         } | ||||
|         err -= dy; | ||||
|         if (err < 0) { | ||||
|             y0 += ystep; | ||||
|             err += dx; | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw horizontal line with color and mode.
 | ||||
| Draw horizontal line using color and mode from x,y to x+width,y of the screen buffer. | ||||
| */ | ||||
| void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode) { | ||||
|   draw_line(x,y,x+width,y,color,mode); | ||||
| } | ||||
| void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode) { draw_line(x, y, x + width, y, color, mode); } | ||||
| 
 | ||||
| /** \brief Draw vertical line.
 | ||||
| Draw vertical line using current fore color and current draw mode from x,y to x,y+height of the screen buffer. | ||||
| */ | ||||
| void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode) { | ||||
|   draw_line(x,y,x,y+height,color,mode); | ||||
| } | ||||
| void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode) { draw_line(x, y, x, y + height, color, mode); } | ||||
| 
 | ||||
| /** \brief Draw rectangle with color and mode.
 | ||||
| Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer. | ||||
| */ | ||||
| void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { | ||||
|   uint8_t tempHeight; | ||||
|     uint8_t tempHeight; | ||||
| 
 | ||||
|   draw_line_hori(x,y, width, color, mode); | ||||
|   draw_line_hori(x,y+height-1, width, color, mode); | ||||
|     draw_line_hori(x, y, width, color, mode); | ||||
|     draw_line_hori(x, y + height - 1, width, color, mode); | ||||
| 
 | ||||
|   tempHeight=height-2; | ||||
|     tempHeight = height - 2; | ||||
| 
 | ||||
|   // skip drawing vertical lines to avoid overlapping of pixel that will
 | ||||
|   // affect XOR plot if no pixel in between horizontal lines
 | ||||
|   if (tempHeight<1) return; | ||||
|     // skip drawing vertical lines to avoid overlapping of pixel that will
 | ||||
|     // affect XOR plot if no pixel in between horizontal lines
 | ||||
|     if (tempHeight < 1) return; | ||||
| 
 | ||||
|   draw_line_vert(x,y+1, tempHeight, color, mode); | ||||
|   draw_line_vert(x+width-1, y+1, tempHeight, color, mode); | ||||
|     draw_line_vert(x, y + 1, tempHeight, color, mode); | ||||
|     draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode); | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw rectangle with color and mode.
 | ||||
| Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer. | ||||
| */ | ||||
| void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { | ||||
|   uint8_t tempHeight; | ||||
|     uint8_t tempHeight; | ||||
| 
 | ||||
|   draw_line_hori(x+1,y, width-2, color, mode); | ||||
|   draw_line_hori(x+1,y+height-1, width-2, color, mode); | ||||
|     draw_line_hori(x + 1, y, width - 2, color, mode); | ||||
|     draw_line_hori(x + 1, y + height - 1, width - 2, color, mode); | ||||
| 
 | ||||
|   tempHeight=height-2; | ||||
|     tempHeight = height - 2; | ||||
| 
 | ||||
|   // skip drawing vertical lines to avoid overlapping of pixel that will
 | ||||
|   // affect XOR plot if no pixel in between horizontal lines
 | ||||
|   if (tempHeight<1) return; | ||||
|     // skip drawing vertical lines to avoid overlapping of pixel that will
 | ||||
|     // affect XOR plot if no pixel in between horizontal lines
 | ||||
|     if (tempHeight < 1) return; | ||||
| 
 | ||||
|   draw_line_vert(x,y+1, tempHeight, color, mode); | ||||
|   draw_line_vert(x+width-1, y+1, tempHeight, color, mode); | ||||
|     draw_line_vert(x, y + 1, tempHeight, color, mode); | ||||
|     draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode); | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw filled rectangle with color and mode.
 | ||||
| Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer. | ||||
| */ | ||||
| void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { | ||||
|   // TODO - need to optimise the memory map draw so that this function will not call pixel one by one
 | ||||
|   for (int i=x; i<x+width;i++) { | ||||
|     draw_line_vert(i,y, height, color, mode); | ||||
|   } | ||||
|     // TODO - need to optimise the memory map draw so that this function will not call pixel one by one
 | ||||
|     for (int i = x; i < x + width; i++) { | ||||
|         draw_line_vert(i, y, height, color, mode); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw filled rectangle with color and mode.
 | ||||
| Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer. | ||||
| */ | ||||
| void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { | ||||
|   // TODO - need to optimise the memory map draw so that this function will not call pixel one by one
 | ||||
|   for (int i=x; i<x+width;i++) { | ||||
|     if (i == x || i == (x + width - 1)) | ||||
|       draw_line_vert(i, y+1, height-2, color, mode); | ||||
|     else | ||||
|       draw_line_vert(i, y, height, color, mode); | ||||
|   } | ||||
|     // TODO - need to optimise the memory map draw so that this function will not call pixel one by one
 | ||||
|     for (int i = x; i < x + width; i++) { | ||||
|         if (i == x || i == (x + width - 1)) | ||||
|             draw_line_vert(i, y + 1, height - 2, color, mode); | ||||
|         else | ||||
|             draw_line_vert(i, y, height, color, mode); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** \brief Draw character with color and mode.
 | ||||
|   Draw character c using color and draw mode at x,y. | ||||
| */ | ||||
| void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font) { | ||||
|   // TODO - New routine to take font of any height, at the moment limited to font height in multiple of 8 pixels
 | ||||
|     // TODO - New routine to take font of any height, at the moment limited to font height in multiple of 8 pixels
 | ||||
| 
 | ||||
|   uint8_t rowsToDraw,row, tempC; | ||||
|   uint8_t i,j,temp; | ||||
|   uint16_t charPerBitmapRow,charColPositionOnBitmap,charRowPositionOnBitmap,charBitmapStartPosition; | ||||
|     uint8_t  rowsToDraw, row, tempC; | ||||
|     uint8_t  i, j, temp; | ||||
|     uint16_t charPerBitmapRow, charColPositionOnBitmap, charRowPositionOnBitmap, charBitmapStartPosition; | ||||
| 
 | ||||
|   if ((font>=TOTALFONTS) || (font<0)) | ||||
|     return; | ||||
|     if ((font >= TOTALFONTS) || (font < 0)) return; | ||||
| 
 | ||||
|   uint8_t fontType = font; | ||||
|   uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0); | ||||
|   uint8_t fontHeight = pgm_read_byte(fonts_pointer[fontType]+1); | ||||
|   uint8_t fontStartChar = pgm_read_byte(fonts_pointer[fontType]+2); | ||||
|   uint8_t fontTotalChar = pgm_read_byte(fonts_pointer[fontType]+3); | ||||
|   uint16_t fontMapWidth = (pgm_read_byte(fonts_pointer[fontType]+4)*100)+pgm_read_byte(fonts_pointer[fontType]+5); // two bytes values into integer 16
 | ||||
|     uint8_t  fontType      = font; | ||||
|     uint8_t  fontWidth     = pgm_read_byte(fonts_pointer[fontType] + 0); | ||||
|     uint8_t  fontHeight    = pgm_read_byte(fonts_pointer[fontType] + 1); | ||||
|     uint8_t  fontStartChar = pgm_read_byte(fonts_pointer[fontType] + 2); | ||||
|     uint8_t  fontTotalChar = pgm_read_byte(fonts_pointer[fontType] + 3); | ||||
|     uint16_t fontMapWidth  = (pgm_read_byte(fonts_pointer[fontType] + 4) * 100) + pgm_read_byte(fonts_pointer[fontType] + 5);  // two bytes values into integer 16
 | ||||
| 
 | ||||
|   if ((c<fontStartChar) || (c>(fontStartChar+fontTotalChar-1)))   // no bitmap for the required c
 | ||||
|     return; | ||||
|     if ((c < fontStartChar) || (c > (fontStartChar + fontTotalChar - 1)))  // no bitmap for the required c
 | ||||
|         return; | ||||
| 
 | ||||
|   tempC=c-fontStartChar; | ||||
|     tempC = c - fontStartChar; | ||||
| 
 | ||||
|   // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn
 | ||||
|   rowsToDraw=fontHeight/8;  // 8 is LCD's page size, see SSD1306 datasheet
 | ||||
|   if (rowsToDraw<=1) rowsToDraw=1; | ||||
|     // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn
 | ||||
|     rowsToDraw = fontHeight / 8;  // 8 is LCD's page size, see SSD1306 datasheet
 | ||||
|     if (rowsToDraw <= 1) rowsToDraw = 1; | ||||
| 
 | ||||
|   // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw
 | ||||
|   if (rowsToDraw==1) { | ||||
|     for  (i=0;i<fontWidth+1;i++) { | ||||
|       if (i==fontWidth) // this is done in a weird way because for 5x7 font, there is no margin, this code add a margin after col 5
 | ||||
|       temp=0; | ||||
|       else | ||||
|       temp=pgm_read_byte(fonts_pointer[fontType]+FONTHEADERSIZE+(tempC*fontWidth)+i); | ||||
|     // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw
 | ||||
|     if (rowsToDraw == 1) { | ||||
|         for (i = 0; i < fontWidth + 1; i++) { | ||||
|             if (i == fontWidth)  // this is done in a weird way because for 5x7 font, there is no margin, this code add a margin after col 5
 | ||||
|                 temp = 0; | ||||
|             else | ||||
|                 temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (tempC * fontWidth) + i); | ||||
| 
 | ||||
|       for (j=0;j<8;j++) {     // 8 is the LCD's page height (see datasheet for explanation)
 | ||||
|         if (temp & 0x1) { | ||||
|           draw_pixel(x+i, y+j, color,mode); | ||||
|             for (j = 0; j < 8; j++) {  // 8 is the LCD's page height (see datasheet for explanation)
 | ||||
|                 if (temp & 0x1) { | ||||
|                     draw_pixel(x + i, y + j, color, mode); | ||||
|                 } else { | ||||
|                     draw_pixel(x + i, y + j, !color, mode); | ||||
|                 } | ||||
| 
 | ||||
|                 temp >>= 1; | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|           draw_pixel(x+i, y+j, !color,mode); | ||||
|         } | ||||
| 
 | ||||
|         temp >>=1; | ||||
|       } | ||||
|         return; | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // font height over 8 bit
 | ||||
|   // take character "0" ASCII 48 as example
 | ||||
|   charPerBitmapRow = fontMapWidth/fontWidth;  // 256/8 =32 char per row
 | ||||
|   charColPositionOnBitmap = tempC % charPerBitmapRow;  // =16
 | ||||
|   charRowPositionOnBitmap = (int)(tempC/charPerBitmapRow); // =1
 | ||||
|   charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight/8)) + (charColPositionOnBitmap * fontWidth) ; | ||||
|     // font height over 8 bit
 | ||||
|     // take character "0" ASCII 48 as example
 | ||||
|     charPerBitmapRow        = fontMapWidth / fontWidth;         // 256/8 =32 char per row
 | ||||
|     charColPositionOnBitmap = tempC % charPerBitmapRow;         // =16
 | ||||
|     charRowPositionOnBitmap = (int)(tempC / charPerBitmapRow);  // =1
 | ||||
|     charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight / 8)) + (charColPositionOnBitmap * fontWidth); | ||||
| 
 | ||||
|   // each row on LCD is 8 bit height (see datasheet for explanation)
 | ||||
|   for(row=0;row<rowsToDraw;row++) { | ||||
|     for (i=0; i<fontWidth;i++) { | ||||
|       temp=pgm_read_byte(fonts_pointer[fontType]+FONTHEADERSIZE+(charBitmapStartPosition+i+(row*fontMapWidth))); | ||||
|       for (j=0;j<8;j++) {     // 8 is the LCD's page height (see datasheet for explanation)
 | ||||
|         if (temp & 0x1) { | ||||
|           draw_pixel(x+i,y+j+(row*8), color, mode); | ||||
|     // each row on LCD is 8 bit height (see datasheet for explanation)
 | ||||
|     for (row = 0; row < rowsToDraw; row++) { | ||||
|         for (i = 0; i < fontWidth; i++) { | ||||
|             temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (charBitmapStartPosition + i + (row * fontMapWidth))); | ||||
|             for (j = 0; j < 8; j++) {  // 8 is the LCD's page height (see datasheet for explanation)
 | ||||
|                 if (temp & 0x1) { | ||||
|                     draw_pixel(x + i, y + j + (row * 8), color, mode); | ||||
|                 } else { | ||||
|                     draw_pixel(x + i, y + j + (row * 8), !color, mode); | ||||
|                 } | ||||
|                 temp >>= 1; | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|           draw_pixel(x+i,y+j+(row*8), !color, mode); | ||||
|         } | ||||
|         temp >>=1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font) { | ||||
| void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font) { | ||||
|     if ((font >= TOTALFONTS) || (font < 0)) return; | ||||
| 
 | ||||
|   if ((font>=TOTALFONTS) || (font<0)) | ||||
|     return; | ||||
| 
 | ||||
|   uint8_t fontType = font; | ||||
|   uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0); | ||||
| 
 | ||||
|   uint8_t cur_x = x; | ||||
|   for (int i = 0; i < strlen(string); i++) { | ||||
|     draw_char(cur_x, y, string[i], color, mode, font); | ||||
|     cur_x += fontWidth + 1; | ||||
|   } | ||||
|     uint8_t fontType  = font; | ||||
|     uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType] + 0); | ||||
| 
 | ||||
|     uint8_t cur_x = x; | ||||
|     for (int i = 0; i < strlen(string); i++) { | ||||
|         draw_char(cur_x, y, string[i], color, mode, font); | ||||
|         cur_x += fontWidth + 1; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -49,86 +49,86 @@ void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t | |||
| void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); | ||||
| void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); | ||||
| void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font); | ||||
| void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font); | ||||
| void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font); | ||||
| 
 | ||||
| #define I2C_ADDRESS_SA0_0 0b0111100 | ||||
| #ifndef I2C_ADDRESS_SA0_1 | ||||
| #define I2C_ADDRESS_SA0_1 0b0111101 | ||||
| #    define I2C_ADDRESS_SA0_1 0b0111101 | ||||
| #endif | ||||
| #define I2C_COMMAND 0x00 | ||||
| #define I2C_DATA 0x40 | ||||
| #define PIXEL_OFF 0 | ||||
| #define PIXEL_ON  1 | ||||
| #define PIXEL_ON 1 | ||||
| 
 | ||||
| #ifndef LCDWIDTH | ||||
| #define LCDWIDTH      64 | ||||
| #    define LCDWIDTH 64 | ||||
| #endif | ||||
| #ifndef LCDWIDTH | ||||
| #define LCDHEIGHT     48 | ||||
| #    define LCDHEIGHT 48 | ||||
| #endif | ||||
| #define FONTHEADERSIZE    6 | ||||
| #define FONTHEADERSIZE 6 | ||||
| 
 | ||||
| #define NORM        0 | ||||
| #define XOR         1 | ||||
| #define NORM 0 | ||||
| #define XOR 1 | ||||
| 
 | ||||
| #define PAGE        0 | ||||
| #define ALL         1 | ||||
| #define PAGE 0 | ||||
| #define ALL 1 | ||||
| 
 | ||||
| #define WIDGETSTYLE0      0 | ||||
| #define WIDGETSTYLE1      1 | ||||
| #define WIDGETSTYLE2      2 | ||||
| #define WIDGETSTYLE0 0 | ||||
| #define WIDGETSTYLE1 1 | ||||
| #define WIDGETSTYLE2 2 | ||||
| 
 | ||||
| #define SETCONTRAST     0x81 | ||||
| #define DISPLAYALLONRESUME  0xA4 | ||||
| #define DISPLAYALLON    0xA5 | ||||
| #define NORMALDISPLAY     0xA6 | ||||
| #define INVERTDISPLAY     0xA7 | ||||
| #define DISPLAYOFF      0xAE | ||||
| #define DISPLAYON       0xAF | ||||
| #define SETDISPLAYOFFSET  0xD3 | ||||
| #define SETCOMPINS      0xDA | ||||
| #define SETVCOMDESELECT   0xDB | ||||
| #define SETDISPLAYCLOCKDIV  0xD5 | ||||
| #define SETPRECHARGE    0xD9 | ||||
| #define SETMULTIPLEX    0xA8 | ||||
| #define SETLOWCOLUMN    0x00 | ||||
| #define SETHIGHCOLUMN     0x10 | ||||
| #define SETSTARTLINE    0x40 | ||||
| #define MEMORYMODE      0x20 | ||||
| #define COMSCANINC      0xC0 | ||||
| #define COMSCANDEC      0xC8 | ||||
| #define SEGREMAP      0xA0 | ||||
| #define CHARGEPUMP      0x8D | ||||
| #define EXTERNALVCC     0x01 | ||||
| #define SWITCHCAPVCC    0x02 | ||||
| #define SETCONTRAST 0x81 | ||||
| #define DISPLAYALLONRESUME 0xA4 | ||||
| #define DISPLAYALLON 0xA5 | ||||
| #define NORMALDISPLAY 0xA6 | ||||
| #define INVERTDISPLAY 0xA7 | ||||
| #define DISPLAYOFF 0xAE | ||||
| #define DISPLAYON 0xAF | ||||
| #define SETDISPLAYOFFSET 0xD3 | ||||
| #define SETCOMPINS 0xDA | ||||
| #define SETVCOMDESELECT 0xDB | ||||
| #define SETDISPLAYCLOCKDIV 0xD5 | ||||
| #define SETPRECHARGE 0xD9 | ||||
| #define SETMULTIPLEX 0xA8 | ||||
| #define SETLOWCOLUMN 0x00 | ||||
| #define SETHIGHCOLUMN 0x10 | ||||
| #define SETSTARTLINE 0x40 | ||||
| #define MEMORYMODE 0x20 | ||||
| #define COMSCANINC 0xC0 | ||||
| #define COMSCANDEC 0xC8 | ||||
| #define SEGREMAP 0xA0 | ||||
| #define CHARGEPUMP 0x8D | ||||
| #define EXTERNALVCC 0x01 | ||||
| #define SWITCHCAPVCC 0x02 | ||||
| 
 | ||||
| // Scroll
 | ||||
| #define ACTIVATESCROLL          0x2F | ||||
| #define DEACTIVATESCROLL        0x2E | ||||
| #define SETVERTICALSCROLLAREA       0xA3 | ||||
| #define RIGHTHORIZONTALSCROLL       0x26 | ||||
| #define LEFT_HORIZONTALSCROLL       0x27 | ||||
| #define ACTIVATESCROLL 0x2F | ||||
| #define DEACTIVATESCROLL 0x2E | ||||
| #define SETVERTICALSCROLLAREA 0xA3 | ||||
| #define RIGHTHORIZONTALSCROLL 0x26 | ||||
| #define LEFT_HORIZONTALSCROLL 0x27 | ||||
| #define VERTICALRIGHTHORIZONTALSCROLL 0x29 | ||||
| #define VERTICALLEFTHORIZONTALSCROLL  0x2A | ||||
| #define VERTICALLEFTHORIZONTALSCROLL 0x2A | ||||
| 
 | ||||
| typedef enum CMD { | ||||
|   CMD_CLEAR,      //0
 | ||||
|   CMD_INVERT,     //1
 | ||||
|   CMD_CONTRAST,   //2
 | ||||
|   CMD_DISPLAY,    //3
 | ||||
|   CMD_SETCURSOR,    //4
 | ||||
|   CMD_PIXEL,      //5
 | ||||
|   CMD_LINE,     //6
 | ||||
|   CMD_LINEH,      //7
 | ||||
|   CMD_LINEV,      //8
 | ||||
|   CMD_RECT,     //9
 | ||||
|   CMD_RECTFILL,   //10
 | ||||
|   CMD_CIRCLE,     //11
 | ||||
|   CMD_CIRCLEFILL,   //12
 | ||||
|   CMD_DRAWCHAR,   //13
 | ||||
|   CMD_DRAWBITMAP,   //14
 | ||||
|   CMD_GETLCDWIDTH,  //15
 | ||||
|   CMD_GETLCDHEIGHT, //16
 | ||||
|   CMD_SETCOLOR,   //17
 | ||||
|   CMD_SETDRAWMODE   //18
 | ||||
|     CMD_CLEAR,         // 0
 | ||||
|     CMD_INVERT,        // 1
 | ||||
|     CMD_CONTRAST,      // 2
 | ||||
|     CMD_DISPLAY,       // 3
 | ||||
|     CMD_SETCURSOR,     // 4
 | ||||
|     CMD_PIXEL,         // 5
 | ||||
|     CMD_LINE,          // 6
 | ||||
|     CMD_LINEH,         // 7
 | ||||
|     CMD_LINEV,         // 8
 | ||||
|     CMD_RECT,          // 9
 | ||||
|     CMD_RECTFILL,      // 10
 | ||||
|     CMD_CIRCLE,        // 11
 | ||||
|     CMD_CIRCLEFILL,    // 12
 | ||||
|     CMD_DRAWCHAR,      // 13
 | ||||
|     CMD_DRAWBITMAP,    // 14
 | ||||
|     CMD_GETLCDWIDTH,   // 15
 | ||||
|     CMD_GETLCDHEIGHT,  // 16
 | ||||
|     CMD_SETCOLOR,      // 17
 | ||||
|     CMD_SETDRAWMODE    // 18
 | ||||
| } commCommand_t; | ||||
|  | @ -16,16 +16,16 @@ | |||
| #include "qwiic.h" | ||||
| 
 | ||||
| void qwiic_init(void) { | ||||
|   #ifdef QWIIC_JOYSTIIC_ENABLE | ||||
| #ifdef QWIIC_JOYSTIIC_ENABLE | ||||
|     joystiic_init(); | ||||
|   #endif | ||||
|   #ifdef QWIIC_MICRO_OLED_ENABLE | ||||
| #endif | ||||
| #ifdef QWIIC_MICRO_OLED_ENABLE | ||||
|     micro_oled_init(); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void qwiic_task(void) { | ||||
|   #ifdef QWIIC_JOYSTIIC_ENABLE | ||||
| #ifdef QWIIC_JOYSTIIC_ENABLE | ||||
|     joystiic_task(); | ||||
|   #endif | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -18,10 +18,10 @@ | |||
| #include "i2c_master.h" | ||||
| 
 | ||||
| #ifdef QWIIC_JOYSTIIC_ENABLE | ||||
|   #include "joystiic.h" | ||||
| #    include "joystiic.h" | ||||
| #endif | ||||
| #ifdef QWIIC_MICRO_OLED_ENABLE | ||||
|   #include "micro_oled.h" | ||||
| #    include "micro_oled.h" | ||||
| #endif | ||||
| 
 | ||||
| void qwiic_init(void); | ||||
|  |  | |||
|  | @ -29,260 +29,11 @@ https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ | |||
| // Standard ASCII 5x7 font
 | ||||
| static const unsigned char font5x7[] PROGMEM = { | ||||
|     // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
 | ||||
|     5,8,0,255,12,75, | ||||
|     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, | ||||
|     0x21, 0x54, 0x54, 0x78, 0x41, | ||||
|     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, | ||||
|     0xF0, 0x29, 0x24, 0x29, 0xF0, | ||||
|     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, | ||||
|     0x32, 0x48, 0x48, 0x48, 0x32, | ||||
|     0x32, 0x4A, 0x48, 0x48, 0x30, | ||||
|     0x3A, 0x41, 0x41, 0x21, 0x7A, | ||||
|     0x3A, 0x42, 0x40, 0x20, 0x78, | ||||
|     0x00, 0x9D, 0xA0, 0xA0, 0x7D, | ||||
|     0x39, 0x44, 0x44, 0x44, 0x39, | ||||
|     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, | ||||
|     0xAA, 0x00, 0x55, 0x00, 0xAA, | ||||
|     0xAA, 0x55, 0xAA, 0x55, 0xAA, | ||||
|     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, | ||||
|     0x7C, 0x2A, 0x2A, 0x3E, 0x14, | ||||
|     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 | ||||
| }; | ||||
|     5,    8,    0,    255,  12,   75,   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, 0x21, 0x54, 0x54, 0x78, 0x41, 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, 0xF0, 0x29, 0x24, 0x29, 0xF0, 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, 0x32, 0x48, 0x48, 0x48, 0x32, 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x39, 0x44, 0x44, 0x44, 0x39, 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, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 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, 0x7C, | ||||
|     0x2A, 0x2A, 0x3E, 0x14, 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}; | ||||
|  |  | |||
|  | @ -27,101 +27,13 @@ https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ | |||
| 
 | ||||
| static const unsigned char font8x16[] PROGMEM = { | ||||
|     // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
 | ||||
|     8,16,32,96,2,56, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00, | ||||
|     0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00, | ||||
|     0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, | ||||
|     0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, | ||||
|     0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, | ||||
|     0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00, | ||||
|     0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, | ||||
|     0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, | ||||
|     0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00, | ||||
|     0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, | ||||
|     0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, | ||||
|     0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00, | ||||
|     0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00, | ||||
|     0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, | ||||
|     0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00, | ||||
|     0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, | ||||
|     0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00, | ||||
|     0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00, | ||||
|     0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00, | ||||
|     0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, | ||||
|     0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x01, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, | ||||
|     0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00, | ||||
|     0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, | ||||
|     0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, | ||||
|     0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, | ||||
|     0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, | ||||
|     0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, | ||||
|     0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, | ||||
|     0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, | ||||
|     0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00, | ||||
|     0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00, | ||||
|     0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, | ||||
|     0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00, | ||||
|     0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, | ||||
|     0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00, | ||||
|     0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, | ||||
|     0x00, 0x10, 0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00, | ||||
|     0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, | ||||
|     0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, | ||||
|     0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00, | ||||
|     0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||
| }; | ||||
|     8,    16,   32,   96,   2,    56,   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00, 0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00, 0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, 0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, | ||||
|     0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00, 0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00, | ||||
|     0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, | ||||
|     0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00, 0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, | ||||
|     0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00, 0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00, 0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00, 0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||||
|     0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, | ||||
|     0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, 0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02, | ||||
|     0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x10, | ||||
|     0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, | ||||
|     0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
|  |  | |||
|  | @ -19,54 +19,53 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #define _GDISP_LLD_BOARD_H | ||||
| 
 | ||||
| static const I2CConfig i2ccfg = { | ||||
|   400000 // clock speed (Hz); 400kHz max for IS31
 | ||||
|     400000  // clock speed (Hz); 400kHz max for IS31
 | ||||
| }; | ||||
| 
 | ||||
| static const uint8_t led_mask[] = { | ||||
| 	0xFF, 0x00, /* C1-1 -> C1-16 */ | ||||
| 	0xFF, 0x00, /* C2-1 -> C2-16 */ | ||||
| 	0xFF, 0x00, /* C3-1 -> C3-16 */ | ||||
| 	0xFF, 0x00, /* C4-1 -> C4-16 */ | ||||
| 	0x3F, 0x00, /* C5-1 -> C5-16 */ | ||||
| 	0x00, 0x00, /* C6-1 -> C6-16 */ | ||||
| 	0x00, 0x00, /* C7-1 -> C7-16 */ | ||||
| 	0x00, 0x00, /* C8-1 -> C8-16 */ | ||||
| 	0x00, 0x00, /* C9-1 -> C9-16 */ | ||||
|     0xFF, 0x00, /* C1-1 -> C1-16 */ | ||||
|     0xFF, 0x00, /* C2-1 -> C2-16 */ | ||||
|     0xFF, 0x00, /* C3-1 -> C3-16 */ | ||||
|     0xFF, 0x00, /* C4-1 -> C4-16 */ | ||||
|     0x3F, 0x00, /* C5-1 -> C5-16 */ | ||||
|     0x00, 0x00, /* C6-1 -> C6-16 */ | ||||
|     0x00, 0x00, /* C7-1 -> C7-16 */ | ||||
|     0x00, 0x00, /* C8-1 -> C8-16 */ | ||||
|     0x00, 0x00, /* C9-1 -> C9-16 */ | ||||
| }; | ||||
| 
 | ||||
| // The address of the LED
 | ||||
| #define LA(c, r) (c + r * 16 ) | ||||
| #define LA(c, r) (c + r * 16) | ||||
| // Need to be an address that is not mapped, but inside the range of the controller matrix
 | ||||
| #define NA LA(8, 8) | ||||
| 
 | ||||
| // The numbers in the comments are the led numbers DXX on the PCB
 | ||||
| // The mapping is taken from the schematic of left hand side
 | ||||
| static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = { | ||||
| //   45        44        43        42        41        40        39
 | ||||
|    { LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)}, | ||||
| //   52        51        50        49        48        47        46
 | ||||
|    { LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2) }, | ||||
| //   58        57        56        55        54        53        N/A
 | ||||
|    { LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA }, | ||||
| //   67        66        65        64        63        62        61
 | ||||
|    { LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2) }, | ||||
| //   76        75        74        73        72        60        59
 | ||||
|    { LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0) }, | ||||
| //   N/A       N/A       N/A       N/A       N/A       N/A       68
 | ||||
|    { NA,       NA,       NA,       NA,       NA,       NA,       LA(5, 4) }, | ||||
| //   N/A       N/A       N/A       N/A       71        70        69
 | ||||
|    { NA,       NA,       NA,       NA,       LA(6, 2), LA(6, 1), LA(6, 0) }, | ||||
|     //   45        44        43        42        41        40        39
 | ||||
|     {LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)}, | ||||
|     //   52        51        50        49        48        47        46
 | ||||
|     {LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2)}, | ||||
|     //   58        57        56        55        54        53        N/A
 | ||||
|     {LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA}, | ||||
|     //   67        66        65        64        63        62        61
 | ||||
|     {LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2)}, | ||||
|     //   76        75        74        73        72        60        59
 | ||||
|     {LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0)}, | ||||
|     //   N/A       N/A       N/A       N/A       N/A       N/A       68
 | ||||
|     {NA, NA, NA, NA, NA, NA, LA(5, 4)}, | ||||
|     //   N/A       N/A       N/A       N/A       71        70        69
 | ||||
|     {NA, NA, NA, NA, LA(6, 2), LA(6, 1), LA(6, 0)}, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #define IS31_ADDR_DEFAULT 0x74 // AD connected to GND
 | ||||
| #define IS31_ADDR_DEFAULT 0x74  // AD connected to GND
 | ||||
| #define IS31_TIMEOUT 5000 | ||||
| 
 | ||||
| static GFXINLINE void init_board(GDisplay *g) { | ||||
|     (void) g; | ||||
| static GFXINLINE void init_board(GDisplay* g) { | ||||
|     (void)g; | ||||
|     /* I2C pins */ | ||||
|     palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
 | ||||
|     palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA
 | ||||
|     palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2);  // PTB0/I2C0/SCL
 | ||||
|     palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2);  // PTB1/I2C0/SDA
 | ||||
|     palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); | ||||
|     palClearPad(GPIOB, 16); | ||||
|     /* start I2C */ | ||||
|  | @ -77,34 +76,30 @@ static GFXINLINE void init_board(GDisplay *g) { | |||
|     I2CD1.i2c->FLT = 4; | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void post_init_board(GDisplay *g) { | ||||
| 	(void) g; | ||||
| } | ||||
| static GFXINLINE void post_init_board(GDisplay* g) { (void)g; } | ||||
| 
 | ||||
| static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) { | ||||
|     (void) g; | ||||
|     (void)g; | ||||
|     return led_mask; | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) | ||||
| { | ||||
|     (void) g; | ||||
| static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) { | ||||
|     (void)g; | ||||
|     return led_mapping[y][x]; | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) { | ||||
|     (void) g; | ||||
|     if(!shutdown) { | ||||
|     (void)g; | ||||
|     if (!shutdown) { | ||||
|         palSetPad(GPIOB, 16); | ||||
|     } | ||||
|     else { | ||||
|     } else { | ||||
|         palClearPad(GPIOB, 16); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { | ||||
| 	(void) g; | ||||
| 	i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); | ||||
| static GFXINLINE void write_data(GDisplay* g, uint8_t* data, uint16_t length) { | ||||
|     (void)g; | ||||
|     i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); | ||||
| } | ||||
| 
 | ||||
| #endif /* _GDISP_LLD_BOARD_H */ | ||||
|  |  | |||
|  | @ -19,15 +19,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| 
 | ||||
| #if GFX_USE_GDISP | ||||
| 
 | ||||
| #define GDISP_DRIVER_VMT          GDISPVMT_IS31FL3731C_QMK | ||||
| #define GDISP_SCREEN_HEIGHT       LED_HEIGHT | ||||
| #define GDISP_SCREEN_WIDTH        LED_WIDTH | ||||
| #    define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_QMK | ||||
| #    define GDISP_SCREEN_HEIGHT LED_HEIGHT | ||||
| #    define GDISP_SCREEN_WIDTH LED_WIDTH | ||||
| 
 | ||||
| #include "gdisp_lld_config.h" | ||||
| #include "src/gdisp/gdisp_driver.h" | ||||
| 
 | ||||
| #include "board_is31fl3731c.h" | ||||
| #    include "gdisp_lld_config.h" | ||||
| #    include "src/gdisp/gdisp_driver.h" | ||||
| 
 | ||||
| #    include "board_is31fl3731c.h" | ||||
| 
 | ||||
| // Can't include led_tables from here
 | ||||
| extern const uint8_t CIE1931_CURVE[]; | ||||
|  | @ -36,96 +35,96 @@ extern const uint8_t CIE1931_CURVE[]; | |||
| /* Driver local definitions.                                                 */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| #ifndef GDISP_INITIAL_CONTRAST | ||||
|     #define GDISP_INITIAL_CONTRAST    0 | ||||
| #endif | ||||
| #ifndef GDISP_INITIAL_BACKLIGHT | ||||
|     #define GDISP_INITIAL_BACKLIGHT   0 | ||||
| #endif | ||||
| #    ifndef GDISP_INITIAL_CONTRAST | ||||
| #        define GDISP_INITIAL_CONTRAST 0 | ||||
| #    endif | ||||
| #    ifndef GDISP_INITIAL_BACKLIGHT | ||||
| #        define GDISP_INITIAL_BACKLIGHT 0 | ||||
| #    endif | ||||
| 
 | ||||
| #define GDISP_FLG_NEEDFLUSH           (GDISP_FLG_DRIVER<<0) | ||||
| #    define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) | ||||
| 
 | ||||
| #define IS31_ADDR_DEFAULT 0x74 | ||||
| #    define IS31_ADDR_DEFAULT 0x74 | ||||
| 
 | ||||
| #define IS31_REG_CONFIG   0x00 | ||||
| #    define IS31_REG_CONFIG 0x00 | ||||
| // bits in reg
 | ||||
| #define IS31_REG_CONFIG_PICTUREMODE   0x00 | ||||
| #define IS31_REG_CONFIG_AUTOPLAYMODE  0x08 | ||||
| #define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 | ||||
| #    define IS31_REG_CONFIG_PICTUREMODE 0x00 | ||||
| #    define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 | ||||
| #    define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 | ||||
| // D2:D0 bits are starting frame for autoplay mode
 | ||||
| 
 | ||||
| #define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode
 | ||||
| #    define IS31_REG_PICTDISP 0x01  // D2:D0 frame select for picture mode
 | ||||
| 
 | ||||
| #define IS31_REG_AUTOPLAYCTRL1 0x02 | ||||
| #    define IS31_REG_AUTOPLAYCTRL1 0x02 | ||||
| // D6:D4 number of loops (000=infty)
 | ||||
| // D2:D0 number of frames to be used
 | ||||
| 
 | ||||
| #define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms)
 | ||||
| #    define IS31_REG_AUTOPLAYCTRL2 0x03  // D5:D0 delay time (*11ms)
 | ||||
| 
 | ||||
| #define IS31_REG_DISPLAYOPT 0x05 | ||||
| #define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
 | ||||
| #define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 | ||||
| #    define IS31_REG_DISPLAYOPT 0x05 | ||||
| #    define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20  // same intensity for all frames
 | ||||
| #    define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 | ||||
| // D2:D0 bits blink period time (*0.27s)
 | ||||
| 
 | ||||
| #define IS31_REG_AUDIOSYNC 0x06 | ||||
| #define IS31_REG_AUDIOSYNC_ENABLE 0x1 | ||||
| #    define IS31_REG_AUDIOSYNC 0x06 | ||||
| #    define IS31_REG_AUDIOSYNC_ENABLE 0x1 | ||||
| 
 | ||||
| #define IS31_REG_FRAMESTATE 0x07 | ||||
| #    define IS31_REG_FRAMESTATE 0x07 | ||||
| 
 | ||||
| #define IS31_REG_BREATHCTRL1 0x08 | ||||
| #    define IS31_REG_BREATHCTRL1 0x08 | ||||
| // D6:D4 fade out time (26ms*2^i)
 | ||||
| // D2:D0 fade in time (26ms*2^i)
 | ||||
| 
 | ||||
| #define IS31_REG_BREATHCTRL2 0x09 | ||||
| #define IS31_REG_BREATHCTRL2_ENABLE 0x10 | ||||
| #    define IS31_REG_BREATHCTRL2 0x09 | ||||
| #    define IS31_REG_BREATHCTRL2_ENABLE 0x10 | ||||
| // D2:D0 extinguish time (3.5ms*2^i)
 | ||||
| 
 | ||||
| #define IS31_REG_SHUTDOWN 0x0A | ||||
| #define IS31_REG_SHUTDOWN_OFF 0x0 | ||||
| #define IS31_REG_SHUTDOWN_ON 0x1 | ||||
| #    define IS31_REG_SHUTDOWN 0x0A | ||||
| #    define IS31_REG_SHUTDOWN_OFF 0x0 | ||||
| #    define IS31_REG_SHUTDOWN_ON 0x1 | ||||
| 
 | ||||
| #define IS31_REG_AGCCTRL 0x0B | ||||
| #define IS31_REG_ADCRATE 0x0C | ||||
| #    define IS31_REG_AGCCTRL 0x0B | ||||
| #    define IS31_REG_ADCRATE 0x0C | ||||
| 
 | ||||
| #define IS31_COMMANDREGISTER 0xFD | ||||
| #define IS31_FUNCTIONREG 0x0B    // helpfully called 'page nine'
 | ||||
| #define IS31_FUNCTIONREG_SIZE 0xD | ||||
| #    define IS31_COMMANDREGISTER 0xFD | ||||
| #    define IS31_FUNCTIONREG 0x0B  // helpfully called 'page nine'
 | ||||
| #    define IS31_FUNCTIONREG_SIZE 0xD | ||||
| 
 | ||||
| #define IS31_FRAME_SIZE 0xB4 | ||||
| #    define IS31_FRAME_SIZE 0xB4 | ||||
| 
 | ||||
| #define IS31_PWM_REG 0x24 | ||||
| #define IS31_PWM_SIZE 0x90 | ||||
| #    define IS31_PWM_REG 0x24 | ||||
| #    define IS31_PWM_SIZE 0x90 | ||||
| 
 | ||||
| #define IS31_LED_MASK_SIZE 0x12 | ||||
| #    define IS31_LED_MASK_SIZE 0x12 | ||||
| 
 | ||||
| #define IS31 | ||||
| #    define IS31 | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver local functions.                                                   */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| typedef struct{ | ||||
| typedef struct { | ||||
|     uint8_t write_buffer_offset; | ||||
|     uint8_t write_buffer[IS31_FRAME_SIZE]; | ||||
|     uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; | ||||
|     uint8_t page; | ||||
| }__attribute__((__packed__)) PrivData; | ||||
| } __attribute__((__packed__)) PrivData; | ||||
| 
 | ||||
| // Some common routines and macros
 | ||||
| #define PRIV(g)                         ((PrivData*)g->priv) | ||||
| #    define PRIV(g) ((PrivData *)g->priv) | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver exported functions.                                                */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| static GFXINLINE void write_page(GDisplay* g, uint8_t page) { | ||||
| static GFXINLINE void write_page(GDisplay *g, uint8_t page) { | ||||
|     uint8_t tx[2] __attribute__((aligned(2))); | ||||
|     tx[0] = IS31_COMMANDREGISTER; | ||||
|     tx[1] = page; | ||||
|     write_data(g, tx, 2); | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) { | ||||
| static GFXINLINE void write_register(GDisplay *g, uint8_t page, uint8_t reg, uint8_t data) { | ||||
|     uint8_t tx[2] __attribute__((aligned(2))); | ||||
|     tx[0] = reg; | ||||
|     tx[1] = data; | ||||
|  | @ -136,7 +135,7 @@ static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uin | |||
| static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { | ||||
|     PRIV(g)->write_buffer_offset = offset; | ||||
|     write_page(g, page); | ||||
|     write_data(g, (uint8_t*)PRIV(g), length + 1); | ||||
|     write_data(g, (uint8_t *)PRIV(g), length + 1); | ||||
| } | ||||
| 
 | ||||
| LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | ||||
|  | @ -160,10 +159,9 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||
|     write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); | ||||
|     gfxSleepMilliseconds(10); | ||||
| 
 | ||||
| 
 | ||||
|     // zero all LED registers on all 8 pages, and enable the mask
 | ||||
|     __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); | ||||
|     for(uint8_t i=0; i<8; i++) { | ||||
|     for (uint8_t i = 0; i < 8; i++) { | ||||
|         write_ram(g, i, 0, IS31_FRAME_SIZE); | ||||
|         gfxSleepMilliseconds(1); | ||||
|     } | ||||
|  | @ -176,133 +174,129 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||
|     post_init_board(g); | ||||
| 
 | ||||
|     /* Initialise the GDISP structure */ | ||||
|     g->g.Width = GDISP_SCREEN_WIDTH; | ||||
|     g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|     g->g.Width       = GDISP_SCREEN_WIDTH; | ||||
|     g->g.Height      = GDISP_SCREEN_HEIGHT; | ||||
|     g->g.Orientation = GDISP_ROTATE_0; | ||||
|     g->g.Powermode = powerOff; | ||||
|     g->g.Backlight = GDISP_INITIAL_BACKLIGHT; | ||||
|     g->g.Contrast = GDISP_INITIAL_CONTRAST; | ||||
|     g->g.Powermode   = powerOff; | ||||
|     g->g.Backlight   = GDISP_INITIAL_BACKLIGHT; | ||||
|     g->g.Contrast    = GDISP_INITIAL_CONTRAST; | ||||
|     return TRUE; | ||||
| } | ||||
| 
 | ||||
| #if GDISP_HARDWARE_FLUSH | ||||
|     LLDSPEC void gdisp_lld_flush(GDisplay *g) { | ||||
|         // Don't flush if we don't need it.
 | ||||
|         if (!(g->flags & GDISP_FLG_NEEDFLUSH)) | ||||
|             return; | ||||
| #    if GDISP_HARDWARE_FLUSH | ||||
| LLDSPEC void gdisp_lld_flush(GDisplay *g) { | ||||
|     // Don't flush if we don't need it.
 | ||||
|     if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; | ||||
| 
 | ||||
|         PRIV(g)->page++; | ||||
|         PRIV(g)->page %= 2; | ||||
|         // TODO: some smarter algorithm for this
 | ||||
|         // We should run only one physical page at a time
 | ||||
|         // This way we don't need to send so much data, and
 | ||||
|         // we could use slightly less memory
 | ||||
|         uint8_t* src = PRIV(g)->frame_buffer; | ||||
|         for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { | ||||
|             for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { | ||||
|                 uint8_t val = (uint16_t)*src * g->g.Backlight / 100; | ||||
|                 PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[val]; | ||||
|                 ++src; | ||||
|             } | ||||
|     PRIV(g)->page++; | ||||
|     PRIV(g)->page %= 2; | ||||
|     // TODO: some smarter algorithm for this
 | ||||
|     // We should run only one physical page at a time
 | ||||
|     // This way we don't need to send so much data, and
 | ||||
|     // we could use slightly less memory
 | ||||
|     uint8_t *src = PRIV(g)->frame_buffer; | ||||
|     for (int y = 0; y < GDISP_SCREEN_HEIGHT; y++) { | ||||
|         for (int x = 0; x < GDISP_SCREEN_WIDTH; x++) { | ||||
|             uint8_t val                                     = (uint16_t)*src * g->g.Backlight / 100; | ||||
|             PRIV(g)->write_buffer[get_led_address(g, x, y)] = CIE1931_CURVE[val]; | ||||
|             ++src; | ||||
|         } | ||||
|         write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); | ||||
|         gfxSleepMilliseconds(1); | ||||
|         write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); | ||||
| 
 | ||||
|         g->flags &= ~GDISP_FLG_NEEDFLUSH; | ||||
|     } | ||||
| #endif | ||||
|     write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); | ||||
|     gfxSleepMilliseconds(1); | ||||
|     write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); | ||||
| 
 | ||||
| #if GDISP_HARDWARE_DRAWPIXEL | ||||
|     LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | ||||
|         coord_t        x, y; | ||||
|     g->flags &= ~GDISP_FLG_NEEDFLUSH; | ||||
| } | ||||
| #    endif | ||||
| 
 | ||||
|         switch(g->g.Orientation) { | ||||
| #    if GDISP_HARDWARE_DRAWPIXEL | ||||
| LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | ||||
|     coord_t x, y; | ||||
| 
 | ||||
|     switch (g->g.Orientation) { | ||||
|         default: | ||||
|         case GDISP_ROTATE_0: | ||||
|             x = g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_180: | ||||
|             x = GDISP_SCREEN_WIDTH-1 - g->p.x; | ||||
|             x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         } | ||||
|         PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); | ||||
|         g->flags |= GDISP_FLG_NEEDFLUSH; | ||||
|     } | ||||
| #endif | ||||
|     PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); | ||||
|     g->flags |= GDISP_FLG_NEEDFLUSH; | ||||
| } | ||||
| #    endif | ||||
| 
 | ||||
| #if GDISP_HARDWARE_PIXELREAD | ||||
|     LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | ||||
|         coord_t        x, y; | ||||
| #    if GDISP_HARDWARE_PIXELREAD | ||||
| LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | ||||
|     coord_t x, y; | ||||
| 
 | ||||
|         switch(g->g.Orientation) { | ||||
|     switch (g->g.Orientation) { | ||||
|         default: | ||||
|         case GDISP_ROTATE_0: | ||||
|             x = g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_180: | ||||
|             x = GDISP_SCREEN_WIDTH-1 - g->p.x; | ||||
|             x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         } | ||||
|         return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); | ||||
|     } | ||||
| #endif | ||||
|     return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); | ||||
| } | ||||
| #    endif | ||||
| 
 | ||||
| #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||||
|     LLDSPEC void gdisp_lld_control(GDisplay *g) { | ||||
|         switch(g->p.x) { | ||||
| #    if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||||
| LLDSPEC void gdisp_lld_control(GDisplay *g) { | ||||
|     switch (g->p.x) { | ||||
|         case GDISP_CONTROL_POWER: | ||||
|             if (g->g.Powermode == (powermode_t)g->p.ptr) | ||||
|                 return; | ||||
|             switch((powermode_t)g->p.ptr) { | ||||
|             case powerOff: | ||||
|             case powerSleep: | ||||
|             case powerDeepSleep: | ||||
|                 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); | ||||
|                 break; | ||||
|             case powerOn: | ||||
|                 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); | ||||
|                 break; | ||||
|             default: | ||||
|                 return; | ||||
|             if (g->g.Powermode == (powermode_t)g->p.ptr) return; | ||||
|             switch ((powermode_t)g->p.ptr) { | ||||
|                 case powerOff: | ||||
|                 case powerSleep: | ||||
|                 case powerDeepSleep: | ||||
|                     write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); | ||||
|                     break; | ||||
|                 case powerOn: | ||||
|                     write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); | ||||
|                     break; | ||||
|                 default: | ||||
|                     return; | ||||
|             } | ||||
|             g->g.Powermode = (powermode_t)g->p.ptr; | ||||
|             return; | ||||
| 
 | ||||
|         case GDISP_CONTROL_ORIENTATION: | ||||
|             if (g->g.Orientation == (orientation_t)g->p.ptr) | ||||
|                 return; | ||||
|             switch((orientation_t)g->p.ptr) { | ||||
|             /* Rotation is handled by the drawing routines */ | ||||
|             case GDISP_ROTATE_0: | ||||
|             case GDISP_ROTATE_180: | ||||
|                 g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|                 g->g.Width = GDISP_SCREEN_WIDTH; | ||||
|                 break; | ||||
|             case GDISP_ROTATE_90: | ||||
|             case GDISP_ROTATE_270: | ||||
|                 g->g.Height = GDISP_SCREEN_WIDTH; | ||||
|                 g->g.Width = GDISP_SCREEN_HEIGHT; | ||||
|                 break; | ||||
|             default: | ||||
|                 return; | ||||
|             if (g->g.Orientation == (orientation_t)g->p.ptr) return; | ||||
|             switch ((orientation_t)g->p.ptr) { | ||||
|                 /* Rotation is handled by the drawing routines */ | ||||
|                 case GDISP_ROTATE_0: | ||||
|                 case GDISP_ROTATE_180: | ||||
|                     g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|                     g->g.Width  = GDISP_SCREEN_WIDTH; | ||||
|                     break; | ||||
|                 case GDISP_ROTATE_90: | ||||
|                 case GDISP_ROTATE_270: | ||||
|                     g->g.Height = GDISP_SCREEN_WIDTH; | ||||
|                     g->g.Width  = GDISP_SCREEN_HEIGHT; | ||||
|                     break; | ||||
|                 default: | ||||
|                     return; | ||||
|             } | ||||
|             g->g.Orientation = (orientation_t)g->p.ptr; | ||||
|             return; | ||||
| 
 | ||||
|         case GDISP_CONTROL_BACKLIGHT: | ||||
|             if (g->g.Backlight == (unsigned)g->p.ptr) | ||||
|                 return; | ||||
|             unsigned val = (unsigned)g->p.ptr; | ||||
|             if (g->g.Backlight == (unsigned)g->p.ptr) return; | ||||
|             unsigned val   = (unsigned)g->p.ptr; | ||||
|             g->g.Backlight = val > 100 ? 100 : val; | ||||
|             g->flags |= GDISP_FLG_NEEDFLUSH; | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| #endif // GDISP_NEED_CONTROL
 | ||||
| } | ||||
| #    endif  // GDISP_NEED_CONTROL
 | ||||
| 
 | ||||
| #endif // GFX_USE_GDISP
 | ||||
| #endif  // GFX_USE_GDISP
 | ||||
|  |  | |||
|  | @ -24,13 +24,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| /* Driver hardware support.                                                  */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| #define GDISP_HARDWARE_FLUSH            TRUE        // This controller requires flushing
 | ||||
| #define GDISP_HARDWARE_DRAWPIXEL        TRUE | ||||
| #define GDISP_HARDWARE_PIXELREAD        TRUE | ||||
| #define GDISP_HARDWARE_CONTROL          TRUE | ||||
| #    define GDISP_HARDWARE_FLUSH TRUE  // This controller requires flushing
 | ||||
| #    define GDISP_HARDWARE_DRAWPIXEL TRUE | ||||
| #    define GDISP_HARDWARE_PIXELREAD TRUE | ||||
| #    define GDISP_HARDWARE_CONTROL TRUE | ||||
| 
 | ||||
| #define GDISP_LLD_PIXELFORMAT           GDISP_PIXELFORMAT_GRAY256 | ||||
| #    define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256 | ||||
| 
 | ||||
| #endif    /* GFX_USE_GDISP */ | ||||
| #endif /* GFX_USE_GDISP */ | ||||
| 
 | ||||
| #endif    /* _GDISP_LLD_CONFIG_H */ | ||||
| #endif /* _GDISP_LLD_CONFIG_H */ | ||||
|  |  | |||
|  | @ -8,10 +8,10 @@ | |||
| #ifndef _GDISP_LLD_BOARD_H | ||||
| #define _GDISP_LLD_BOARD_H | ||||
| 
 | ||||
| #define ST7565_LCD_BIAS         ST7565_LCD_BIAS_9 // actually 6
 | ||||
| #define ST7565_ADC              ST7565_ADC_NORMAL | ||||
| #define ST7565_COM_SCAN         ST7565_COM_SCAN_DEC | ||||
| #define ST7565_PAGE_ORDER       0,1,2,3 | ||||
| #define ST7565_LCD_BIAS ST7565_LCD_BIAS_9  // actually 6
 | ||||
| #define ST7565_ADC ST7565_ADC_NORMAL | ||||
| #define ST7565_COM_SCAN ST7565_COM_SCAN_DEC | ||||
| #define ST7565_PAGE_ORDER 0, 1, 2, 3 | ||||
| /*
 | ||||
|  * Custom page order for several LCD boards, e.g. HEM12864-99 | ||||
|  * #define ST7565_PAGE_ORDER       4,5,6,7,0,1,2,3 | ||||
|  | @ -25,11 +25,9 @@ | |||
| #define ST7565_SLCK_PIN 5 | ||||
| #define ST7565_SS_PIN 4 | ||||
| 
 | ||||
| #define palSetPadModeRaw(portname, bits) \ | ||||
|     ST7565_PORT->PCR[ST7565_##portname##_PIN] = bits | ||||
| #define palSetPadModeRaw(portname, bits) ST7565_PORT->PCR[ST7565_##portname##_PIN] = bits | ||||
| 
 | ||||
| #define palSetPadModeNamed(portname, portmode) \ | ||||
|     palSetPadMode(ST7565_GPIOPORT, ST7565_##portname##_PIN, portmode) | ||||
| #define palSetPadModeNamed(portname, portmode) palSetPadMode(ST7565_GPIOPORT, ST7565_##portname##_PIN, portmode) | ||||
| 
 | ||||
| #define ST7565_SPI_MODE PORTx_PCRn_DSE | PORTx_PCRn_MUX(2) | ||||
| // DSPI Clock and Transfer Attributes
 | ||||
|  | @ -37,38 +35,37 @@ | |||
| // MSB First
 | ||||
| // CLK Low by default
 | ||||
| static const SPIConfig spi1config = { | ||||
|    // Operation complete callback or @p NULL.
 | ||||
|   .end_cb = NULL, | ||||
|    //The chip select line port - when not using pcs.
 | ||||
|   .ssport = ST7565_GPIOPORT, | ||||
|    // brief The chip select line pad number - when not using pcs.
 | ||||
|   .sspad=ST7565_SS_PIN, | ||||
|    // SPI initialization data.
 | ||||
|   .tar0 = | ||||
|     SPIx_CTARn_FMSZ(7) // Frame size = 8 bytes
 | ||||
|     | SPIx_CTARn_ASC(1) // After SCK Delay Scaler (min 50 ns) = 55.56ns
 | ||||
|     | SPIx_CTARn_DT(0) // Delay After Transfer Scaler (no minimum)= 27.78ns
 | ||||
|     | SPIx_CTARn_CSSCK(0) // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns
 | ||||
|     | SPIx_CTARn_PBR(0) // Baud Rate Prescaler = 2
 | ||||
|     | SPIx_CTARn_BR(0) // Baud rate (min 50ns) = 55.56ns
 | ||||
|     // Operation complete callback or @p NULL.
 | ||||
|     .end_cb = NULL, | ||||
|     // The chip select line port - when not using pcs.
 | ||||
|     .ssport = ST7565_GPIOPORT, | ||||
|     // brief The chip select line pad number - when not using pcs.
 | ||||
|     .sspad = ST7565_SS_PIN, | ||||
|     // SPI initialization data.
 | ||||
|     .tar0 = SPIx_CTARn_FMSZ(7)     // Frame size = 8 bytes
 | ||||
|             | SPIx_CTARn_ASC(1)    // After SCK Delay Scaler (min 50 ns) = 55.56ns
 | ||||
|             | SPIx_CTARn_DT(0)     // Delay After Transfer Scaler (no minimum)= 27.78ns
 | ||||
|             | SPIx_CTARn_CSSCK(0)  // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns
 | ||||
|             | SPIx_CTARn_PBR(0)    // Baud Rate Prescaler = 2
 | ||||
|             | SPIx_CTARn_BR(0)     // Baud rate (min 50ns) = 55.56ns
 | ||||
| }; | ||||
| 
 | ||||
| static GFXINLINE void acquire_bus(GDisplay *g) { | ||||
|     (void) g; | ||||
|     (void)g; | ||||
|     // Only the LCD is using the SPI bus, so no need to acquire
 | ||||
|     // spiAcquireBus(&SPID1);
 | ||||
|     spiSelect(&SPID1); | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void release_bus(GDisplay *g) { | ||||
|     (void) g; | ||||
|     (void)g; | ||||
|     // Only the LCD is using the SPI bus, so no need to release
 | ||||
|     //spiReleaseBus(&SPID1);
 | ||||
|     // spiReleaseBus(&SPID1);
 | ||||
|     spiUnselect(&SPID1); | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void init_board(GDisplay *g) { | ||||
|     (void) g; | ||||
|     (void)g; | ||||
|     palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); | ||||
|     palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||
|     palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); | ||||
|  | @ -82,31 +79,23 @@ static GFXINLINE void init_board(GDisplay *g) { | |||
|     release_bus(g); | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void post_init_board(GDisplay *g) { | ||||
|     (void) g; | ||||
| } | ||||
| static GFXINLINE void post_init_board(GDisplay *g) { (void)g; } | ||||
| 
 | ||||
| static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { | ||||
|     (void) g; | ||||
|     (void)g; | ||||
|     if (state) { | ||||
|         palClearPad(ST7565_GPIOPORT, ST7565_RST_PIN); | ||||
|     } | ||||
|     else { | ||||
|     } else { | ||||
|         palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static GFXINLINE void enter_data_mode(GDisplay *g) { | ||||
|     palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||
| } | ||||
| static GFXINLINE void enter_data_mode(GDisplay *g) { palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); } | ||||
| 
 | ||||
| static GFXINLINE void enter_cmd_mode(GDisplay *g) { | ||||
|     palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||
| } | ||||
| static GFXINLINE void enter_cmd_mode(GDisplay *g) { palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); } | ||||
| 
 | ||||
| 
 | ||||
| static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { | ||||
|     (void) g; | ||||
| static GFXINLINE void write_data(GDisplay *g, uint8_t *data, uint16_t length) { | ||||
|     (void)g; | ||||
|     spiSend(&SPID1, length, data); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,82 +9,89 @@ | |||
| 
 | ||||
| #if GFX_USE_GDISP | ||||
| 
 | ||||
| #define GDISP_DRIVER_VMT            GDISPVMT_ST7565_QMK | ||||
| #include "gdisp_lld_config.h" | ||||
| #include "src/gdisp/gdisp_driver.h" | ||||
| #    define GDISP_DRIVER_VMT GDISPVMT_ST7565_QMK | ||||
| #    include "gdisp_lld_config.h" | ||||
| #    include "src/gdisp/gdisp_driver.h" | ||||
| 
 | ||||
| #include "board_st7565.h" | ||||
| #    include "board_st7565.h" | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver local definitions.                                                 */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| #ifndef GDISP_SCREEN_HEIGHT | ||||
| #define GDISP_SCREEN_HEIGHT         LCD_HEIGHT | ||||
| #endif | ||||
| #ifndef GDISP_SCREEN_WIDTH | ||||
| #define GDISP_SCREEN_WIDTH          LCD_WIDTH | ||||
| #endif | ||||
| #ifndef GDISP_INITIAL_CONTRAST | ||||
| #define GDISP_INITIAL_CONTRAST      35 | ||||
| #endif | ||||
| #ifndef GDISP_INITIAL_BACKLIGHT | ||||
| #define GDISP_INITIAL_BACKLIGHT     100 | ||||
| #endif | ||||
| #    ifndef GDISP_SCREEN_HEIGHT | ||||
| #        define GDISP_SCREEN_HEIGHT LCD_HEIGHT | ||||
| #    endif | ||||
| #    ifndef GDISP_SCREEN_WIDTH | ||||
| #        define GDISP_SCREEN_WIDTH LCD_WIDTH | ||||
| #    endif | ||||
| #    ifndef GDISP_INITIAL_CONTRAST | ||||
| #        define GDISP_INITIAL_CONTRAST 35 | ||||
| #    endif | ||||
| #    ifndef GDISP_INITIAL_BACKLIGHT | ||||
| #        define GDISP_INITIAL_BACKLIGHT 100 | ||||
| #    endif | ||||
| 
 | ||||
| #define GDISP_FLG_NEEDFLUSH         (GDISP_FLG_DRIVER<<0) | ||||
| #    define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) | ||||
| 
 | ||||
| #include "st7565.h" | ||||
| #    include "st7565.h" | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver config defaults for backward compatibility.                        */ | ||||
| /*===========================================================================*/ | ||||
| #ifndef ST7565_LCD_BIAS | ||||
| #define ST7565_LCD_BIAS         ST7565_LCD_BIAS_7 | ||||
| #endif | ||||
| #ifndef ST7565_ADC | ||||
| #define ST7565_ADC              ST7565_ADC_NORMAL | ||||
| #endif | ||||
| #ifndef ST7565_COM_SCAN | ||||
| #define ST7565_COM_SCAN         ST7565_COM_SCAN_INC | ||||
| #endif | ||||
| #ifndef ST7565_PAGE_ORDER | ||||
| #define ST7565_PAGE_ORDER       0,1,2,3 | ||||
| #endif | ||||
| #    ifndef ST7565_LCD_BIAS | ||||
| #        define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 | ||||
| #    endif | ||||
| #    ifndef ST7565_ADC | ||||
| #        define ST7565_ADC ST7565_ADC_NORMAL | ||||
| #    endif | ||||
| #    ifndef ST7565_COM_SCAN | ||||
| #        define ST7565_COM_SCAN ST7565_COM_SCAN_INC | ||||
| #    endif | ||||
| #    ifndef ST7565_PAGE_ORDER | ||||
| #        define ST7565_PAGE_ORDER 0, 1, 2, 3 | ||||
| #    endif | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver local functions.                                                   */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| typedef struct{ | ||||
|     bool_t buffer2; | ||||
| typedef struct { | ||||
|     bool_t  buffer2; | ||||
|     uint8_t data_pos; | ||||
|     uint8_t data[16]; | ||||
|     uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; | ||||
| }PrivData; | ||||
| } PrivData; | ||||
| 
 | ||||
| // Some common routines and macros
 | ||||
| #define PRIV(g)                         ((PrivData*)g->priv) | ||||
| #define RAM(g)                          (PRIV(g)->ram) | ||||
| #    define PRIV(g) ((PrivData *)g->priv) | ||||
| #    define RAM(g) (PRIV(g)->ram) | ||||
| 
 | ||||
| static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) { | ||||
|     PRIV(g)->data[PRIV(g)->data_pos++] = cmd; | ||||
| } | ||||
| static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { PRIV(g)->data[PRIV(g)->data_pos++] = cmd; } | ||||
| 
 | ||||
| static GFXINLINE void flush_cmd(GDisplay* g) { | ||||
| static GFXINLINE void flush_cmd(GDisplay *g) { | ||||
|     write_data(g, PRIV(g)->data, PRIV(g)->data_pos); | ||||
|     PRIV(g)->data_pos = 0; | ||||
| } | ||||
| 
 | ||||
| #define write_cmd2(g, cmd1, cmd2)        { write_cmd(g, cmd1); write_cmd(g, cmd2); } | ||||
| #define write_cmd3(g, cmd1, cmd2, cmd3)  { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } | ||||
| #    define write_cmd2(g, cmd1, cmd2) \ | ||||
|         {                             \ | ||||
|             write_cmd(g, cmd1);       \ | ||||
|             write_cmd(g, cmd2);       \ | ||||
|         } | ||||
| #    define write_cmd3(g, cmd1, cmd2, cmd3) \ | ||||
|         {                                   \ | ||||
|             write_cmd(g, cmd1);             \ | ||||
|             write_cmd(g, cmd2);             \ | ||||
|             write_cmd(g, cmd3);             \ | ||||
|         } | ||||
| 
 | ||||
| // Some common routines and macros
 | ||||
| #define delay(us)           gfxSleepMicroseconds(us) | ||||
| #define delay_ms(ms)        gfxSleepMilliseconds(ms) | ||||
| #    define delay(us) gfxSleepMicroseconds(us) | ||||
| #    define delay_ms(ms) gfxSleepMilliseconds(ms) | ||||
| 
 | ||||
| #define xyaddr(x, y)        ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH) | ||||
| #define xybit(y)            (1<<((y)&7)) | ||||
| #    define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_SCREEN_WIDTH) | ||||
| #    define xybit(y) (1 << ((y)&7)) | ||||
| 
 | ||||
| /*===========================================================================*/ | ||||
| /* Driver exported functions.                                                */ | ||||
|  | @ -99,8 +106,8 @@ static GFXINLINE void flush_cmd(GDisplay* g) { | |||
| 
 | ||||
| LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | ||||
|     // The private area is the display surface.
 | ||||
|     g->priv = gfxAlloc(sizeof(PrivData)); | ||||
|     PRIV(g)->buffer2 = false; | ||||
|     g->priv           = gfxAlloc(sizeof(PrivData)); | ||||
|     PRIV(g)->buffer2  = false; | ||||
|     PRIV(g)->data_pos = 0; | ||||
| 
 | ||||
|     // Initialise the board interface
 | ||||
|  | @ -139,22 +146,21 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||
|     release_bus(g); | ||||
| 
 | ||||
|     /* Initialise the GDISP structure */ | ||||
|     g->g.Width = GDISP_SCREEN_WIDTH; | ||||
|     g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|     g->g.Width       = GDISP_SCREEN_WIDTH; | ||||
|     g->g.Height      = GDISP_SCREEN_HEIGHT; | ||||
|     g->g.Orientation = GDISP_ROTATE_0; | ||||
|     g->g.Powermode = powerOff; | ||||
|     g->g.Backlight = GDISP_INITIAL_BACKLIGHT; | ||||
|     g->g.Contrast = GDISP_INITIAL_CONTRAST; | ||||
|     g->g.Powermode   = powerOff; | ||||
|     g->g.Backlight   = GDISP_INITIAL_BACKLIGHT; | ||||
|     g->g.Contrast    = GDISP_INITIAL_CONTRAST; | ||||
|     return TRUE; | ||||
| } | ||||
| 
 | ||||
| #if GDISP_HARDWARE_FLUSH | ||||
| #    if GDISP_HARDWARE_FLUSH | ||||
| LLDSPEC void gdisp_lld_flush(GDisplay *g) { | ||||
|     unsigned    p; | ||||
|     unsigned p; | ||||
| 
 | ||||
|     // Don't flush if we don't need it.
 | ||||
|     if (!(g->flags & GDISP_FLG_NEEDFLUSH)) | ||||
|         return; | ||||
|     if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; | ||||
| 
 | ||||
|     acquire_bus(g); | ||||
|     enter_cmd_mode(g); | ||||
|  | @ -166,7 +172,7 @@ LLDSPEC void gdisp_lld_flush(GDisplay *g) { | |||
|         write_cmd(g, ST7565_RMW); | ||||
|         flush_cmd(g); | ||||
|         enter_data_mode(g); | ||||
|         write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | ||||
|         write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | ||||
|         enter_cmd_mode(g); | ||||
|     } | ||||
|     unsigned line = (PRIV(g)->buffer2 ? 32 : 0); | ||||
|  | @ -177,30 +183,30 @@ LLDSPEC void gdisp_lld_flush(GDisplay *g) { | |||
| 
 | ||||
|     g->flags &= ~GDISP_FLG_NEEDFLUSH; | ||||
| } | ||||
| #endif | ||||
| #    endif | ||||
| 
 | ||||
| #if GDISP_HARDWARE_DRAWPIXEL | ||||
| #    if GDISP_HARDWARE_DRAWPIXEL | ||||
| LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | ||||
|     coord_t        x, y; | ||||
|     coord_t x, y; | ||||
| 
 | ||||
|     switch(g->g.Orientation) { | ||||
|     default: | ||||
|     case GDISP_ROTATE_0: | ||||
|         x = g->p.x; | ||||
|         y = g->p.y; | ||||
|         break; | ||||
|     case GDISP_ROTATE_90: | ||||
|         x = g->p.y; | ||||
|         y = GDISP_SCREEN_HEIGHT-1 - g->p.x; | ||||
|         break; | ||||
|     case GDISP_ROTATE_180: | ||||
|         x = GDISP_SCREEN_WIDTH-1 - g->p.x; | ||||
|         y = GDISP_SCREEN_HEIGHT-1 - g->p.y; | ||||
|         break; | ||||
|     case GDISP_ROTATE_270: | ||||
|         x = GDISP_SCREEN_HEIGHT-1 - g->p.y; | ||||
|         y = g->p.x; | ||||
|         break; | ||||
|     switch (g->g.Orientation) { | ||||
|         default: | ||||
|         case GDISP_ROTATE_0: | ||||
|             x = g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_90: | ||||
|             x = g->p.y; | ||||
|             y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; | ||||
|             break; | ||||
|         case GDISP_ROTATE_180: | ||||
|             x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||||
|             y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_270: | ||||
|             x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||||
|             y = g->p.x; | ||||
|             break; | ||||
|     } | ||||
|     if (gdispColor2Native(g->p.color) != Black) | ||||
|         RAM(g)[xyaddr(x, y)] |= xybit(y); | ||||
|  | @ -208,53 +214,52 @@ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { | |||
|         RAM(g)[xyaddr(x, y)] &= ~xybit(y); | ||||
|     g->flags |= GDISP_FLG_NEEDFLUSH; | ||||
| } | ||||
| #endif | ||||
| #    endif | ||||
| 
 | ||||
| #if GDISP_HARDWARE_PIXELREAD | ||||
| #    if GDISP_HARDWARE_PIXELREAD | ||||
| LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { | ||||
|     coord_t        x, y; | ||||
|     coord_t x, y; | ||||
| 
 | ||||
|     switch(g->g.Orientation) { | ||||
|     default: | ||||
|     case GDISP_ROTATE_0: | ||||
|         x = g->p.x; | ||||
|         y = g->p.y; | ||||
|         break; | ||||
|     case GDISP_ROTATE_90: | ||||
|         x = g->p.y; | ||||
|         y = GDISP_SCREEN_HEIGHT-1 - g->p.x; | ||||
|         break; | ||||
|     case GDISP_ROTATE_180: | ||||
|         x = GDISP_SCREEN_WIDTH-1 - g->p.x; | ||||
|         y = GDISP_SCREEN_HEIGHT-1 - g->p.y; | ||||
|         break; | ||||
|     case GDISP_ROTATE_270: | ||||
|         x = GDISP_SCREEN_HEIGHT-1 - g->p.y; | ||||
|         y = g->p.x; | ||||
|         break; | ||||
|     switch (g->g.Orientation) { | ||||
|         default: | ||||
|         case GDISP_ROTATE_0: | ||||
|             x = g->p.x; | ||||
|             y = g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_90: | ||||
|             x = g->p.y; | ||||
|             y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; | ||||
|             break; | ||||
|         case GDISP_ROTATE_180: | ||||
|             x = GDISP_SCREEN_WIDTH - 1 - g->p.x; | ||||
|             y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||||
|             break; | ||||
|         case GDISP_ROTATE_270: | ||||
|             x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; | ||||
|             y = g->p.x; | ||||
|             break; | ||||
|     } | ||||
|     return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; | ||||
| } | ||||
| #endif | ||||
| #    endif | ||||
| 
 | ||||
| LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { | ||||
|     uint8_t* buffer = (uint8_t*)g->p.ptr; | ||||
|     int linelength = g->p.cx; | ||||
|     uint8_t *buffer     = (uint8_t *)g->p.ptr; | ||||
|     int      linelength = g->p.cx; | ||||
|     for (int i = 0; i < g->p.cy; i++) { | ||||
|         unsigned dstx = g->p.x; | ||||
|         unsigned dsty = g->p.y + i; | ||||
|         unsigned srcx = g->p.x1; | ||||
|         unsigned srcy = g->p.y1 + i; | ||||
|         unsigned dstx   = g->p.x; | ||||
|         unsigned dsty   = g->p.y + i; | ||||
|         unsigned srcx   = g->p.x1; | ||||
|         unsigned srcy   = g->p.y1 + i; | ||||
|         unsigned srcbit = srcy * g->p.x2 + srcx; | ||||
|         for(int j=0; j < linelength; j++) { | ||||
|             uint8_t src = buffer[srcbit / 8]; | ||||
|             uint8_t bit = 7-(srcbit % 8); | ||||
|             uint8_t bitset = (src >> bit) & 1; | ||||
|             uint8_t* dst = &(RAM(g)[xyaddr(dstx, dsty)]); | ||||
|         for (int j = 0; j < linelength; j++) { | ||||
|             uint8_t  src    = buffer[srcbit / 8]; | ||||
|             uint8_t  bit    = 7 - (srcbit % 8); | ||||
|             uint8_t  bitset = (src >> bit) & 1; | ||||
|             uint8_t *dst    = &(RAM(g)[xyaddr(dstx, dsty)]); | ||||
|             if (bitset) { | ||||
|                 *dst |= xybit(dsty); | ||||
|             } | ||||
|             else { | ||||
|             } else { | ||||
|                 *dst &= ~xybit(dsty); | ||||
|             } | ||||
|             dstx++; | ||||
|  | @ -264,66 +269,64 @@ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { | |||
|     g->flags |= GDISP_FLG_NEEDFLUSH; | ||||
| } | ||||
| 
 | ||||
| #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||||
| #    if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||||
| LLDSPEC void gdisp_lld_control(GDisplay *g) { | ||||
|     switch(g->p.x) { | ||||
|     case GDISP_CONTROL_POWER: | ||||
|         if (g->g.Powermode == (powermode_t)g->p.ptr) | ||||
|     switch (g->p.x) { | ||||
|         case GDISP_CONTROL_POWER: | ||||
|             if (g->g.Powermode == (powermode_t)g->p.ptr) return; | ||||
|             switch ((powermode_t)g->p.ptr) { | ||||
|                 case powerOff: | ||||
|                 case powerSleep: | ||||
|                 case powerDeepSleep: | ||||
|                     acquire_bus(g); | ||||
|                     enter_cmd_mode(g); | ||||
|                     write_cmd(g, ST7565_DISPLAY_OFF); | ||||
|                     flush_cmd(g); | ||||
|                     release_bus(g); | ||||
|                     break; | ||||
|                 case powerOn: | ||||
|                     acquire_bus(g); | ||||
|                     enter_cmd_mode(g); | ||||
|                     write_cmd(g, ST7565_DISPLAY_ON); | ||||
|                     flush_cmd(g); | ||||
|                     release_bus(g); | ||||
|                     break; | ||||
|                 default: | ||||
|                     return; | ||||
|             } | ||||
|             g->g.Powermode = (powermode_t)g->p.ptr; | ||||
|             return; | ||||
|         switch((powermode_t)g->p.ptr) { | ||||
|         case powerOff: | ||||
|         case powerSleep: | ||||
|         case powerDeepSleep: | ||||
|             acquire_bus(g); | ||||
|             enter_cmd_mode(g); | ||||
|             write_cmd(g, ST7565_DISPLAY_OFF); | ||||
|             flush_cmd(g); | ||||
|             release_bus(g); | ||||
|             break; | ||||
|         case powerOn: | ||||
|             acquire_bus(g); | ||||
|             enter_cmd_mode(g); | ||||
|             write_cmd(g, ST7565_DISPLAY_ON); | ||||
|             flush_cmd(g); | ||||
|             release_bus(g); | ||||
|             break; | ||||
|         default: | ||||
|             return; | ||||
|         } | ||||
|         g->g.Powermode = (powermode_t)g->p.ptr; | ||||
|         return; | ||||
| 
 | ||||
|         case GDISP_CONTROL_ORIENTATION: | ||||
|             if (g->g.Orientation == (orientation_t)g->p.ptr) | ||||
|                 return; | ||||
|             switch((orientation_t)g->p.ptr) { | ||||
|             /* Rotation is handled by the drawing routines */ | ||||
|             case GDISP_ROTATE_0: | ||||
|             case GDISP_ROTATE_180: | ||||
|                 g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|                 g->g.Width = GDISP_SCREEN_WIDTH; | ||||
|                 break; | ||||
|             case GDISP_ROTATE_90: | ||||
|             case GDISP_ROTATE_270: | ||||
|                 g->g.Height = GDISP_SCREEN_WIDTH; | ||||
|                 g->g.Width = GDISP_SCREEN_HEIGHT; | ||||
|                 break; | ||||
|             default: | ||||
|                 return; | ||||
|             if (g->g.Orientation == (orientation_t)g->p.ptr) return; | ||||
|             switch ((orientation_t)g->p.ptr) { | ||||
|                 /* Rotation is handled by the drawing routines */ | ||||
|                 case GDISP_ROTATE_0: | ||||
|                 case GDISP_ROTATE_180: | ||||
|                     g->g.Height = GDISP_SCREEN_HEIGHT; | ||||
|                     g->g.Width  = GDISP_SCREEN_WIDTH; | ||||
|                     break; | ||||
|                 case GDISP_ROTATE_90: | ||||
|                 case GDISP_ROTATE_270: | ||||
|                     g->g.Height = GDISP_SCREEN_WIDTH; | ||||
|                     g->g.Width  = GDISP_SCREEN_HEIGHT; | ||||
|                     break; | ||||
|                 default: | ||||
|                     return; | ||||
|             } | ||||
|             g->g.Orientation = (orientation_t)g->p.ptr; | ||||
|             return; | ||||
| 
 | ||||
|             case GDISP_CONTROL_CONTRAST: | ||||
|                 g->g.Contrast = (unsigned)g->p.ptr & 63; | ||||
|                 acquire_bus(g); | ||||
|                 enter_cmd_mode(g); | ||||
|                 write_cmd2(g, ST7565_CONTRAST, g->g.Contrast); | ||||
|                 flush_cmd(g); | ||||
|                 release_bus(g); | ||||
|                 return; | ||||
|         case GDISP_CONTROL_CONTRAST: | ||||
|             g->g.Contrast = (unsigned)g->p.ptr & 63; | ||||
|             acquire_bus(g); | ||||
|             enter_cmd_mode(g); | ||||
|             write_cmd2(g, ST7565_CONTRAST, g->g.Contrast); | ||||
|             flush_cmd(g); | ||||
|             release_bus(g); | ||||
|             return; | ||||
|     } | ||||
| } | ||||
| #endif // GDISP_NEED_CONTROL
 | ||||
| #    endif  // GDISP_NEED_CONTROL
 | ||||
| 
 | ||||
| #endif // GFX_USE_GDISP
 | ||||
| #endif  // GFX_USE_GDISP
 | ||||
|  |  | |||
|  | @ -14,14 +14,14 @@ | |||
| /* Driver hardware support.                                                  */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| #define GDISP_HARDWARE_FLUSH            TRUE        // This controller requires flushing
 | ||||
| #define GDISP_HARDWARE_DRAWPIXEL        TRUE | ||||
| #define GDISP_HARDWARE_PIXELREAD        TRUE | ||||
| #define GDISP_HARDWARE_CONTROL          TRUE | ||||
| #define GDISP_HARDWARE_BITFILLS         TRUE | ||||
| #    define GDISP_HARDWARE_FLUSH TRUE  // This controller requires flushing
 | ||||
| #    define GDISP_HARDWARE_DRAWPIXEL TRUE | ||||
| #    define GDISP_HARDWARE_PIXELREAD TRUE | ||||
| #    define GDISP_HARDWARE_CONTROL TRUE | ||||
| #    define GDISP_HARDWARE_BITFILLS TRUE | ||||
| 
 | ||||
| #define GDISP_LLD_PIXELFORMAT           GDISP_PIXELFORMAT_MONO | ||||
| #    define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO | ||||
| 
 | ||||
| #endif    /* GFX_USE_GDISP */ | ||||
| #endif /* GFX_USE_GDISP */ | ||||
| 
 | ||||
| #endif    /* _GDISP_LLD_CONFIG_H */ | ||||
| #endif /* _GDISP_LLD_CONFIG_H */ | ||||
|  |  | |||
|  | @ -8,32 +8,32 @@ | |||
| #ifndef _ST7565_H | ||||
| #define _ST7565_H | ||||
| 
 | ||||
| #define ST7565_CONTRAST             0x81 | ||||
| #define ST7565_ALLON_NORMAL         0xA4 | ||||
| #define ST7565_ALLON                0xA5 | ||||
| #define ST7565_POSITIVE_DISPLAY     0xA6 | ||||
| #define ST7565_INVERT_DISPLAY       0xA7 | ||||
| #define ST7565_DISPLAY_OFF          0xAE | ||||
| #define ST7565_DISPLAY_ON           0xAF | ||||
| #define ST7565_CONTRAST 0x81 | ||||
| #define ST7565_ALLON_NORMAL 0xA4 | ||||
| #define ST7565_ALLON 0xA5 | ||||
| #define ST7565_POSITIVE_DISPLAY 0xA6 | ||||
| #define ST7565_INVERT_DISPLAY 0xA7 | ||||
| #define ST7565_DISPLAY_OFF 0xAE | ||||
| #define ST7565_DISPLAY_ON 0xAF | ||||
| 
 | ||||
| #define ST7565_LCD_BIAS_7           0xA3 | ||||
| #define ST7565_LCD_BIAS_9           0xA2 | ||||
| #define ST7565_LCD_BIAS_7 0xA3 | ||||
| #define ST7565_LCD_BIAS_9 0xA2 | ||||
| 
 | ||||
| #define ST7565_ADC_NORMAL           0xA0 | ||||
| #define ST7565_ADC_REVERSE          0xA1 | ||||
| #define ST7565_ADC_NORMAL 0xA0 | ||||
| #define ST7565_ADC_REVERSE 0xA1 | ||||
| 
 | ||||
| #define ST7565_COM_SCAN_INC         0xC0 | ||||
| #define ST7565_COM_SCAN_DEC         0xC8 | ||||
| #define ST7565_COM_SCAN_INC 0xC0 | ||||
| #define ST7565_COM_SCAN_DEC 0xC8 | ||||
| 
 | ||||
| #define ST7565_START_LINE           0x40 | ||||
| #define ST7565_PAGE                 0xB0 | ||||
| #define ST7565_COLUMN_MSB           0x10 | ||||
| #define ST7565_COLUMN_LSB           0x00 | ||||
| #define ST7565_RMW                  0xE0 | ||||
| #define ST7565_START_LINE 0x40 | ||||
| #define ST7565_PAGE 0xB0 | ||||
| #define ST7565_COLUMN_MSB 0x10 | ||||
| #define ST7565_COLUMN_LSB 0x00 | ||||
| #define ST7565_RMW 0xE0 | ||||
| 
 | ||||
| #define ST7565_RESISTOR_RATIO       0x20 | ||||
| #define ST7565_POWER_CONTROL        0x28 | ||||
| #define ST7565_RESISTOR_RATIO 0x20 | ||||
| #define ST7565_POWER_CONTROL 0x28 | ||||
| 
 | ||||
| #define ST7565_RESET                0xE2 | ||||
| #define ST7565_RESET 0xE2 | ||||
| 
 | ||||
| #endif /* _ST7565_H */ | ||||
|  |  | |||
							
								
								
									
										115
									
								
								quantum/api.c
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								quantum/api.c
									
										
									
									
									
								
							|  | @ -17,40 +17,28 @@ | |||
| #include "api.h" | ||||
| #include "quantum.h" | ||||
| 
 | ||||
| void dword_to_bytes(uint32_t dword, uint8_t * bytes) { | ||||
| void dword_to_bytes(uint32_t dword, uint8_t* bytes) { | ||||
|     bytes[0] = (dword >> 24) & 0xFF; | ||||
|     bytes[1] = (dword >> 16) & 0xFF;  | ||||
|     bytes[2] = (dword >> 8) & 0xFF;  | ||||
|     bytes[3] = (dword >> 0) & 0xFF;  | ||||
|     bytes[1] = (dword >> 16) & 0xFF; | ||||
|     bytes[2] = (dword >> 8) & 0xFF; | ||||
|     bytes[3] = (dword >> 0) & 0xFF; | ||||
| } | ||||
| 
 | ||||
| uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) { | ||||
|     return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; | ||||
| } | ||||
| uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index) { return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; } | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_quantum(uint8_t length, uint8_t * data) { | ||||
|     return process_api_keyboard(length, data); | ||||
| } | ||||
| __attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data) { return process_api_keyboard(length, data); } | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_keyboard(uint8_t length, uint8_t * data) { | ||||
|     return process_api_user(length, data); | ||||
| } | ||||
| __attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data) { return process_api_user(length, data); } | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_user(uint8_t length, uint8_t * data) { | ||||
|     return true; | ||||
| } | ||||
| __attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data) { return true; } | ||||
| 
 | ||||
| void process_api(uint16_t length, uint8_t * data) { | ||||
| void process_api(uint16_t length, uint8_t* data) { | ||||
|     // SEND_STRING("\nRX: ");
 | ||||
|     // for (uint8_t i = 0; i < length; i++) {
 | ||||
|     //     send_byte(data[i]);
 | ||||
|     //     SEND_STRING(" ");
 | ||||
|     // }
 | ||||
|     if (!process_api_quantum(length, data)) | ||||
|         return; | ||||
|     if (!process_api_quantum(length, data)) return; | ||||
| 
 | ||||
|     switch (data[0]) { | ||||
|         case MT_SET_DATA: | ||||
|  | @ -65,10 +53,10 @@ void process_api(uint16_t length, uint8_t * data) { | |||
|                     break; | ||||
|                 } | ||||
|                 case DT_RGBLIGHT: { | ||||
|                     #ifdef RGBLIGHT_ENABLE | ||||
|                         uint32_t rgblight = bytes_to_dword(data, 2); | ||||
|                         eeconfig_update_rgblight(rgblight); | ||||
|                     #endif | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|                     uint32_t rgblight = bytes_to_dword(data, 2); | ||||
|                     eeconfig_update_rgblight(rgblight); | ||||
| #endif | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | @ -79,12 +67,12 @@ void process_api(uint16_t length, uint8_t * data) { | |||
|                     break; | ||||
|                 } | ||||
|                 case DT_DEBUG: { | ||||
|                     uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) }; | ||||
|                     uint8_t debug_bytes[1] = {eeprom_read_byte(EECONFIG_DEBUG)}; | ||||
|                     MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); | ||||
|                     break; | ||||
|                 } | ||||
|                 case DT_DEFAULT_LAYER: { | ||||
|                     uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) }; | ||||
|                     uint8_t default_bytes[1] = {eeprom_read_byte(EECONFIG_DEFAULT_LAYER)}; | ||||
|                     MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); | ||||
|                     break; | ||||
|                 } | ||||
|  | @ -95,35 +83,35 @@ void process_api(uint16_t length, uint8_t * data) { | |||
|                     break; | ||||
|                 } | ||||
|                 case DT_AUDIO: { | ||||
|                     #ifdef AUDIO_ENABLE | ||||
|                         uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) }; | ||||
|                         MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); | ||||
|                     #else | ||||
|                         MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); | ||||
|                     #endif | ||||
| #ifdef AUDIO_ENABLE | ||||
|                     uint8_t audio_bytes[1] = {eeprom_read_byte(EECONFIG_AUDIO)}; | ||||
|                     MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); | ||||
| #else | ||||
|                     MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); | ||||
| #endif | ||||
|                     break; | ||||
|                 } | ||||
|                 case DT_BACKLIGHT: { | ||||
|                     #ifdef BACKLIGHT_ENABLE | ||||
|                         uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) }; | ||||
|                         MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); | ||||
|                     #else | ||||
|                         MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); | ||||
|                     #endif | ||||
| #ifdef BACKLIGHT_ENABLE | ||||
|                     uint8_t backlight_bytes[1] = {eeprom_read_byte(EECONFIG_BACKLIGHT)}; | ||||
|                     MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); | ||||
| #else | ||||
|                     MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); | ||||
| #endif | ||||
|                     break; | ||||
|                 } | ||||
|                 case DT_RGBLIGHT: { | ||||
|                     #ifdef RGBLIGHT_ENABLE | ||||
|                         uint8_t rgblight_bytes[4]; | ||||
|                         dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); | ||||
|                         MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); | ||||
|                     #else | ||||
|                         MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); | ||||
|                     #endif | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|                     uint8_t rgblight_bytes[4]; | ||||
|                     dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); | ||||
|                     MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); | ||||
| #else | ||||
|                     MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); | ||||
| #endif | ||||
|                     break; | ||||
|                 } | ||||
|                 case DT_KEYMAP_OPTIONS: { | ||||
|                     uint8_t keymap_bytes[1] = { eeconfig_read_keymap() }; | ||||
|                     uint8_t keymap_bytes[1] = {eeconfig_read_keymap()}; | ||||
|                     MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); | ||||
|                     break; | ||||
|                 } | ||||
|  | @ -172,24 +160,23 @@ void process_api(uint16_t length, uint8_t * data) { | |||
|             break; | ||||
|         case MT_TYPE_ERROR: | ||||
|             break; | ||||
|         default: ; // command not recognised
 | ||||
|         default:;  // command not recognised
 | ||||
|             SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length); | ||||
|             break; | ||||
| 
 | ||||
|         // #ifdef RGBLIGHT_ENABLE
 | ||||
|         // case 0x27: ; // RGB LED functions
 | ||||
|         //     switch (*data++) {
 | ||||
|         //         case 0x00: ; // Update HSV
 | ||||
|         //             rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]);
 | ||||
|         //             break;
 | ||||
|         //         case 0x01: ; // Update RGB
 | ||||
|         //             break;
 | ||||
|         //         case 0x02: ; // Update mode
 | ||||
|         //             rgblight_mode(data[0]);
 | ||||
|         //             break;
 | ||||
|         //     }
 | ||||
|         //     break;
 | ||||
|         // #endif
 | ||||
|             // #ifdef RGBLIGHT_ENABLE
 | ||||
|             // case 0x27: ; // RGB LED functions
 | ||||
|             //     switch (*data++) {
 | ||||
|             //         case 0x00: ; // Update HSV
 | ||||
|             //             rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]);
 | ||||
|             //             break;
 | ||||
|             //         case 0x01: ; // Update RGB
 | ||||
|             //             break;
 | ||||
|             //         case 0x02: ; // Update mode
 | ||||
|             //             rgblight_mode(data[0]);
 | ||||
|             //             break;
 | ||||
|             //     }
 | ||||
|             //     break;
 | ||||
|             // #endif
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -18,41 +18,25 @@ | |||
| #define _API_H_ | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
| #include "lufa.h" | ||||
| #    include "lufa.h" | ||||
| #endif | ||||
| 
 | ||||
| enum MESSAGE_TYPE { | ||||
|     MT_GET_DATA =      0x10, // Get data from keyboard
 | ||||
|     MT_GET_DATA_ACK =  0x11, // returned data to process (ACK)
 | ||||
|     MT_SET_DATA =      0x20, // Set data on keyboard
 | ||||
|     MT_SET_DATA_ACK =  0x21, // returned data to confirm (ACK)
 | ||||
|     MT_SEND_DATA =     0x30, // Sending data/action from keyboard
 | ||||
|     MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK)
 | ||||
|     MT_EXE_ACTION =    0x40, // executing actions on keyboard
 | ||||
|     MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK)
 | ||||
|     MT_TYPE_ERROR =    0x80 // type not recognised (ACK)
 | ||||
|     MT_GET_DATA       = 0x10,  // Get data from keyboard
 | ||||
|     MT_GET_DATA_ACK   = 0x11,  // returned data to process (ACK)
 | ||||
|     MT_SET_DATA       = 0x20,  // Set data on keyboard
 | ||||
|     MT_SET_DATA_ACK   = 0x21,  // returned data to confirm (ACK)
 | ||||
|     MT_SEND_DATA      = 0x30,  // Sending data/action from keyboard
 | ||||
|     MT_SEND_DATA_ACK  = 0x31,  // returned data/action confirmation (ACK)
 | ||||
|     MT_EXE_ACTION     = 0x40,  // executing actions on keyboard
 | ||||
|     MT_EXE_ACTION_ACK = 0x41,  // return confirmation/value (ACK)
 | ||||
|     MT_TYPE_ERROR     = 0x80   // type not recognised (ACK)
 | ||||
| }; | ||||
| 
 | ||||
| enum DATA_TYPE { | ||||
|     DT_NONE = 0x00, | ||||
|     DT_HANDSHAKE, | ||||
|     DT_DEFAULT_LAYER, | ||||
|     DT_CURRENT_LAYER, | ||||
|     DT_KEYMAP_OPTIONS, | ||||
|     DT_BACKLIGHT, | ||||
|     DT_RGBLIGHT, | ||||
|     DT_UNICODE, | ||||
|     DT_DEBUG, | ||||
|     DT_AUDIO, | ||||
|     DT_QUANTUM_ACTION, | ||||
|     DT_KEYBOARD_ACTION, | ||||
|     DT_USER_ACTION, | ||||
|     DT_KEYMAP_SIZE, | ||||
|     DT_KEYMAP | ||||
| }; | ||||
| enum DATA_TYPE { DT_NONE = 0x00, DT_HANDSHAKE, DT_DEFAULT_LAYER, DT_CURRENT_LAYER, DT_KEYMAP_OPTIONS, DT_BACKLIGHT, DT_RGBLIGHT, DT_UNICODE, DT_DEBUG, DT_AUDIO, DT_QUANTUM_ACTION, DT_KEYBOARD_ACTION, DT_USER_ACTION, DT_KEYMAP_SIZE, DT_KEYMAP }; | ||||
| 
 | ||||
| void dword_to_bytes(uint32_t dword, uint8_t * bytes); | ||||
| uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index); | ||||
| void     dword_to_bytes(uint32_t dword, uint8_t* bytes); | ||||
| uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index); | ||||
| 
 | ||||
| #define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length) | ||||
| #define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length) | ||||
|  | @ -63,15 +47,12 @@ uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index); | |||
| #define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length) | ||||
| #define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length) | ||||
| 
 | ||||
| void process_api(uint16_t length, uint8_t * data); | ||||
| void process_api(uint16_t length, uint8_t* data); | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_quantum(uint8_t length, uint8_t * data); | ||||
| __attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data); | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_keyboard(uint8_t length, uint8_t * data); | ||||
| __attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data); | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| bool process_api_user(uint8_t length, uint8_t * data); | ||||
| __attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ | |||
| #include "print.h" | ||||
| #include "qmk_midi.h" | ||||
| 
 | ||||
| void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { | ||||
| void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length) { | ||||
|     // SEND_STRING("\nTX: ");
 | ||||
|     // for (uint8_t i = 0; i < length; i++) {
 | ||||
|     //     send_byte(bytes[i]);
 | ||||
|  | @ -29,7 +29,6 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // The buffer size required is calculated as the following
 | ||||
|     // API_SYSEX_MAX_SIZE is the maximum length
 | ||||
|     // In addition to that we have a two byte message header consisting of the message_type and data_type
 | ||||
|  | @ -37,14 +36,14 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, | |||
|     // We just add one extra byte in case it's not divisible by 7
 | ||||
|     // Then we have an unencoded header consisting of 4 bytes
 | ||||
|     // Plus a one byte terminator
 | ||||
|     const unsigned message_header = 2; | ||||
|     const unsigned message_header    = 2; | ||||
|     const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header; | ||||
|     const unsigned encoding_overhead = unencoded_message / 7 + 1; | ||||
|     const unsigned encoded_size = unencoded_message + encoding_overhead; | ||||
|     const unsigned unencoded_header = 4; | ||||
|     const unsigned terminator = 1; | ||||
|     const unsigned buffer_size = encoded_size + unencoded_header + terminator; | ||||
|     uint8_t buffer[encoded_size + unencoded_header + terminator]; | ||||
|     const unsigned encoded_size      = unencoded_message + encoding_overhead; | ||||
|     const unsigned unencoded_header  = 4; | ||||
|     const unsigned terminator        = 1; | ||||
|     const unsigned buffer_size       = encoded_size + unencoded_header + terminator; | ||||
|     uint8_t        buffer[encoded_size + unencoded_header + terminator]; | ||||
|     // The unencoded header
 | ||||
|     buffer[0] = 0xF0; | ||||
|     buffer[1] = 0x00; | ||||
|  | @ -53,16 +52,16 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, | |||
| 
 | ||||
|     // We copy the message to the end of the array, this way we can do an inplace encoding, using the same
 | ||||
|     // buffer for both input and output
 | ||||
|     const unsigned message_size = length + message_header; | ||||
|     uint8_t* unencoded_start = buffer + buffer_size - message_size; | ||||
|     uint8_t* ptr = unencoded_start; | ||||
|     *(ptr++) = message_type; | ||||
|     *(ptr++) = data_type; | ||||
|     const unsigned message_size    = length + message_header; | ||||
|     uint8_t*       unencoded_start = buffer + buffer_size - message_size; | ||||
|     uint8_t*       ptr             = unencoded_start; | ||||
|     *(ptr++)                       = message_type; | ||||
|     *(ptr++)                       = data_type; | ||||
|     memcpy(ptr, bytes, length); | ||||
| 
 | ||||
|     unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size); | ||||
|     unsigned final_size = unencoded_header + encoded_length + terminator; | ||||
|     buffer[final_size - 1] = 0xF7; | ||||
|     unsigned final_size     = unencoded_header + encoded_length + terminator; | ||||
|     buffer[final_size - 1]  = 0xF7; | ||||
|     midi_send_array(&midi_device, final_size, buffer); | ||||
| 
 | ||||
|     // SEND_STRING("\nTD: ");
 | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ | |||
| 
 | ||||
| #include "api.h" | ||||
| 
 | ||||
| void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length); | ||||
| void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length); | ||||
| 
 | ||||
| #define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l) | ||||
| 
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -19,7 +19,7 @@ | |||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #if defined(__AVR__) | ||||
|   #include <avr/io.h> | ||||
| #    include <avr/io.h> | ||||
| #endif | ||||
| #include "wait.h" | ||||
| #include "musical_notes.h" | ||||
|  | @ -39,9 +39,9 @@ | |||
| typedef union { | ||||
|     uint8_t raw; | ||||
|     struct { | ||||
|         bool    enable :1; | ||||
|         bool    clicky_enable :1; | ||||
|         uint8_t level  :6; | ||||
|         bool    enable : 1; | ||||
|         bool    clicky_enable : 1; | ||||
|         uint8_t level : 6; | ||||
|     }; | ||||
| } audio_config_t; | ||||
| 
 | ||||
|  | @ -58,13 +58,13 @@ void set_vibrato_rate(float rate); | |||
| void increase_vibrato_rate(float change); | ||||
| void decrease_vibrato_rate(float change); | ||||
| 
 | ||||
| #ifdef VIBRATO_STRENGTH_ENABLE | ||||
| #    ifdef VIBRATO_STRENGTH_ENABLE | ||||
| 
 | ||||
| void set_vibrato_strength(float strength); | ||||
| void increase_vibrato_strength(float change); | ||||
| void decrease_vibrato_strength(float change); | ||||
| 
 | ||||
| #endif | ||||
| #    endif | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  | @ -85,25 +85,23 @@ void decrease_tempo(uint8_t tempo_change); | |||
| void audio_init(void); | ||||
| 
 | ||||
| #ifdef PWM_AUDIO | ||||
| void play_sample(uint8_t * s, uint16_t l, bool r); | ||||
| void play_sample(uint8_t* s, uint16_t l, bool r); | ||||
| #endif | ||||
| void play_note(float freq, int vol); | ||||
| void stop_note(float freq); | ||||
| void stop_all_notes(void); | ||||
| void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); | ||||
| 
 | ||||
| #define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ | ||||
|                            0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ | ||||
|                            0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ | ||||
|                            0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ | ||||
|                            0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } | ||||
| #define SCALE \ | ||||
|     (int8_t[]) { 0 + (12 * 0), 2 + (12 * 0), 4 + (12 * 0), 5 + (12 * 0), 7 + (12 * 0), 9 + (12 * 0), 11 + (12 * 0), 0 + (12 * 1), 2 + (12 * 1), 4 + (12 * 1), 5 + (12 * 1), 7 + (12 * 1), 9 + (12 * 1), 11 + (12 * 1), 0 + (12 * 2), 2 + (12 * 2), 4 + (12 * 2), 5 + (12 * 2), 7 + (12 * 2), 9 + (12 * 2), 11 + (12 * 2), 0 + (12 * 3), 2 + (12 * 3), 4 + (12 * 3), 5 + (12 * 3), 7 + (12 * 3), 9 + (12 * 3), 11 + (12 * 3), 0 + (12 * 4), 2 + (12 * 4), 4 + (12 * 4), 5 + (12 * 4), 7 + (12 * 4), 9 + (12 * 4), 11 + (12 * 4), } | ||||
| 
 | ||||
| // These macros are used to allow play_notes to play an array of indeterminate
 | ||||
| // length. This works around the limitation of C's sizeof operation on pointers.
 | ||||
| // The global float array for the song must be used here.
 | ||||
| #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) | ||||
| #define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ | ||||
| 	_Pragma ("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") | ||||
| #define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg)           \ | ||||
|     play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ | ||||
|     _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") | ||||
| #define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) | ||||
| #define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) | ||||
| 
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -29,7 +29,6 @@ | |||
| 
 | ||||
| #define CPU_PRESCALER 8 | ||||
| 
 | ||||
| 
 | ||||
| // Timer Abstractions
 | ||||
| 
 | ||||
| // TIMSK3 - Timer/Counter #3 Interrupt Mask Register
 | ||||
|  | @ -37,70 +36,67 @@ | |||
| #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) | ||||
| #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) | ||||
| 
 | ||||
| 
 | ||||
| // TCCR3A: Timer/Counter #3 Control Register
 | ||||
| // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
 | ||||
| #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); | ||||
| #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); | ||||
| 
 | ||||
| 
 | ||||
| #define NOTE_PERIOD ICR3 | ||||
| #define NOTE_DUTY_CYCLE OCR3A | ||||
| 
 | ||||
| 
 | ||||
| #ifdef PWM_AUDIO | ||||
|     #include "wave.h" | ||||
|     #define SAMPLE_DIVIDER 39 | ||||
|     #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) | ||||
|     // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
 | ||||
| #    include "wave.h" | ||||
| #    define SAMPLE_DIVIDER 39 | ||||
| #    define SAMPLE_RATE (2000000.0 / SAMPLE_DIVIDER / 2048) | ||||
| // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
 | ||||
| 
 | ||||
|     float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||||
|     uint16_t place_int = 0; | ||||
|     bool repeat = true; | ||||
| float    places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||||
| uint16_t place_int = 0; | ||||
| bool     repeat    = true; | ||||
| #endif | ||||
| 
 | ||||
| void delay_us(int count) { | ||||
|   while(count--) { | ||||
|     _delay_us(1); | ||||
|   } | ||||
|     while (count--) { | ||||
|         _delay_us(1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int voices = 0; | ||||
| int voice_place = 0; | ||||
| float frequency = 0; | ||||
| int volume = 0; | ||||
| long position = 0; | ||||
| int   voices      = 0; | ||||
| int   voice_place = 0; | ||||
| float frequency   = 0; | ||||
| int   volume      = 0; | ||||
| long  position    = 0; | ||||
| 
 | ||||
| float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||||
| int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||||
| bool sliding = false; | ||||
| int   volumes[8]     = {0, 0, 0, 0, 0, 0, 0, 0}; | ||||
| bool  sliding        = false; | ||||
| 
 | ||||
| float place = 0; | ||||
| 
 | ||||
| uint8_t * sample; | ||||
| uint8_t* sample; | ||||
| uint16_t sample_length = 0; | ||||
| // float freq = 0;
 | ||||
| 
 | ||||
| bool     playing_notes = false; | ||||
| bool     playing_note = false; | ||||
| bool     playing_notes  = false; | ||||
| bool     playing_note   = false; | ||||
| float    note_frequency = 0; | ||||
| float    note_length = 0; | ||||
| uint8_t  note_tempo = TEMPO_DEFAULT; | ||||
| float    note_timbre = TIMBRE_DEFAULT; | ||||
| uint16_t note_position = 0; | ||||
| float (* notes_pointer)[][2]; | ||||
| float    note_length    = 0; | ||||
| uint8_t  note_tempo     = TEMPO_DEFAULT; | ||||
| float    note_timbre    = TIMBRE_DEFAULT; | ||||
| uint16_t note_position  = 0; | ||||
| float (*notes_pointer)[][2]; | ||||
| uint16_t notes_count; | ||||
| bool     notes_repeat; | ||||
| float    notes_rest; | ||||
| bool     note_resting = false; | ||||
| 
 | ||||
| uint16_t current_note = 0; | ||||
| uint8_t rest_counter = 0; | ||||
| uint8_t  rest_counter = 0; | ||||
| 
 | ||||
| #ifdef VIBRATO_ENABLE | ||||
| float vibrato_counter = 0; | ||||
| float vibrato_counter  = 0; | ||||
| float vibrato_strength = .5; | ||||
| float vibrato_rate = 0.125; | ||||
| float vibrato_rate     = 0.125; | ||||
| #endif | ||||
| 
 | ||||
| float polyphony_rate = 0; | ||||
|  | @ -112,50 +108,49 @@ audio_config_t audio_config; | |||
| uint16_t envelope_index = 0; | ||||
| 
 | ||||
| void audio_init() { | ||||
| 
 | ||||
|     // Check EEPROM
 | ||||
|     if (!eeconfig_is_enabled()) | ||||
|     { | ||||
|     if (!eeconfig_is_enabled()) { | ||||
|         eeconfig_init(); | ||||
|     } | ||||
|     audio_config.raw = eeconfig_read_audio(); | ||||
| 
 | ||||
|     #ifdef PWM_AUDIO | ||||
| #ifdef PWM_AUDIO | ||||
| 
 | ||||
|         PLLFRQ = _BV(PDIV2); | ||||
|         PLLCSR = _BV(PLLE); | ||||
|         while(!(PLLCSR & _BV(PLOCK))); | ||||
|         PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ | ||||
|     PLLFRQ = _BV(PDIV2); | ||||
|     PLLCSR = _BV(PLLE); | ||||
|     while (!(PLLCSR & _BV(PLOCK))) | ||||
|         ; | ||||
|     PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ | ||||
| 
 | ||||
|         /* Init a fast PWM on Timer4 */ | ||||
|         TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ | ||||
|         TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ | ||||
|         OCR4A = 0; | ||||
|     /* Init a fast PWM on Timer4 */ | ||||
|     TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ | ||||
|     TCCR4B = _BV(CS40);                /* No prescaling => f = PCK/256 = 187500Hz */ | ||||
|     OCR4A  = 0; | ||||
| 
 | ||||
|         /* Enable the OC4A output */ | ||||
|         DDRC |= _BV(PORTC6); | ||||
|     /* Enable the OC4A output */ | ||||
|     DDRC |= _BV(PORTC6); | ||||
| 
 | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; // Turn off 3A interputs
 | ||||
|     DISABLE_AUDIO_COUNTER_3_ISR;  // Turn off 3A interputs
 | ||||
| 
 | ||||
|         TCCR3A = 0x0; // Options not needed
 | ||||
|         TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
 | ||||
|         OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
 | ||||
|     TCCR3A = 0x0;                                 // Options not needed
 | ||||
|     TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32);  // 64th prescaling and CTC
 | ||||
|     OCR3A  = SAMPLE_DIVIDER - 1;                  // Correct count/compare, related to sample playback
 | ||||
| 
 | ||||
|     #else | ||||
| #else | ||||
| 
 | ||||
|     	// Set port PC6 (OC3A and /OC4A) as output
 | ||||
|         DDRC |= _BV(PORTC6); | ||||
|     // Set port PC6 (OC3A and /OC4A) as output
 | ||||
|     DDRC |= _BV(PORTC6); | ||||
| 
 | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|     DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| 
 | ||||
| 		// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
 | ||||
| 		// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
 | ||||
| 		// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
 | ||||
| 		// Clock Select (CS3n) = 0b010 = Clock / 8
 | ||||
|         TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | ||||
|         TCCR3B = (1 << WGM33)  | (1 << WGM32)  | (0 << CS32)  | (1 << CS31) | (0 << CS30); | ||||
|     // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
 | ||||
|     // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
 | ||||
|     // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
 | ||||
|     // Clock Select (CS3n) = 0b010 = Clock / 8
 | ||||
|     TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | ||||
|     TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); | ||||
| 
 | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
|     audio_initialized = true; | ||||
| } | ||||
|  | @ -165,62 +160,59 @@ void stop_all_notes() { | |||
|         audio_init(); | ||||
|     } | ||||
|     voices = 0; | ||||
|     #ifdef PWM_AUDIO | ||||
| 	    DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|     #else | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|         DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
|     #endif | ||||
| #ifdef PWM_AUDIO | ||||
|     DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| #else | ||||
|     DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|     DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| #endif | ||||
| 
 | ||||
|     playing_notes = false; | ||||
|     playing_note = false; | ||||
|     frequency = 0; | ||||
|     volume = 0; | ||||
|     playing_note  = false; | ||||
|     frequency     = 0; | ||||
|     volume        = 0; | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < 8; i++) | ||||
|     { | ||||
|     for (uint8_t i = 0; i < 8; i++) { | ||||
|         frequencies[i] = 0; | ||||
|         volumes[i] = 0; | ||||
|         volumes[i]     = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void stop_note(float freq) | ||||
| { | ||||
| void stop_note(float freq) { | ||||
|     if (playing_note) { | ||||
|         if (!audio_initialized) { | ||||
|             audio_init(); | ||||
|         } | ||||
|         #ifdef PWM_AUDIO | ||||
|             freq = freq / SAMPLE_RATE; | ||||
|         #endif | ||||
| #ifdef PWM_AUDIO | ||||
|         freq = freq / SAMPLE_RATE; | ||||
| #endif | ||||
|         for (int i = 7; i >= 0; i--) { | ||||
|             if (frequencies[i] == freq) { | ||||
|                 frequencies[i] = 0; | ||||
|                 volumes[i] = 0; | ||||
|                 volumes[i]     = 0; | ||||
|                 for (int j = i; (j < 7); j++) { | ||||
|                     frequencies[j] = frequencies[j+1]; | ||||
|                     frequencies[j+1] = 0; | ||||
|                     volumes[j] = volumes[j+1]; | ||||
|                     volumes[j+1] = 0; | ||||
|                     frequencies[j]     = frequencies[j + 1]; | ||||
|                     frequencies[j + 1] = 0; | ||||
|                     volumes[j]         = volumes[j + 1]; | ||||
|                     volumes[j + 1]     = 0; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         voices--; | ||||
|         if (voices < 0) | ||||
|             voices = 0; | ||||
|         if (voices < 0) voices = 0; | ||||
|         if (voice_place >= voices) { | ||||
|             voice_place = 0; | ||||
|         } | ||||
|         if (voices == 0) { | ||||
|             #ifdef PWM_AUDIO | ||||
|                 DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|             #else | ||||
|                 DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|                 DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
|             #endif | ||||
|             frequency = 0; | ||||
|             volume = 0; | ||||
| #ifdef PWM_AUDIO | ||||
|             DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| #else | ||||
|             DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|             DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| #endif | ||||
|             frequency    = 0; | ||||
|             volume       = 0; | ||||
|             playing_note = false; | ||||
|         } | ||||
|     } | ||||
|  | @ -228,126 +220,120 @@ void stop_note(float freq) | |||
| 
 | ||||
| #ifdef VIBRATO_ENABLE | ||||
| 
 | ||||
| float mod(float a, int b) | ||||
| { | ||||
| float mod(float a, int b) { | ||||
|     float r = fmod(a, b); | ||||
|     return r < 0 ? r + b : r; | ||||
| } | ||||
| 
 | ||||
| float vibrato(float average_freq) { | ||||
|     #ifdef VIBRATO_STRENGTH_ENABLE | ||||
|         float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); | ||||
|     #else | ||||
|         float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; | ||||
|     #endif | ||||
|     vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); | ||||
| #    ifdef VIBRATO_STRENGTH_ENABLE | ||||
|     float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); | ||||
| #    else | ||||
|     float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; | ||||
| #    endif | ||||
|     vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); | ||||
|     return vibrated_freq; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| ISR(TIMER3_COMPA_vect) | ||||
| { | ||||
| ISR(TIMER3_COMPA_vect) { | ||||
|     if (playing_note) { | ||||
|         #ifdef PWM_AUDIO | ||||
|             if (voices == 1) { | ||||
| #ifdef PWM_AUDIO | ||||
|         if (voices == 1) { | ||||
|             // SINE
 | ||||
|             OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; | ||||
| 
 | ||||
|             // SQUARE
 | ||||
|             // if (((int)place) >= 1024){
 | ||||
|             //     OCR4A = 0xFF >> 2;
 | ||||
|             // } else {
 | ||||
|             //     OCR4A = 0x00;
 | ||||
|             // }
 | ||||
| 
 | ||||
|             // SAWTOOTH
 | ||||
|             // OCR4A = (int)place / 4;
 | ||||
| 
 | ||||
|             // TRIANGLE
 | ||||
|             // if (((int)place) >= 1024) {
 | ||||
|             //     OCR4A = (int)place / 2;
 | ||||
|             // } else {
 | ||||
|             //     OCR4A = 2048 - (int)place / 2;
 | ||||
|             // }
 | ||||
| 
 | ||||
|             place += frequency; | ||||
| 
 | ||||
|             if (place >= SINE_LENGTH) place -= SINE_LENGTH; | ||||
| 
 | ||||
|         } else { | ||||
|             int sum = 0; | ||||
|             for (int i = 0; i < voices; i++) { | ||||
|                 // SINE
 | ||||
|                 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; | ||||
|                 sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; | ||||
| 
 | ||||
|                 // SQUARE
 | ||||
|                 // if (((int)place) >= 1024){
 | ||||
|                 //     OCR4A = 0xFF >> 2;
 | ||||
|                 // if (((int)places[i]) >= 1024){
 | ||||
|                 //     sum += 0xFF >> 2;
 | ||||
|                 // } else {
 | ||||
|                 //     OCR4A = 0x00;
 | ||||
|                 //     sum += 0x00;
 | ||||
|                 // }
 | ||||
| 
 | ||||
|                 // SAWTOOTH
 | ||||
|                 // OCR4A = (int)place / 4;
 | ||||
|                 places[i] += frequencies[i]; | ||||
| 
 | ||||
|                 // TRIANGLE
 | ||||
|                 // if (((int)place) >= 1024) {
 | ||||
|                 //     OCR4A = (int)place / 2;
 | ||||
|                 // } else {
 | ||||
|                 //     OCR4A = 2048 - (int)place / 2;
 | ||||
|                 // }
 | ||||
| 
 | ||||
|                 place += frequency; | ||||
| 
 | ||||
|                 if (place >= SINE_LENGTH) | ||||
|                     place -= SINE_LENGTH; | ||||
| 
 | ||||
|             } else { | ||||
|                 int sum = 0; | ||||
|                 for (int i = 0; i < voices; i++) { | ||||
|                     // SINE
 | ||||
|                     sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; | ||||
| 
 | ||||
|                     // SQUARE
 | ||||
|                     // if (((int)places[i]) >= 1024){
 | ||||
|                     //     sum += 0xFF >> 2;
 | ||||
|                     // } else {
 | ||||
|                     //     sum += 0x00;
 | ||||
|                     // }
 | ||||
| 
 | ||||
|                     places[i] += frequencies[i]; | ||||
| 
 | ||||
|                     if (places[i] >= SINE_LENGTH) | ||||
|                         places[i] -= SINE_LENGTH; | ||||
|                 } | ||||
|                 OCR4A = sum; | ||||
|                 if (places[i] >= SINE_LENGTH) places[i] -= SINE_LENGTH; | ||||
|             } | ||||
|         #else | ||||
|             if (voices > 0) { | ||||
|                 float freq; | ||||
|                 if (polyphony_rate > 0) { | ||||
|                     if (voices > 1) { | ||||
|                         voice_place %= voices; | ||||
|                         if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { | ||||
|                             voice_place = (voice_place + 1) % voices; | ||||
|                             place = 0.0; | ||||
|                         } | ||||
|                     } | ||||
|                     #ifdef VIBRATO_ENABLE | ||||
|                     if (vibrato_strength > 0) { | ||||
|                         freq = vibrato(frequencies[voice_place]); | ||||
|                     } else { | ||||
|                     #else | ||||
|                     { | ||||
|                     #endif | ||||
|                         freq = frequencies[voice_place]; | ||||
|             OCR4A = sum; | ||||
|         } | ||||
| #else | ||||
|         if (voices > 0) { | ||||
|             float freq; | ||||
|             if (polyphony_rate > 0) { | ||||
|                 if (voices > 1) { | ||||
|                     voice_place %= voices; | ||||
|                     if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { | ||||
|                         voice_place = (voice_place + 1) % voices; | ||||
|                         place       = 0.0; | ||||
|                     } | ||||
|                 } | ||||
| #    ifdef VIBRATO_ENABLE | ||||
|                 if (vibrato_strength > 0) { | ||||
|                     freq = vibrato(frequencies[voice_place]); | ||||
|                 } else { | ||||
|                     if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { | ||||
|                         frequency = frequency * pow(2, 440/frequency/12/2); | ||||
|                     } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { | ||||
|                         frequency = frequency * pow(2, -440/frequency/12/2); | ||||
|                     } else { | ||||
|                         frequency = frequencies[voices - 1]; | ||||
|                     } | ||||
| 
 | ||||
| 
 | ||||
|                     #ifdef VIBRATO_ENABLE | ||||
|                     if (vibrato_strength > 0) { | ||||
|                         freq = vibrato(frequency); | ||||
|                     } else { | ||||
|                     #else | ||||
|                     { | ||||
|                     #endif | ||||
|                         freq = frequency; | ||||
|                     } | ||||
| #    else | ||||
|                 { | ||||
| #    endif | ||||
|                     freq = frequencies[voice_place]; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { | ||||
|                     frequency = frequency * pow(2, 440 / frequency / 12 / 2); | ||||
|                 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { | ||||
|                     frequency = frequency * pow(2, -440 / frequency / 12 / 2); | ||||
|                 } else { | ||||
|                     frequency = frequencies[voices - 1]; | ||||
|                 } | ||||
| 
 | ||||
|                 if (envelope_index < 65535) { | ||||
|                     envelope_index++; | ||||
| #    ifdef VIBRATO_ENABLE | ||||
|                 if (vibrato_strength > 0) { | ||||
|                     freq = vibrato(frequency); | ||||
|                 } else { | ||||
| #    else | ||||
|                 { | ||||
| #    endif | ||||
|                     freq = frequency; | ||||
|                 } | ||||
|                 freq = voice_envelope(freq); | ||||
| 
 | ||||
|                 if (freq < 30.517578125) | ||||
|                     freq = 30.52; | ||||
|                 NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
 | ||||
|                 NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
 | ||||
|             } | ||||
|         #endif | ||||
| 
 | ||||
|             if (envelope_index < 65535) { | ||||
|                 envelope_index++; | ||||
|             } | ||||
|             freq = voice_envelope(freq); | ||||
| 
 | ||||
|             if (freq < 30.517578125) freq = 30.52; | ||||
|             NOTE_PERIOD     = (int)(((double)F_CPU) / (freq * CPU_PRESCALER));                  // Set max to the period
 | ||||
|             NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);  // Set compare to half the period
 | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     // SAMPLE
 | ||||
|  | @ -361,41 +347,38 @@ ISR(TIMER3_COMPA_vect) | |||
|     //     else
 | ||||
|     //         DISABLE_AUDIO_COUNTER_3_ISR;
 | ||||
| 
 | ||||
| 
 | ||||
|     if (playing_notes) { | ||||
|         #ifdef PWM_AUDIO | ||||
|             OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; | ||||
| #ifdef PWM_AUDIO | ||||
|         OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; | ||||
| 
 | ||||
|             place += note_frequency; | ||||
|             if (place >= SINE_LENGTH) | ||||
|                 place -= SINE_LENGTH; | ||||
|         #else | ||||
|             if (note_frequency > 0) { | ||||
|                 float freq; | ||||
|         place += note_frequency; | ||||
|         if (place >= SINE_LENGTH) place -= SINE_LENGTH; | ||||
| #else | ||||
|         if (note_frequency > 0) { | ||||
|             float freq; | ||||
| 
 | ||||
|                 #ifdef VIBRATO_ENABLE | ||||
|                 if (vibrato_strength > 0) { | ||||
|                     freq = vibrato(note_frequency); | ||||
|                 } else { | ||||
|                 #else | ||||
|                 { | ||||
|                 #endif | ||||
|                     freq = note_frequency; | ||||
|                 } | ||||
| 
 | ||||
|                 if (envelope_index < 65535) { | ||||
|                     envelope_index++; | ||||
|                 } | ||||
|                 freq = voice_envelope(freq); | ||||
| 
 | ||||
|                 NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
 | ||||
|                 NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
 | ||||
| #    ifdef VIBRATO_ENABLE | ||||
|             if (vibrato_strength > 0) { | ||||
|                 freq = vibrato(note_frequency); | ||||
|             } else { | ||||
|                 NOTE_PERIOD = 0; | ||||
|                 NOTE_DUTY_CYCLE = 0; | ||||
| #    else | ||||
|             { | ||||
| #    endif | ||||
|                 freq = note_frequency; | ||||
|             } | ||||
|         #endif | ||||
| 
 | ||||
|             if (envelope_index < 65535) { | ||||
|                 envelope_index++; | ||||
|             } | ||||
|             freq = voice_envelope(freq); | ||||
| 
 | ||||
|             NOTE_PERIOD     = (int)(((double)F_CPU) / (freq * CPU_PRESCALER));                  // Set max to the period
 | ||||
|             NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);  // Set compare to half the period
 | ||||
|         } else { | ||||
|             NOTE_PERIOD     = 0; | ||||
|             NOTE_DUTY_CYCLE = 0; | ||||
|         } | ||||
| #endif | ||||
| 
 | ||||
|         note_position++; | ||||
|         bool end_of_note = false; | ||||
|  | @ -409,126 +392,116 @@ ISR(TIMER3_COMPA_vect) | |||
|                 if (notes_repeat) { | ||||
|                     current_note = 0; | ||||
|                 } else { | ||||
|                     #ifdef PWM_AUDIO | ||||
|                         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|                     #else | ||||
|                         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|                         DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
|                     #endif | ||||
| #ifdef PWM_AUDIO | ||||
|                     DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| #else | ||||
|                     DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|                     DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| #endif | ||||
|                     playing_notes = false; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             if (!note_resting && (notes_rest > 0)) { | ||||
|                 note_resting = true; | ||||
|                 note_resting   = true; | ||||
|                 note_frequency = 0; | ||||
|                 note_length = notes_rest; | ||||
|                 note_length    = notes_rest; | ||||
|                 current_note--; | ||||
|             } else { | ||||
|                 note_resting = false; | ||||
|                 #ifdef PWM_AUDIO | ||||
|                     note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||||
|                     note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||||
|                 #else | ||||
|                     envelope_index = 0; | ||||
|                     note_frequency = (*notes_pointer)[current_note][0]; | ||||
|                     note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||||
|                 #endif | ||||
| #ifdef PWM_AUDIO | ||||
|                 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||||
|                 note_length    = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||||
| #else | ||||
|                 envelope_index = 0; | ||||
|                 note_frequency = (*notes_pointer)[current_note][0]; | ||||
|                 note_length    = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||||
| #endif | ||||
|             } | ||||
|             note_position = 0; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     if (!audio_config.enable) { | ||||
|         playing_notes = false; | ||||
|         playing_note = false; | ||||
|         playing_note  = false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void play_note(float freq, int vol) { | ||||
| 
 | ||||
|     if (!audio_initialized) { | ||||
|         audio_init(); | ||||
|     } | ||||
| 
 | ||||
| 	if (audio_config.enable && voices < 8) { | ||||
| 	    DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|     if (audio_config.enable && voices < 8) { | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| 
 | ||||
| 	    // Cancel notes if notes are playing
 | ||||
| 	    if (playing_notes) | ||||
| 	        stop_all_notes(); | ||||
|         // Cancel notes if notes are playing
 | ||||
|         if (playing_notes) stop_all_notes(); | ||||
| 
 | ||||
| 	    playing_note = true; | ||||
|         playing_note = true; | ||||
| 
 | ||||
| 	    envelope_index = 0; | ||||
|         envelope_index = 0; | ||||
| 
 | ||||
| 	    #ifdef PWM_AUDIO | ||||
| 	        freq = freq / SAMPLE_RATE; | ||||
| 	    #endif | ||||
| 	    if (freq > 0) { | ||||
| 	        frequencies[voices] = freq; | ||||
| 	        volumes[voices] = vol; | ||||
| 	        voices++; | ||||
| 	    } | ||||
| 
 | ||||
| 	    #ifdef PWM_AUDIO | ||||
| 	        ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| 	    #else | ||||
| 	        ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| 	        ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| 	    #endif | ||||
| 	} | ||||
| #ifdef PWM_AUDIO | ||||
|         freq = freq / SAMPLE_RATE; | ||||
| #endif | ||||
|         if (freq > 0) { | ||||
|             frequencies[voices] = freq; | ||||
|             volumes[voices]     = vol; | ||||
|             voices++; | ||||
|         } | ||||
| 
 | ||||
| #ifdef PWM_AUDIO | ||||
|         ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| #else | ||||
|         ENABLE_AUDIO_COUNTER_3_ISR; | ||||
|         ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) | ||||
| { | ||||
| 
 | ||||
| void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { | ||||
|     if (!audio_initialized) { | ||||
|         audio_init(); | ||||
|     } | ||||
| 
 | ||||
| 	if (audio_config.enable) { | ||||
|     if (audio_config.enable) { | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
| 
 | ||||
| 	    DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|         // Cancel note if a note is playing
 | ||||
|         if (playing_note) stop_all_notes(); | ||||
| 
 | ||||
| 		// Cancel note if a note is playing
 | ||||
| 	    if (playing_note) | ||||
| 	        stop_all_notes(); | ||||
|         playing_notes = true; | ||||
| 
 | ||||
| 	    playing_notes = true; | ||||
|         notes_pointer = np; | ||||
|         notes_count   = n_count; | ||||
|         notes_repeat  = n_repeat; | ||||
|         notes_rest    = n_rest; | ||||
| 
 | ||||
| 	    notes_pointer = np; | ||||
| 	    notes_count = n_count; | ||||
| 	    notes_repeat = n_repeat; | ||||
| 	    notes_rest = n_rest; | ||||
|         place        = 0; | ||||
|         current_note = 0; | ||||
| 
 | ||||
| 	    place = 0; | ||||
| 	    current_note = 0; | ||||
| 
 | ||||
| 	    #ifdef PWM_AUDIO | ||||
| 	        note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||||
| 	        note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||||
| 	    #else | ||||
| 	        note_frequency = (*notes_pointer)[current_note][0]; | ||||
| 	        note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||||
| 	    #endif | ||||
| 	    note_position = 0; | ||||
| 
 | ||||
| 
 | ||||
| 	    #ifdef PWM_AUDIO | ||||
| 	        ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| 	    #else | ||||
| 	        ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| 	        ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| 	    #endif | ||||
| 	} | ||||
| #ifdef PWM_AUDIO | ||||
|         note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||||
|         note_length    = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||||
| #else | ||||
|         note_frequency = (*notes_pointer)[current_note][0]; | ||||
|         note_length    = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||||
| #endif | ||||
|         note_position = 0; | ||||
| 
 | ||||
| #ifdef PWM_AUDIO | ||||
|         ENABLE_AUDIO_COUNTER_3_ISR; | ||||
| #else | ||||
|         ENABLE_AUDIO_COUNTER_3_ISR; | ||||
|         ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #ifdef PWM_AUDIO | ||||
| void play_sample(uint8_t * s, uint16_t l, bool r) { | ||||
| void play_sample(uint8_t* s, uint16_t l, bool r) { | ||||
|     if (!audio_initialized) { | ||||
|         audio_init(); | ||||
|     } | ||||
|  | @ -536,17 +509,16 @@ void play_sample(uint8_t * s, uint16_t l, bool r) { | |||
|     if (audio_config.enable) { | ||||
|         DISABLE_AUDIO_COUNTER_3_ISR; | ||||
|         stop_all_notes(); | ||||
|         place_int = 0; | ||||
|         sample = s; | ||||
|         place_int     = 0; | ||||
|         sample        = s; | ||||
|         sample_length = l; | ||||
|         repeat = r; | ||||
|         repeat        = r; | ||||
| 
 | ||||
|         ENABLE_AUDIO_COUNTER_3_ISR; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| void audio_toggle(void) { | ||||
|     audio_config.enable ^= 1; | ||||
|     eeconfig_update_audio(audio_config.raw); | ||||
|  | @ -566,73 +538,45 @@ void audio_off(void) { | |||
| 
 | ||||
| // Vibrato rate functions
 | ||||
| 
 | ||||
| void set_vibrato_rate(float rate) { | ||||
|     vibrato_rate = rate; | ||||
| } | ||||
| void set_vibrato_rate(float rate) { vibrato_rate = rate; } | ||||
| 
 | ||||
| void increase_vibrato_rate(float change) { | ||||
|     vibrato_rate *= change; | ||||
| } | ||||
| void increase_vibrato_rate(float change) { vibrato_rate *= change; } | ||||
| 
 | ||||
| void decrease_vibrato_rate(float change) { | ||||
|     vibrato_rate /= change; | ||||
| } | ||||
| void decrease_vibrato_rate(float change) { vibrato_rate /= change; } | ||||
| 
 | ||||
| #ifdef VIBRATO_STRENGTH_ENABLE | ||||
| #    ifdef VIBRATO_STRENGTH_ENABLE | ||||
| 
 | ||||
| void set_vibrato_strength(float strength) { | ||||
|     vibrato_strength = strength; | ||||
| } | ||||
| void set_vibrato_strength(float strength) { vibrato_strength = strength; } | ||||
| 
 | ||||
| void increase_vibrato_strength(float change) { | ||||
|     vibrato_strength *= change; | ||||
| } | ||||
| void increase_vibrato_strength(float change) { vibrato_strength *= change; } | ||||
| 
 | ||||
| void decrease_vibrato_strength(float change) { | ||||
|     vibrato_strength /= change; | ||||
| } | ||||
| void decrease_vibrato_strength(float change) { vibrato_strength /= change; } | ||||
| 
 | ||||
| #endif  /* VIBRATO_STRENGTH_ENABLE */ | ||||
| #    endif /* VIBRATO_STRENGTH_ENABLE */ | ||||
| 
 | ||||
| #endif /* VIBRATO_ENABLE */ | ||||
| 
 | ||||
| // Polyphony functions
 | ||||
| 
 | ||||
| void set_polyphony_rate(float rate) { | ||||
|     polyphony_rate = rate; | ||||
| } | ||||
| void set_polyphony_rate(float rate) { polyphony_rate = rate; } | ||||
| 
 | ||||
| void enable_polyphony() { | ||||
|     polyphony_rate = 5; | ||||
| } | ||||
| void enable_polyphony() { polyphony_rate = 5; } | ||||
| 
 | ||||
| void disable_polyphony() { | ||||
|     polyphony_rate = 0; | ||||
| } | ||||
| void disable_polyphony() { polyphony_rate = 0; } | ||||
| 
 | ||||
| void increase_polyphony_rate(float change) { | ||||
|     polyphony_rate *= change; | ||||
| } | ||||
| void increase_polyphony_rate(float change) { polyphony_rate *= change; } | ||||
| 
 | ||||
| void decrease_polyphony_rate(float change) { | ||||
|     polyphony_rate /= change; | ||||
| } | ||||
| void decrease_polyphony_rate(float change) { polyphony_rate /= change; } | ||||
| 
 | ||||
| // Timbre function
 | ||||
| 
 | ||||
| void set_timbre(float timbre) { | ||||
|     note_timbre = timbre; | ||||
| } | ||||
| void set_timbre(float timbre) { note_timbre = timbre; } | ||||
| 
 | ||||
| // Tempo functions
 | ||||
| 
 | ||||
| void set_tempo(uint8_t tempo) { | ||||
|     note_tempo = tempo; | ||||
| } | ||||
| void set_tempo(uint8_t tempo) { note_tempo = tempo; } | ||||
| 
 | ||||
| void decrease_tempo(uint8_t tempo_change) { | ||||
|     note_tempo += tempo_change; | ||||
| } | ||||
| void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } | ||||
| 
 | ||||
| void increase_tempo(uint8_t tempo_change) { | ||||
|     if (note_tempo - tempo_change < 10) { | ||||
|  | @ -642,17 +586,10 @@ void increase_tempo(uint8_t tempo_change) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //------------------------------------------------------------------------------
 | ||||
| // Override these functions in your keymap file to play different tunes on
 | ||||
| // startup and bootloader jump
 | ||||
| __attribute__ ((weak)) | ||||
| void play_startup_tone() | ||||
| { | ||||
| } | ||||
| __attribute__((weak)) void play_startup_tone() {} | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| void play_goodbye_tone() | ||||
| { | ||||
| } | ||||
| __attribute__((weak)) void play_goodbye_tone() {} | ||||
| //------------------------------------------------------------------------------
 | ||||
|  |  | |||
|  | @ -16,380 +16,12 @@ | |||
| 
 | ||||
| #include "luts.h" | ||||
| 
 | ||||
| const float vibrato_lut[VIBRATO_LUT_LENGTH] = | ||||
| { | ||||
| 	1.0022336811487, | ||||
| 	1.0042529943610, | ||||
| 	1.0058584256028, | ||||
| 	1.0068905285205, | ||||
| 	1.0072464122237, | ||||
| 	1.0068905285205, | ||||
| 	1.0058584256028, | ||||
| 	1.0042529943610, | ||||
| 	1.0022336811487, | ||||
| 	1.0000000000000, | ||||
| 	0.9977712970630, | ||||
| 	0.9957650169978, | ||||
| 	0.9941756956510, | ||||
| 	0.9931566259436, | ||||
| 	0.9928057204913, | ||||
| 	0.9931566259436, | ||||
| 	0.9941756956510, | ||||
| 	0.9957650169978, | ||||
| 	0.9977712970630, | ||||
| 	1.0000000000000, | ||||
| const float vibrato_lut[VIBRATO_LUT_LENGTH] = { | ||||
|     1.0022336811487, 1.0042529943610, 1.0058584256028, 1.0068905285205, 1.0072464122237, 1.0068905285205, 1.0058584256028, 1.0042529943610, 1.0022336811487, 1.0000000000000, 0.9977712970630, 0.9957650169978, 0.9941756956510, 0.9931566259436, 0.9928057204913, 0.9931566259436, 0.9941756956510, 0.9957650169978, 0.9977712970630, 1.0000000000000, | ||||
| }; | ||||
| 
 | ||||
| const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] = | ||||
| { | ||||
| 	0x8E0B, | ||||
| 	0x8C02, | ||||
| 	0x8A00, | ||||
| 	0x8805, | ||||
| 	0x8612, | ||||
| 	0x8426, | ||||
| 	0x8241, | ||||
| 	0x8063, | ||||
| 	0x7E8C, | ||||
| 	0x7CBB, | ||||
| 	0x7AF2, | ||||
| 	0x792E, | ||||
| 	0x7772, | ||||
| 	0x75BB, | ||||
| 	0x740B, | ||||
| 	0x7261, | ||||
| 	0x70BD, | ||||
| 	0x6F20, | ||||
| 	0x6D88, | ||||
| 	0x6BF6, | ||||
| 	0x6A69, | ||||
| 	0x68E3, | ||||
| 	0x6762, | ||||
| 	0x65E6, | ||||
| 	0x6470, | ||||
| 	0x6300, | ||||
| 	0x6194, | ||||
| 	0x602E, | ||||
| 	0x5ECD, | ||||
| 	0x5D71, | ||||
| 	0x5C1A, | ||||
| 	0x5AC8, | ||||
| 	0x597B, | ||||
| 	0x5833, | ||||
| 	0x56EF, | ||||
| 	0x55B0, | ||||
| 	0x5475, | ||||
| 	0x533F, | ||||
| 	0x520E, | ||||
| 	0x50E1, | ||||
| 	0x4FB8, | ||||
| 	0x4E93, | ||||
| 	0x4D73, | ||||
| 	0x4C57, | ||||
| 	0x4B3E, | ||||
| 	0x4A2A, | ||||
| 	0x491A, | ||||
| 	0x480E, | ||||
| 	0x4705, | ||||
| 	0x4601, | ||||
| 	0x4500, | ||||
| 	0x4402, | ||||
| 	0x4309, | ||||
| 	0x4213, | ||||
| 	0x4120, | ||||
| 	0x4031, | ||||
| 	0x3F46, | ||||
| 	0x3E5D, | ||||
| 	0x3D79, | ||||
| 	0x3C97, | ||||
| 	0x3BB9, | ||||
| 	0x3ADD, | ||||
| 	0x3A05, | ||||
| 	0x3930, | ||||
| 	0x385E, | ||||
| 	0x3790, | ||||
| 	0x36C4, | ||||
| 	0x35FB, | ||||
| 	0x3534, | ||||
| 	0x3471, | ||||
| 	0x33B1, | ||||
| 	0x32F3, | ||||
| 	0x3238, | ||||
| 	0x3180, | ||||
| 	0x30CA, | ||||
| 	0x3017, | ||||
| 	0x2F66, | ||||
| 	0x2EB8, | ||||
| 	0x2E0D, | ||||
| 	0x2D64, | ||||
| 	0x2CBD, | ||||
| 	0x2C19, | ||||
| 	0x2B77, | ||||
| 	0x2AD8, | ||||
| 	0x2A3A, | ||||
| 	0x299F, | ||||
| 	0x2907, | ||||
| 	0x2870, | ||||
| 	0x27DC, | ||||
| 	0x2749, | ||||
| 	0x26B9, | ||||
| 	0x262B, | ||||
| 	0x259F, | ||||
| 	0x2515, | ||||
| 	0x248D, | ||||
| 	0x2407, | ||||
| 	0x2382, | ||||
| 	0x2300, | ||||
| 	0x2280, | ||||
| 	0x2201, | ||||
| 	0x2184, | ||||
| 	0x2109, | ||||
| 	0x2090, | ||||
| 	0x2018, | ||||
| 	0x1FA3, | ||||
| 	0x1F2E, | ||||
| 	0x1EBC, | ||||
| 	0x1E4B, | ||||
| 	0x1DDC, | ||||
| 	0x1D6E, | ||||
| 	0x1D02, | ||||
| 	0x1C98, | ||||
| 	0x1C2F, | ||||
| 	0x1BC8, | ||||
| 	0x1B62, | ||||
| 	0x1AFD, | ||||
| 	0x1A9A, | ||||
| 	0x1A38, | ||||
| 	0x19D8, | ||||
| 	0x1979, | ||||
| 	0x191C, | ||||
| 	0x18C0, | ||||
| 	0x1865, | ||||
| 	0x180B, | ||||
| 	0x17B3, | ||||
| 	0x175C, | ||||
| 	0x1706, | ||||
| 	0x16B2, | ||||
| 	0x165E, | ||||
| 	0x160C, | ||||
| 	0x15BB, | ||||
| 	0x156C, | ||||
| 	0x151D, | ||||
| 	0x14CF, | ||||
| 	0x1483, | ||||
| 	0x1438, | ||||
| 	0x13EE, | ||||
| 	0x13A4, | ||||
| 	0x135C, | ||||
| 	0x1315, | ||||
| 	0x12CF, | ||||
| 	0x128A, | ||||
| 	0x1246, | ||||
| 	0x1203, | ||||
| 	0x11C1, | ||||
| 	0x1180, | ||||
| 	0x1140, | ||||
| 	0x1100, | ||||
| 	0x10C2, | ||||
| 	0x1084, | ||||
| 	0x1048, | ||||
| 	0x100C, | ||||
| 	0xFD1, | ||||
| 	0xF97, | ||||
| 	0xF5E, | ||||
| 	0xF25, | ||||
| 	0xEEE, | ||||
| 	0xEB7, | ||||
| 	0xE81, | ||||
| 	0xE4C, | ||||
| 	0xE17, | ||||
| 	0xDE4, | ||||
| 	0xDB1, | ||||
| 	0xD7E, | ||||
| 	0xD4D, | ||||
| 	0xD1C, | ||||
| 	0xCEC, | ||||
| 	0xCBC, | ||||
| 	0xC8E, | ||||
| 	0xC60, | ||||
| 	0xC32, | ||||
| 	0xC05, | ||||
| 	0xBD9, | ||||
| 	0xBAE, | ||||
| 	0xB83, | ||||
| 	0xB59, | ||||
| 	0xB2F, | ||||
| 	0xB06, | ||||
| 	0xADD, | ||||
| 	0xAB6, | ||||
| 	0xA8E, | ||||
| 	0xA67, | ||||
| 	0xA41, | ||||
| 	0xA1C, | ||||
| 	0x9F7, | ||||
| 	0x9D2, | ||||
| 	0x9AE, | ||||
| 	0x98A, | ||||
| 	0x967, | ||||
| 	0x945, | ||||
| 	0x923, | ||||
| 	0x901, | ||||
| 	0x8E0, | ||||
| 	0x8C0, | ||||
| 	0x8A0, | ||||
| 	0x880, | ||||
| 	0x861, | ||||
| 	0x842, | ||||
| 	0x824, | ||||
| 	0x806, | ||||
| 	0x7E8, | ||||
| 	0x7CB, | ||||
| 	0x7AF, | ||||
| 	0x792, | ||||
| 	0x777, | ||||
| 	0x75B, | ||||
| 	0x740, | ||||
| 	0x726, | ||||
| 	0x70B, | ||||
| 	0x6F2, | ||||
| 	0x6D8, | ||||
| 	0x6BF, | ||||
| 	0x6A6, | ||||
| 	0x68E, | ||||
| 	0x676, | ||||
| 	0x65E, | ||||
| 	0x647, | ||||
| 	0x630, | ||||
| 	0x619, | ||||
| 	0x602, | ||||
| 	0x5EC, | ||||
| 	0x5D7, | ||||
| 	0x5C1, | ||||
| 	0x5AC, | ||||
| 	0x597, | ||||
| 	0x583, | ||||
| 	0x56E, | ||||
| 	0x55B, | ||||
| 	0x547, | ||||
| 	0x533, | ||||
| 	0x520, | ||||
| 	0x50E, | ||||
| 	0x4FB, | ||||
| 	0x4E9, | ||||
| 	0x4D7, | ||||
| 	0x4C5, | ||||
| 	0x4B3, | ||||
| 	0x4A2, | ||||
| 	0x491, | ||||
| 	0x480, | ||||
| 	0x470, | ||||
| 	0x460, | ||||
| 	0x450, | ||||
| 	0x440, | ||||
| 	0x430, | ||||
| 	0x421, | ||||
| 	0x412, | ||||
| 	0x403, | ||||
| 	0x3F4, | ||||
| 	0x3E5, | ||||
| 	0x3D7, | ||||
| 	0x3C9, | ||||
| 	0x3BB, | ||||
| 	0x3AD, | ||||
| 	0x3A0, | ||||
| 	0x393, | ||||
| 	0x385, | ||||
| 	0x379, | ||||
| 	0x36C, | ||||
| 	0x35F, | ||||
| 	0x353, | ||||
| 	0x347, | ||||
| 	0x33B, | ||||
| 	0x32F, | ||||
| 	0x323, | ||||
| 	0x318, | ||||
| 	0x30C, | ||||
| 	0x301, | ||||
| 	0x2F6, | ||||
| 	0x2EB, | ||||
| 	0x2E0, | ||||
| 	0x2D6, | ||||
| 	0x2CB, | ||||
| 	0x2C1, | ||||
| 	0x2B7, | ||||
| 	0x2AD, | ||||
| 	0x2A3, | ||||
| 	0x299, | ||||
| 	0x290, | ||||
| 	0x287, | ||||
| 	0x27D, | ||||
| 	0x274, | ||||
| 	0x26B, | ||||
| 	0x262, | ||||
| 	0x259, | ||||
| 	0x251, | ||||
| 	0x248, | ||||
| 	0x240, | ||||
| 	0x238, | ||||
| 	0x230, | ||||
| 	0x228, | ||||
| 	0x220, | ||||
| 	0x218, | ||||
| 	0x210, | ||||
| 	0x209, | ||||
| 	0x201, | ||||
| 	0x1FA, | ||||
| 	0x1F2, | ||||
| 	0x1EB, | ||||
| 	0x1E4, | ||||
| 	0x1DD, | ||||
| 	0x1D6, | ||||
| 	0x1D0, | ||||
| 	0x1C9, | ||||
| 	0x1C2, | ||||
| 	0x1BC, | ||||
| 	0x1B6, | ||||
| 	0x1AF, | ||||
| 	0x1A9, | ||||
| 	0x1A3, | ||||
| 	0x19D, | ||||
| 	0x197, | ||||
| 	0x191, | ||||
| 	0x18C, | ||||
| 	0x186, | ||||
| 	0x180, | ||||
| 	0x17B, | ||||
| 	0x175, | ||||
| 	0x170, | ||||
| 	0x16B, | ||||
| 	0x165, | ||||
| 	0x160, | ||||
| 	0x15B, | ||||
| 	0x156, | ||||
| 	0x151, | ||||
| 	0x14C, | ||||
| 	0x148, | ||||
| 	0x143, | ||||
| 	0x13E, | ||||
| 	0x13A, | ||||
| 	0x135, | ||||
| 	0x131, | ||||
| 	0x12C, | ||||
| 	0x128, | ||||
| 	0x124, | ||||
| 	0x120, | ||||
| 	0x11C, | ||||
| 	0x118, | ||||
| 	0x114, | ||||
| 	0x110, | ||||
| 	0x10C, | ||||
| 	0x108, | ||||
| 	0x104, | ||||
| 	0x100, | ||||
| 	0xFD, | ||||
| 	0xF9, | ||||
| 	0xF5, | ||||
| 	0xF2, | ||||
| 	0xEE, | ||||
| const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] = { | ||||
|     0x8E0B, 0x8C02, 0x8A00, 0x8805, 0x8612, 0x8426, 0x8241, 0x8063, 0x7E8C, 0x7CBB, 0x7AF2, 0x792E, 0x7772, 0x75BB, 0x740B, 0x7261, 0x70BD, 0x6F20, 0x6D88, 0x6BF6, 0x6A69, 0x68E3, 0x6762, 0x65E6, 0x6470, 0x6300, 0x6194, 0x602E, 0x5ECD, 0x5D71, 0x5C1A, 0x5AC8, 0x597B, 0x5833, 0x56EF, 0x55B0, 0x5475, 0x533F, 0x520E, 0x50E1, 0x4FB8, 0x4E93, 0x4D73, 0x4C57, 0x4B3E, 0x4A2A, 0x491A, 0x480E, 0x4705, 0x4601, 0x4500, 0x4402, 0x4309, 0x4213, 0x4120, 0x4031, 0x3F46, 0x3E5D, 0x3D79, 0x3C97, 0x3BB9, 0x3ADD, 0x3A05, 0x3930, 0x385E, 0x3790, 0x36C4, 0x35FB, 0x3534, 0x3471, 0x33B1, 0x32F3, 0x3238, 0x3180, 0x30CA, 0x3017, 0x2F66, 0x2EB8, 0x2E0D, 0x2D64, 0x2CBD, 0x2C19, 0x2B77, 0x2AD8, 0x2A3A, 0x299F, 0x2907, 0x2870, 0x27DC, 0x2749, 0x26B9, 0x262B, 0x259F, 0x2515, 0x248D, 0x2407, 0x2382, 0x2300, 0x2280, 0x2201, 0x2184, 0x2109, 0x2090, 0x2018, 0x1FA3, 0x1F2E, 0x1EBC, 0x1E4B, 0x1DDC, 0x1D6E, 0x1D02, 0x1C98, 0x1C2F, 0x1BC8, 0x1B62, 0x1AFD, 0x1A9A, | ||||
|     0x1A38, 0x19D8, 0x1979, 0x191C, 0x18C0, 0x1865, 0x180B, 0x17B3, 0x175C, 0x1706, 0x16B2, 0x165E, 0x160C, 0x15BB, 0x156C, 0x151D, 0x14CF, 0x1483, 0x1438, 0x13EE, 0x13A4, 0x135C, 0x1315, 0x12CF, 0x128A, 0x1246, 0x1203, 0x11C1, 0x1180, 0x1140, 0x1100, 0x10C2, 0x1084, 0x1048, 0x100C, 0xFD1,  0xF97,  0xF5E,  0xF25,  0xEEE,  0xEB7,  0xE81,  0xE4C,  0xE17,  0xDE4,  0xDB1,  0xD7E,  0xD4D,  0xD1C,  0xCEC,  0xCBC,  0xC8E,  0xC60,  0xC32,  0xC05,  0xBD9,  0xBAE,  0xB83,  0xB59,  0xB2F,  0xB06,  0xADD,  0xAB6,  0xA8E,  0xA67,  0xA41,  0xA1C,  0x9F7,  0x9D2,  0x9AE,  0x98A,  0x967,  0x945,  0x923,  0x901,  0x8E0,  0x8C0,  0x8A0,  0x880,  0x861,  0x842,  0x824,  0x806,  0x7E8,  0x7CB,  0x7AF,  0x792,  0x777,  0x75B,  0x740,  0x726,  0x70B,  0x6F2,  0x6D8,  0x6BF,  0x6A6,  0x68E,  0x676,  0x65E,  0x647,  0x630,  0x619,  0x602,  0x5EC,  0x5D7,  0x5C1,  0x5AC,  0x597,  0x583,  0x56E,  0x55B,  0x547,  0x533,  0x520,  0x50E,  0x4FB,  0x4E9, | ||||
|     0x4D7,  0x4C5,  0x4B3,  0x4A2,  0x491,  0x480,  0x470,  0x460,  0x450,  0x440,  0x430,  0x421,  0x412,  0x403,  0x3F4,  0x3E5,  0x3D7,  0x3C9,  0x3BB,  0x3AD,  0x3A0,  0x393,  0x385,  0x379,  0x36C,  0x35F,  0x353,  0x347,  0x33B,  0x32F,  0x323,  0x318,  0x30C,  0x301,  0x2F6,  0x2EB,  0x2E0,  0x2D6,  0x2CB,  0x2C1,  0x2B7,  0x2AD,  0x2A3,  0x299,  0x290,  0x287,  0x27D,  0x274,  0x26B,  0x262,  0x259,  0x251,  0x248,  0x240,  0x238,  0x230,  0x228,  0x220,  0x218,  0x210,  0x209,  0x201,  0x1FA,  0x1F2,  0x1EB,  0x1E4,  0x1DD,  0x1D6,  0x1D0,  0x1C9,  0x1C2,  0x1BC,  0x1B6,  0x1AF,  0x1A9,  0x1A3,  0x19D,  0x197,  0x191,  0x18C,  0x186,  0x180,  0x17B,  0x175,  0x170,  0x16B,  0x165,  0x160,  0x15B,  0x156,  0x151,  0x14C,  0x148,  0x143,  0x13E,  0x13A,  0x135,  0x131,  0x12C,  0x128,  0x124,  0x120,  0x11C,  0x118,  0x114,  0x110,  0x10C,  0x108,  0x104,  0x100,  0xFD,   0xF9,   0xF5,   0xF2,   0xEE, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,22 +15,22 @@ | |||
|  */ | ||||
| 
 | ||||
| #if defined(__AVR__) | ||||
|     #include <avr/io.h> | ||||
|     #include <avr/interrupt.h> | ||||
|     #include <avr/pgmspace.h> | ||||
| #    include <avr/io.h> | ||||
| #    include <avr/interrupt.h> | ||||
| #    include <avr/pgmspace.h> | ||||
| #else | ||||
|     #include "ch.h" | ||||
|     #include "hal.h" | ||||
| #    include "ch.h" | ||||
| #    include "hal.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef LUTS_H | ||||
| #define LUTS_H | ||||
| #    define LUTS_H | ||||
| 
 | ||||
| #define VIBRATO_LUT_LENGTH 20 | ||||
| #    define VIBRATO_LUT_LENGTH 20 | ||||
| 
 | ||||
| #define FREQUENCY_LUT_LENGTH 349 | ||||
| #    define FREQUENCY_LUT_LENGTH 349 | ||||
| 
 | ||||
| extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; | ||||
| extern const float    vibrato_lut[VIBRATO_LUT_LENGTH]; | ||||
| extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; | ||||
| 
 | ||||
| #endif /* LUTS_H */ | ||||
|  |  | |||
|  | @ -1,111 +1,56 @@ | |||
| #include "muse.h" | ||||
| 
 | ||||
| enum { | ||||
|   MUSE_OFF, | ||||
|   MUSE_ON, | ||||
|   MUSE_C_1_2, | ||||
|   MUSE_C1, | ||||
|   MUSE_C2, | ||||
|   MUSE_C4, | ||||
|   MUSE_C8, | ||||
|   MUSE_C3, | ||||
|   MUSE_C6, | ||||
|   MUSE_B1, | ||||
|   MUSE_B2, | ||||
|   MUSE_B3, | ||||
|   MUSE_B4, | ||||
|   MUSE_B5, | ||||
|   MUSE_B6, | ||||
|   MUSE_B7, | ||||
|   MUSE_B8, | ||||
|   MUSE_B9, | ||||
|   MUSE_B10, | ||||
|   MUSE_B11, | ||||
|   MUSE_B12, | ||||
|   MUSE_B13, | ||||
|   MUSE_B14, | ||||
|   MUSE_B15, | ||||
|   MUSE_B16, | ||||
|   MUSE_B17, | ||||
|   MUSE_B18, | ||||
|   MUSE_B19, | ||||
|   MUSE_B20, | ||||
|   MUSE_B21, | ||||
|   MUSE_B22, | ||||
|   MUSE_B23, | ||||
|   MUSE_B24, | ||||
|   MUSE_B25, | ||||
|   MUSE_B26, | ||||
|   MUSE_B27, | ||||
|   MUSE_B28, | ||||
|   MUSE_B29, | ||||
|   MUSE_B30, | ||||
|   MUSE_B31 | ||||
| }; | ||||
| enum { MUSE_OFF, MUSE_ON, MUSE_C_1_2, MUSE_C1, MUSE_C2, MUSE_C4, MUSE_C8, MUSE_C3, MUSE_C6, MUSE_B1, MUSE_B2, MUSE_B3, MUSE_B4, MUSE_B5, MUSE_B6, MUSE_B7, MUSE_B8, MUSE_B9, MUSE_B10, MUSE_B11, MUSE_B12, MUSE_B13, MUSE_B14, MUSE_B15, MUSE_B16, MUSE_B17, MUSE_B18, MUSE_B19, MUSE_B20, MUSE_B21, MUSE_B22, MUSE_B23, MUSE_B24, MUSE_B25, MUSE_B26, MUSE_B27, MUSE_B28, MUSE_B29, MUSE_B30, MUSE_B31 }; | ||||
| 
 | ||||
| bool number_of_ones_to_bool[16] = { | ||||
|   1, 0, 0, 1, 0, 1, 1, 0, | ||||
|   0, 1, 1, 0, 1, 0, 0, 1 | ||||
| }; | ||||
| bool number_of_ones_to_bool[16] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; | ||||
| 
 | ||||
| uint8_t muse_interval[4] = {MUSE_B7,  MUSE_B19, MUSE_B3,  MUSE_B28}; | ||||
| uint8_t muse_interval[4] = {MUSE_B7, MUSE_B19, MUSE_B3, MUSE_B28}; | ||||
| uint8_t muse_theme[4]    = {MUSE_B8, MUSE_B23, MUSE_B18, MUSE_B17}; | ||||
| 
 | ||||
| bool muse_timer_1bit = 0; | ||||
| uint8_t muse_timer_2bit = 0; | ||||
| uint8_t muse_timer_2bit_counter = 0; | ||||
| uint8_t muse_timer_4bit = 0; | ||||
| uint32_t muse_timer_31bit = 0; | ||||
| bool     muse_timer_1bit         = 0; | ||||
| uint8_t  muse_timer_2bit         = 0; | ||||
| uint8_t  muse_timer_2bit_counter = 0; | ||||
| uint8_t  muse_timer_4bit         = 0; | ||||
| uint32_t muse_timer_31bit        = 0; | ||||
| 
 | ||||
| bool bit_for_value(uint8_t value) { | ||||
|   switch (value) { | ||||
|     case MUSE_OFF: | ||||
|       return 0; | ||||
|     case MUSE_ON: | ||||
|       return 1; | ||||
|     case MUSE_C_1_2: | ||||
|       return muse_timer_1bit; | ||||
|     case MUSE_C1: | ||||
|       return (muse_timer_4bit & 1); | ||||
|     case MUSE_C2: | ||||
|       return (muse_timer_4bit & 2); | ||||
|     case MUSE_C4: | ||||
|       return (muse_timer_4bit & 4); | ||||
|     case MUSE_C8: | ||||
|       return (muse_timer_4bit & 8); | ||||
|     case MUSE_C3: | ||||
|       return (muse_timer_2bit & 1); | ||||
|     case MUSE_C6: | ||||
|       return (muse_timer_2bit & 2); | ||||
|     default: | ||||
|       return muse_timer_31bit & (1UL << (value - MUSE_B1)); | ||||
|   } | ||||
|     switch (value) { | ||||
|         case MUSE_OFF: | ||||
|             return 0; | ||||
|         case MUSE_ON: | ||||
|             return 1; | ||||
|         case MUSE_C_1_2: | ||||
|             return muse_timer_1bit; | ||||
|         case MUSE_C1: | ||||
|             return (muse_timer_4bit & 1); | ||||
|         case MUSE_C2: | ||||
|             return (muse_timer_4bit & 2); | ||||
|         case MUSE_C4: | ||||
|             return (muse_timer_4bit & 4); | ||||
|         case MUSE_C8: | ||||
|             return (muse_timer_4bit & 8); | ||||
|         case MUSE_C3: | ||||
|             return (muse_timer_2bit & 1); | ||||
|         case MUSE_C6: | ||||
|             return (muse_timer_2bit & 2); | ||||
|         default: | ||||
|             return muse_timer_31bit & (1UL << (value - MUSE_B1)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint8_t muse_clock_pulse(void) { | ||||
|     bool top = number_of_ones_to_bool[bit_for_value(muse_theme[0]) + (bit_for_value(muse_theme[1]) << 1) + (bit_for_value(muse_theme[2]) << 2) + (bit_for_value(muse_theme[3]) << 3)]; | ||||
| 
 | ||||
|   bool top = number_of_ones_to_bool[ | ||||
|     bit_for_value(muse_theme[0]) + | ||||
|     (bit_for_value(muse_theme[1]) << 1) + | ||||
|     (bit_for_value(muse_theme[2]) << 2) + | ||||
|     (bit_for_value(muse_theme[3]) << 3) | ||||
|   ]; | ||||
| 
 | ||||
|   if (muse_timer_1bit == 0) { | ||||
|     if (muse_timer_2bit_counter == 0) { | ||||
|       muse_timer_2bit = (muse_timer_2bit + 1) % 4; | ||||
|     if (muse_timer_1bit == 0) { | ||||
|         if (muse_timer_2bit_counter == 0) { | ||||
|             muse_timer_2bit = (muse_timer_2bit + 1) % 4; | ||||
|         } | ||||
|         muse_timer_2bit_counter = (muse_timer_2bit_counter + 1) % 3; | ||||
|         muse_timer_4bit         = (muse_timer_4bit + 1) % 16; | ||||
|         muse_timer_31bit        = (muse_timer_31bit << 1) + top; | ||||
|     } | ||||
|     muse_timer_2bit_counter = (muse_timer_2bit_counter + 1) % 3; | ||||
|     muse_timer_4bit = (muse_timer_4bit + 1) % 16; | ||||
|     muse_timer_31bit = (muse_timer_31bit << 1) + top; | ||||
|   } | ||||
| 
 | ||||
|   muse_timer_1bit = (muse_timer_1bit + 1) % 2; | ||||
| 
 | ||||
|   return | ||||
|     bit_for_value(muse_interval[0]) + | ||||
|     (bit_for_value(muse_interval[1]) << 1) + | ||||
|     (bit_for_value(muse_interval[2]) << 2) + | ||||
|     (bit_for_value(muse_interval[3]) << 3); | ||||
|     muse_timer_1bit = (muse_timer_1bit + 1) % 2; | ||||
| 
 | ||||
|     return bit_for_value(muse_interval[0]) + (bit_for_value(muse_interval[1]) << 1) + (bit_for_value(muse_interval[2]) << 2) + (bit_for_value(muse_interval[3]) << 3); | ||||
| } | ||||
|  |  | |||
|  | @ -20,55 +20,55 @@ | |||
| // Tempo Placeholder
 | ||||
| #define TEMPO_DEFAULT 100 | ||||
| 
 | ||||
| 
 | ||||
| #define SONG(notes...) { notes } | ||||
| 
 | ||||
| #define SONG(notes...) \ | ||||
|     { notes } | ||||
| 
 | ||||
| // Note Types
 | ||||
| #define MUSICAL_NOTE(note, duration)   {(NOTE##note), duration} | ||||
| #define BREVE_NOTE(note)               MUSICAL_NOTE(note, 128) | ||||
| #define WHOLE_NOTE(note)               MUSICAL_NOTE(note, 64) | ||||
| #define HALF_NOTE(note)                MUSICAL_NOTE(note, 32) | ||||
| #define QUARTER_NOTE(note)             MUSICAL_NOTE(note, 16) | ||||
| #define EIGHTH_NOTE(note)              MUSICAL_NOTE(note,  8) | ||||
| #define SIXTEENTH_NOTE(note)           MUSICAL_NOTE(note,  4) | ||||
| #define MUSICAL_NOTE(note, duration) \ | ||||
|     { (NOTE##note), duration } | ||||
| #define BREVE_NOTE(note) MUSICAL_NOTE(note, 128) | ||||
| #define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) | ||||
| #define HALF_NOTE(note) MUSICAL_NOTE(note, 32) | ||||
| #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) | ||||
| #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) | ||||
| #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) | ||||
| 
 | ||||
| #define BREVE_DOT_NOTE(note)           MUSICAL_NOTE(note, 128+64) | ||||
| #define WHOLE_DOT_NOTE(note)           MUSICAL_NOTE(note, 64+32) | ||||
| #define HALF_DOT_NOTE(note)            MUSICAL_NOTE(note, 32+16) | ||||
| #define QUARTER_DOT_NOTE(note)         MUSICAL_NOTE(note, 16+8) | ||||
| #define EIGHTH_DOT_NOTE(note)          MUSICAL_NOTE(note,  8+4) | ||||
| #define SIXTEENTH_DOT_NOTE(note)       MUSICAL_NOTE(note,  4+2) | ||||
| #define BREVE_DOT_NOTE(note) MUSICAL_NOTE(note, 128 + 64) | ||||
| #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64 + 32) | ||||
| #define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32 + 16) | ||||
| #define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16 + 8) | ||||
| #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8 + 4) | ||||
| #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4 + 2) | ||||
| 
 | ||||
| // Note Type Shortcuts
 | ||||
| #define M__NOTE(note, duration)        MUSICAL_NOTE(note, duration) | ||||
| #define B__NOTE(n)                     BREVE_NOTE(n) | ||||
| #define W__NOTE(n)                     WHOLE_NOTE(n) | ||||
| #define H__NOTE(n)                     HALF_NOTE(n) | ||||
| #define Q__NOTE(n)                     QUARTER_NOTE(n) | ||||
| #define E__NOTE(n)                     EIGHTH_NOTE(n) | ||||
| #define S__NOTE(n)                     SIXTEENTH_NOTE(n) | ||||
| #define BD_NOTE(n)                     BREVE_DOT_NOTE(n) | ||||
| #define WD_NOTE(n)                     WHOLE_DOT_NOTE(n) | ||||
| #define HD_NOTE(n)                     HALF_DOT_NOTE(n) | ||||
| #define QD_NOTE(n)                     QUARTER_DOT_NOTE(n) | ||||
| #define ED_NOTE(n)                     EIGHTH_DOT_NOTE(n) | ||||
| #define SD_NOTE(n)                     SIXTEENTH_DOT_NOTE(n) | ||||
| #define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) | ||||
| #define B__NOTE(n) BREVE_NOTE(n) | ||||
| #define W__NOTE(n) WHOLE_NOTE(n) | ||||
| #define H__NOTE(n) HALF_NOTE(n) | ||||
| #define Q__NOTE(n) QUARTER_NOTE(n) | ||||
| #define E__NOTE(n) EIGHTH_NOTE(n) | ||||
| #define S__NOTE(n) SIXTEENTH_NOTE(n) | ||||
| #define BD_NOTE(n) BREVE_DOT_NOTE(n) | ||||
| #define WD_NOTE(n) WHOLE_DOT_NOTE(n) | ||||
| #define HD_NOTE(n) HALF_DOT_NOTE(n) | ||||
| #define QD_NOTE(n) QUARTER_DOT_NOTE(n) | ||||
| #define ED_NOTE(n) EIGHTH_DOT_NOTE(n) | ||||
| #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) | ||||
| 
 | ||||
| // Note Timbre
 | ||||
| // Changes how the notes sound
 | ||||
| #define TIMBRE_12       0.125f | ||||
| #define TIMBRE_25       0.250f | ||||
| #define TIMBRE_50       0.500f | ||||
| #define TIMBRE_75       0.750f | ||||
| #define TIMBRE_DEFAULT  TIMBRE_50 | ||||
| #define TIMBRE_12 0.125f | ||||
| #define TIMBRE_25 0.250f | ||||
| #define TIMBRE_50 0.500f | ||||
| #define TIMBRE_75 0.750f | ||||
| #define TIMBRE_DEFAULT TIMBRE_50 | ||||
| 
 | ||||
| // Notes - # = Octave
 | ||||
| 
 | ||||
| #ifdef __arm__ | ||||
| #define NOTE_REST         1.00f | ||||
| #    define NOTE_REST 1.00f | ||||
| #else | ||||
| #define NOTE_REST         0.00f | ||||
| #    define NOTE_REST 0.00f | ||||
| #endif | ||||
| 
 | ||||
| /* These notes are currently bugged
 | ||||
|  | @ -97,91 +97,91 @@ | |||
| #define NOTE_AS1         58.27f | ||||
| */ | ||||
| 
 | ||||
| #define NOTE_B1          61.74f | ||||
| #define NOTE_C2          65.41f | ||||
| #define NOTE_CS2         69.30f | ||||
| #define NOTE_D2          73.42f | ||||
| #define NOTE_DS2         77.78f | ||||
| #define NOTE_E2          82.41f | ||||
| #define NOTE_F2          87.31f | ||||
| #define NOTE_FS2         92.50f | ||||
| #define NOTE_G2          98.00f | ||||
| #define NOTE_GS2        103.83f | ||||
| #define NOTE_A2         110.00f | ||||
| #define NOTE_AS2        116.54f | ||||
| #define NOTE_B2         123.47f | ||||
| #define NOTE_C3         130.81f | ||||
| #define NOTE_CS3        138.59f | ||||
| #define NOTE_D3         146.83f | ||||
| #define NOTE_DS3        155.56f | ||||
| #define NOTE_E3         164.81f | ||||
| #define NOTE_F3         174.61f | ||||
| #define NOTE_FS3        185.00f | ||||
| #define NOTE_G3         196.00f | ||||
| #define NOTE_GS3        207.65f | ||||
| #define NOTE_A3         220.00f | ||||
| #define NOTE_AS3        233.08f | ||||
| #define NOTE_B3         246.94f | ||||
| #define NOTE_C4         261.63f | ||||
| #define NOTE_CS4        277.18f | ||||
| #define NOTE_D4         293.66f | ||||
| #define NOTE_DS4        311.13f | ||||
| #define NOTE_E4         329.63f | ||||
| #define NOTE_F4         349.23f | ||||
| #define NOTE_FS4        369.99f | ||||
| #define NOTE_G4         392.00f | ||||
| #define NOTE_GS4        415.30f | ||||
| #define NOTE_A4         440.00f | ||||
| #define NOTE_AS4        466.16f | ||||
| #define NOTE_B4         493.88f | ||||
| #define NOTE_C5         523.25f | ||||
| #define NOTE_CS5        554.37f | ||||
| #define NOTE_D5         587.33f | ||||
| #define NOTE_DS5        622.25f | ||||
| #define NOTE_E5         659.26f | ||||
| #define NOTE_F5         698.46f | ||||
| #define NOTE_FS5        739.99f | ||||
| #define NOTE_G5         783.99f | ||||
| #define NOTE_GS5        830.61f | ||||
| #define NOTE_A5         880.00f | ||||
| #define NOTE_AS5        932.33f | ||||
| #define NOTE_B5         987.77f | ||||
| #define NOTE_C6        1046.50f | ||||
| #define NOTE_CS6       1108.73f | ||||
| #define NOTE_D6        1174.66f | ||||
| #define NOTE_DS6       1244.51f | ||||
| #define NOTE_E6        1318.51f | ||||
| #define NOTE_F6        1396.91f | ||||
| #define NOTE_FS6       1479.98f | ||||
| #define NOTE_G6        1567.98f | ||||
| #define NOTE_GS6       1661.22f | ||||
| #define NOTE_A6        1760.00f | ||||
| #define NOTE_AS6       1864.66f | ||||
| #define NOTE_B6        1975.53f | ||||
| #define NOTE_C7        2093.00f | ||||
| #define NOTE_CS7       2217.46f | ||||
| #define NOTE_D7        2349.32f | ||||
| #define NOTE_DS7       2489.02f | ||||
| #define NOTE_E7        2637.02f | ||||
| #define NOTE_F7        2793.83f | ||||
| #define NOTE_FS7       2959.96f | ||||
| #define NOTE_G7        3135.96f | ||||
| #define NOTE_GS7       3322.44f | ||||
| #define NOTE_A7        3520.00f | ||||
| #define NOTE_AS7       3729.31f | ||||
| #define NOTE_B7        3951.07f | ||||
| #define NOTE_C8        4186.01f | ||||
| #define NOTE_CS8       4434.92f | ||||
| #define NOTE_D8        4698.64f | ||||
| #define NOTE_DS8       4978.03f | ||||
| #define NOTE_E8        5274.04f | ||||
| #define NOTE_F8        5587.65f | ||||
| #define NOTE_FS8       5919.91f | ||||
| #define NOTE_G8        6271.93f | ||||
| #define NOTE_GS8       6644.88f | ||||
| #define NOTE_A8        7040.00f | ||||
| #define NOTE_AS8       7458.62f | ||||
| #define NOTE_B8        7902.13f | ||||
| #define NOTE_B1 61.74f | ||||
| #define NOTE_C2 65.41f | ||||
| #define NOTE_CS2 69.30f | ||||
| #define NOTE_D2 73.42f | ||||
| #define NOTE_DS2 77.78f | ||||
| #define NOTE_E2 82.41f | ||||
| #define NOTE_F2 87.31f | ||||
| #define NOTE_FS2 92.50f | ||||
| #define NOTE_G2 98.00f | ||||
| #define NOTE_GS2 103.83f | ||||
| #define NOTE_A2 110.00f | ||||
| #define NOTE_AS2 116.54f | ||||
| #define NOTE_B2 123.47f | ||||
| #define NOTE_C3 130.81f | ||||
| #define NOTE_CS3 138.59f | ||||
| #define NOTE_D3 146.83f | ||||
| #define NOTE_DS3 155.56f | ||||
| #define NOTE_E3 164.81f | ||||
| #define NOTE_F3 174.61f | ||||
| #define NOTE_FS3 185.00f | ||||
| #define NOTE_G3 196.00f | ||||
| #define NOTE_GS3 207.65f | ||||
| #define NOTE_A3 220.00f | ||||
| #define NOTE_AS3 233.08f | ||||
| #define NOTE_B3 246.94f | ||||
| #define NOTE_C4 261.63f | ||||
| #define NOTE_CS4 277.18f | ||||
| #define NOTE_D4 293.66f | ||||
| #define NOTE_DS4 311.13f | ||||
| #define NOTE_E4 329.63f | ||||
| #define NOTE_F4 349.23f | ||||
| #define NOTE_FS4 369.99f | ||||
| #define NOTE_G4 392.00f | ||||
| #define NOTE_GS4 415.30f | ||||
| #define NOTE_A4 440.00f | ||||
| #define NOTE_AS4 466.16f | ||||
| #define NOTE_B4 493.88f | ||||
| #define NOTE_C5 523.25f | ||||
| #define NOTE_CS5 554.37f | ||||
| #define NOTE_D5 587.33f | ||||
| #define NOTE_DS5 622.25f | ||||
| #define NOTE_E5 659.26f | ||||
| #define NOTE_F5 698.46f | ||||
| #define NOTE_FS5 739.99f | ||||
| #define NOTE_G5 783.99f | ||||
| #define NOTE_GS5 830.61f | ||||
| #define NOTE_A5 880.00f | ||||
| #define NOTE_AS5 932.33f | ||||
| #define NOTE_B5 987.77f | ||||
| #define NOTE_C6 1046.50f | ||||
| #define NOTE_CS6 1108.73f | ||||
| #define NOTE_D6 1174.66f | ||||
| #define NOTE_DS6 1244.51f | ||||
| #define NOTE_E6 1318.51f | ||||
| #define NOTE_F6 1396.91f | ||||
| #define NOTE_FS6 1479.98f | ||||
| #define NOTE_G6 1567.98f | ||||
| #define NOTE_GS6 1661.22f | ||||
| #define NOTE_A6 1760.00f | ||||
| #define NOTE_AS6 1864.66f | ||||
| #define NOTE_B6 1975.53f | ||||
| #define NOTE_C7 2093.00f | ||||
| #define NOTE_CS7 2217.46f | ||||
| #define NOTE_D7 2349.32f | ||||
| #define NOTE_DS7 2489.02f | ||||
| #define NOTE_E7 2637.02f | ||||
| #define NOTE_F7 2793.83f | ||||
| #define NOTE_FS7 2959.96f | ||||
| #define NOTE_G7 3135.96f | ||||
| #define NOTE_GS7 3322.44f | ||||
| #define NOTE_A7 3520.00f | ||||
| #define NOTE_AS7 3729.31f | ||||
| #define NOTE_B7 3951.07f | ||||
| #define NOTE_C8 4186.01f | ||||
| #define NOTE_CS8 4434.92f | ||||
| #define NOTE_D8 4698.64f | ||||
| #define NOTE_DS8 4978.03f | ||||
| #define NOTE_E8 5274.04f | ||||
| #define NOTE_F8 5587.65f | ||||
| #define NOTE_FS8 5919.91f | ||||
| #define NOTE_G8 6271.93f | ||||
| #define NOTE_GS8 6644.88f | ||||
| #define NOTE_A8 7040.00f | ||||
| #define NOTE_AS8 7458.62f | ||||
| #define NOTE_B8 7902.13f | ||||
| 
 | ||||
| // Flat Aliases
 | ||||
| #define NOTE_DF0 NOTE_CS0 | ||||
|  | @ -230,5 +230,4 @@ | |||
| #define NOTE_AF8 NOTE_GS8 | ||||
| #define NOTE_BF8 NOTE_AS8 | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -26,25 +26,15 @@ | |||
|  * Author: Friedrich Schiller | ||||
|  + License: Public Domain | ||||
|  */ | ||||
| #define ODE_TO_JOY                                          \ | ||||
|     Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ | ||||
|     Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ | ||||
|     Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ | ||||
|     QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), | ||||
| #define ODE_TO_JOY Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), | ||||
| 
 | ||||
| /* Rock-a-bye Baby
 | ||||
|  * Author: Unknown | ||||
|  + License: Public Domain | ||||
|  */ | ||||
| #define ROCK_A_BYE_BABY                            \ | ||||
|     QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5),      \ | ||||
|     H__NOTE(_A5), Q__NOTE(_G5),                    \ | ||||
|     QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5),      \ | ||||
|     H__NOTE(_FS5), | ||||
| #define ROCK_A_BYE_BABY QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), H__NOTE(_A5), Q__NOTE(_G5), QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), H__NOTE(_FS5), | ||||
| 
 | ||||
| 
 | ||||
| #define CLUEBOARD_SOUND \ | ||||
|     HD_NOTE(_C3), HD_NOTE(_D3), HD_NOTE(_E3), HD_NOTE(_F3), HD_NOTE(_G3), HD_NOTE(_A4), HD_NOTE(_B4), HD_NOTE(_C4) | ||||
| #define CLUEBOARD_SOUND HD_NOTE(_C3), HD_NOTE(_D3), HD_NOTE(_E3), HD_NOTE(_F3), HD_NOTE(_G3), HD_NOTE(_A4), HD_NOTE(_B4), HD_NOTE(_C4) | ||||
| /*
 | ||||
|     HD_NOTE(_G3), HD_NOTE(_E3), HD_NOTE(_C3), \ | ||||
|     Q__NOTE(_E3), Q__NOTE(_C3), Q__NOTE(_G3), \ | ||||
|  | @ -56,258 +46,93 @@ | |||
|     Q__NOTE(_F3) | ||||
| */ | ||||
| 
 | ||||
| #define STARTUP_SOUND  \ | ||||
|     E__NOTE(_E6),     \ | ||||
|     E__NOTE(_A6),     \ | ||||
|     ED_NOTE(_E7), | ||||
| #define STARTUP_SOUND E__NOTE(_E6), E__NOTE(_A6), ED_NOTE(_E7), | ||||
| 
 | ||||
| #define GOODBYE_SOUND \ | ||||
|     E__NOTE(_E7),     \ | ||||
|     E__NOTE(_A6),     \ | ||||
|     ED_NOTE(_E6), | ||||
| #define GOODBYE_SOUND E__NOTE(_E7), E__NOTE(_A6), ED_NOTE(_E6), | ||||
| 
 | ||||
| #define PLANCK_SOUND  \ | ||||
|     ED_NOTE(_E7 ),     \ | ||||
|     E__NOTE(_CS7),     \ | ||||
|     E__NOTE(_E6 ),     \ | ||||
|     E__NOTE(_A6 ),     \ | ||||
|     M__NOTE(_CS7, 20), | ||||
| #define PLANCK_SOUND ED_NOTE(_E7), E__NOTE(_CS7), E__NOTE(_E6), E__NOTE(_A6), M__NOTE(_CS7, 20), | ||||
| 
 | ||||
| #define PREONIC_SOUND \ | ||||
|     M__NOTE(_B5, 20),  \ | ||||
|     E__NOTE(_B6),      \ | ||||
|     M__NOTE(_DS6, 20), \ | ||||
|     E__NOTE(_B6), | ||||
| #define PREONIC_SOUND M__NOTE(_B5, 20), E__NOTE(_B6), M__NOTE(_DS6, 20), E__NOTE(_B6), | ||||
| 
 | ||||
| #define QWERTY_SOUND \ | ||||
|     E__NOTE(_GS6 ),  \ | ||||
|     E__NOTE(_A6  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     Q__NOTE(_E7  ), | ||||
| #define QWERTY_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), Q__NOTE(_E7), | ||||
| 
 | ||||
| #define COLEMAK_SOUND \ | ||||
|     E__NOTE(_GS6 ),   \ | ||||
|     E__NOTE(_A6  ),   \ | ||||
|     S__NOTE(_REST),   \ | ||||
|     ED_NOTE(_E7  ),   \ | ||||
|     S__NOTE(_REST),   \ | ||||
|     ED_NOTE(_GS7 ), | ||||
| #define COLEMAK_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_E7), S__NOTE(_REST), ED_NOTE(_GS7), | ||||
| 
 | ||||
| #define DVORAK_SOUND \ | ||||
|     E__NOTE(_GS6 ),  \ | ||||
|     E__NOTE(_A6  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     E__NOTE(_E7  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     E__NOTE(_FS7 ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     E__NOTE(_E7  ), | ||||
| #define DVORAK_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), E__NOTE(_E7), S__NOTE(_REST), E__NOTE(_FS7), S__NOTE(_REST), E__NOTE(_E7), | ||||
| 
 | ||||
| #define WORKMAN_SOUND \ | ||||
|     E__NOTE(_GS6 ), \ | ||||
|     E__NOTE(_A6  ), \ | ||||
|     S__NOTE(_REST), \ | ||||
|     E__NOTE(_GS6 ), \ | ||||
|     E__NOTE(_A6  ), \ | ||||
|     S__NOTE(_REST), \ | ||||
|     ED_NOTE(_FS7  ), \ | ||||
|     S__NOTE(_REST), \ | ||||
|     ED_NOTE(_A7 ), | ||||
| #define WORKMAN_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_FS7), S__NOTE(_REST), ED_NOTE(_A7), | ||||
| 
 | ||||
| #define PLOVER_SOUND \ | ||||
|     E__NOTE(_GS6 ),  \ | ||||
|     E__NOTE(_A6  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     ED_NOTE(_E7  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     ED_NOTE(_A7  ), | ||||
| #define PLOVER_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_E7), S__NOTE(_REST), ED_NOTE(_A7), | ||||
| 
 | ||||
| #define PLOVER_GOODBYE_SOUND \ | ||||
|     E__NOTE(_GS6 ),  \ | ||||
|     E__NOTE(_A6  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     ED_NOTE(_A7  ),  \ | ||||
|     S__NOTE(_REST),  \ | ||||
|     ED_NOTE(_E7  ), | ||||
| #define PLOVER_GOODBYE_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_A7), S__NOTE(_REST), ED_NOTE(_E7), | ||||
| 
 | ||||
| #define MUSIC_ON_SOUND \ | ||||
|     E__NOTE(_A5 ),        \ | ||||
|     E__NOTE(_B5 ),        \ | ||||
|     E__NOTE(_CS6),        \ | ||||
|     E__NOTE(_D6 ),        \ | ||||
|     E__NOTE(_E6 ),        \ | ||||
|     E__NOTE(_FS6),        \ | ||||
|     E__NOTE(_GS6),        \ | ||||
|     E__NOTE(_A6 ), | ||||
| #define MUSIC_ON_SOUND E__NOTE(_A5), E__NOTE(_B5), E__NOTE(_CS6), E__NOTE(_D6), E__NOTE(_E6), E__NOTE(_FS6), E__NOTE(_GS6), E__NOTE(_A6), | ||||
| 
 | ||||
| #define AUDIO_ON_SOUND \ | ||||
|     E__NOTE(_A5 ),        \ | ||||
|     E__NOTE(_A6 ), | ||||
| #define AUDIO_ON_SOUND E__NOTE(_A5), E__NOTE(_A6), | ||||
| 
 | ||||
| #define AUDIO_OFF_SOUND \ | ||||
|     E__NOTE(_A6 ),        \ | ||||
|     E__NOTE(_A5 ), | ||||
| #define AUDIO_OFF_SOUND E__NOTE(_A6), E__NOTE(_A5), | ||||
| 
 | ||||
| #define MUSIC_SCALE_SOUND MUSIC_ON_SOUND | ||||
| 
 | ||||
| #define MUSIC_OFF_SOUND \ | ||||
|     E__NOTE(_A6 ),        \ | ||||
|     E__NOTE(_GS6 ),        \ | ||||
|     E__NOTE(_FS6),        \ | ||||
|     E__NOTE(_E6 ),        \ | ||||
|     E__NOTE(_D6 ),        \ | ||||
|     E__NOTE(_CS6),        \ | ||||
|     E__NOTE(_B5),        \ | ||||
|     E__NOTE(_A5 ), | ||||
| #define MUSIC_OFF_SOUND E__NOTE(_A6), E__NOTE(_GS6), E__NOTE(_FS6), E__NOTE(_E6), E__NOTE(_D6), E__NOTE(_CS6), E__NOTE(_B5), E__NOTE(_A5), | ||||
| 
 | ||||
| #define VOICE_CHANGE_SOUND \ | ||||
|     Q__NOTE(_A5 ),        \ | ||||
|     Q__NOTE(_CS6),        \ | ||||
|     Q__NOTE(_E6 ),        \ | ||||
|     Q__NOTE(_A6 ), | ||||
| #define VOICE_CHANGE_SOUND Q__NOTE(_A5), Q__NOTE(_CS6), Q__NOTE(_E6), Q__NOTE(_A6), | ||||
| 
 | ||||
| #define CHROMATIC_SOUND \ | ||||
|     Q__NOTE(_A5 ),        \ | ||||
|     Q__NOTE(_AS5 ),        \ | ||||
|     Q__NOTE(_B5),        \ | ||||
|     Q__NOTE(_C6 ),        \ | ||||
|     Q__NOTE(_CS6 ), | ||||
| #define CHROMATIC_SOUND Q__NOTE(_A5), Q__NOTE(_AS5), Q__NOTE(_B5), Q__NOTE(_C6), Q__NOTE(_CS6), | ||||
| 
 | ||||
| #define MAJOR_SOUND \ | ||||
|     Q__NOTE(_A5 ),        \ | ||||
|     Q__NOTE(_B5 ),        \ | ||||
|     Q__NOTE(_CS6),        \ | ||||
|     Q__NOTE(_D6 ),        \ | ||||
|     Q__NOTE(_E6 ), | ||||
| #define MAJOR_SOUND Q__NOTE(_A5), Q__NOTE(_B5), Q__NOTE(_CS6), Q__NOTE(_D6), Q__NOTE(_E6), | ||||
| 
 | ||||
| #define MINOR_SOUND \ | ||||
|     Q__NOTE(_A5 ),        \ | ||||
|     Q__NOTE(_B5 ),        \ | ||||
|     Q__NOTE(_C6 ),        \ | ||||
|     Q__NOTE(_D6 ),        \ | ||||
|     Q__NOTE(_E6 ), | ||||
| #define MINOR_SOUND Q__NOTE(_A5), Q__NOTE(_B5), Q__NOTE(_C6), Q__NOTE(_D6), Q__NOTE(_E6), | ||||
| 
 | ||||
| #define GUITAR_SOUND \ | ||||
|     Q__NOTE(_E5 ),        \ | ||||
|     Q__NOTE(_A5),        \ | ||||
|     Q__NOTE(_D6 ),        \ | ||||
|     Q__NOTE(_G6 ), | ||||
| #define GUITAR_SOUND Q__NOTE(_E5), Q__NOTE(_A5), Q__NOTE(_D6), Q__NOTE(_G6), | ||||
| 
 | ||||
| #define VIOLIN_SOUND \ | ||||
|     Q__NOTE(_G5 ),        \ | ||||
|     Q__NOTE(_D6),        \ | ||||
|     Q__NOTE(_A6 ),        \ | ||||
|     Q__NOTE(_E7 ), | ||||
| #define VIOLIN_SOUND Q__NOTE(_G5), Q__NOTE(_D6), Q__NOTE(_A6), Q__NOTE(_E7), | ||||
| 
 | ||||
| #define CAPS_LOCK_ON_SOUND \ | ||||
|     E__NOTE(_A3),          \ | ||||
|     E__NOTE(_B3), | ||||
| #define CAPS_LOCK_ON_SOUND E__NOTE(_A3), E__NOTE(_B3), | ||||
| 
 | ||||
| #define CAPS_LOCK_OFF_SOUND \ | ||||
|     E__NOTE(_B3),           \ | ||||
|     E__NOTE(_A3), | ||||
| #define CAPS_LOCK_OFF_SOUND E__NOTE(_B3), E__NOTE(_A3), | ||||
| 
 | ||||
| #define SCROLL_LOCK_ON_SOUND \ | ||||
|     E__NOTE(_D4),            \ | ||||
|     E__NOTE(_E4), | ||||
| #define SCROLL_LOCK_ON_SOUND E__NOTE(_D4), E__NOTE(_E4), | ||||
| 
 | ||||
| #define SCROLL_LOCK_OFF_SOUND \ | ||||
|     E__NOTE(_E4),             \ | ||||
|     E__NOTE(_D4), | ||||
| #define SCROLL_LOCK_OFF_SOUND E__NOTE(_E4), E__NOTE(_D4), | ||||
| 
 | ||||
| #define NUM_LOCK_ON_SOUND \ | ||||
|     E__NOTE(_D5),         \ | ||||
|     E__NOTE(_E5), | ||||
| #define NUM_LOCK_ON_SOUND E__NOTE(_D5), E__NOTE(_E5), | ||||
| 
 | ||||
| #define NUM_LOCK_OFF_SOUND \ | ||||
|     E__NOTE(_E5),          \ | ||||
|     E__NOTE(_D5), | ||||
| #define NUM_LOCK_OFF_SOUND E__NOTE(_E5), E__NOTE(_D5), | ||||
| 
 | ||||
| #define AG_NORM_SOUND \ | ||||
|     E__NOTE(_A5),      \ | ||||
|     E__NOTE(_A5), | ||||
| #define AG_NORM_SOUND E__NOTE(_A5), E__NOTE(_A5), | ||||
| 
 | ||||
| #define AG_SWAP_SOUND \ | ||||
|     SD_NOTE(_B5),      \ | ||||
|     SD_NOTE(_A5),      \ | ||||
|     SD_NOTE(_B5),      \ | ||||
|     SD_NOTE(_A5), | ||||
| #define AG_SWAP_SOUND SD_NOTE(_B5), SD_NOTE(_A5), SD_NOTE(_B5), SD_NOTE(_A5), | ||||
| 
 | ||||
| #define UNICODE_WINDOWS \ | ||||
|     E__NOTE(_B5),       \ | ||||
|     S__NOTE(_E6), | ||||
| #define UNICODE_WINDOWS E__NOTE(_B5), S__NOTE(_E6), | ||||
| 
 | ||||
| #define UNICODE_LINUX \ | ||||
|     E__NOTE(_E6),     \ | ||||
|     S__NOTE(_B5), | ||||
| 
 | ||||
| 
 | ||||
| #define TERMINAL_SOUND \ | ||||
|     E__NOTE(_C5 ) | ||||
| #define UNICODE_LINUX E__NOTE(_E6), S__NOTE(_B5), | ||||
| 
 | ||||
| #define TERMINAL_SOUND E__NOTE(_C5) | ||||
| 
 | ||||
| /* Title:            La Campanella
 | ||||
|  * Author/Composer:  Frank Lizst | ||||
|  + License:          Public Domain | ||||
|  */ | ||||
| #define CAMPANELLA \ | ||||
|   Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), \ | ||||
|   E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), \ | ||||
|   Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_GS4), \ | ||||
|   E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), \ | ||||
|   E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS6), \ | ||||
|   Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_E5), E__NOTE(_E5), E__NOTE(_DS6), Q__NOTE(_DS5), \ | ||||
|   E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), \ | ||||
|   E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), \ | ||||
|   Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), \ | ||||
|   E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), \ | ||||
|   E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), \ | ||||
|   Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), Q__NOTE(_CS6), E__NOTE(_CS6), E__NOTE(_DS7), Q__NOTE(_B5), \ | ||||
|   E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_B5), E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), \ | ||||
|   E__NOTE(_DS7), Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_G5), E__NOTE(_G5), E__NOTE(_DS7), \ | ||||
|   Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), E__NOTE(_DS7), Q__NOTE(_DS5), \ | ||||
|   E__NOTE(_DS5), E__NOTE(_DS7), W__NOTE(_DS6), W__NOTE(_GS5), | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #define CAMPANELLA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 \ | ||||
|     Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_E5), E__NOTE(_E5), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_AS4), \ | ||||
|         E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), Q__NOTE(_CS6), E__NOTE(_CS6), E__NOTE(_DS7), Q__NOTE(_B5), E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_B5), E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), E__NOTE(_DS7), Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_G5), E__NOTE(_G5), E__NOTE(_DS7), Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), E__NOTE(_DS7), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS7), W__NOTE(_DS6), W__NOTE(_GS5), | ||||
| 
 | ||||
| /* Title:            Fantaisie-Impromptu
 | ||||
|  * Author/Composer:  Chopin | ||||
|  * License:          Public Domain | ||||
| */ | ||||
| #define FANTASIE_IMPROMPTU \ | ||||
|   E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), \ | ||||
|   E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_A4), \ | ||||
|   E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), \ | ||||
|   E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_A4), E__NOTE(_CS5), E__NOTE(_DS5), \ | ||||
|   E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_CS6), E__NOTE(_DS6), E__NOTE(_B6), E__NOTE(_A6), E__NOTE(_GS6), E__NOTE(_FS6), \ | ||||
|   E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_FS6), E__NOTE(_CS6), E__NOTE(_C5), E__NOTE(_DS6), E__NOTE(_A5), E__NOTE(_GS5), \ | ||||
|   E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_FS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_DS5), \ | ||||
|   E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_B4), E__NOTE(_A4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), \ | ||||
|   E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), \ | ||||
|   E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_AS4), E__NOTE(_GS4), E__NOTE(_REST), \ | ||||
|   E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), \ | ||||
|   E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_DS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_REST), E__NOTE(_DS5), \ | ||||
|   E__NOTE(_B5), E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_CS6), E__NOTE(_B5), \ | ||||
|   E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_AS5), WD_NOTE(_GS5), | ||||
| 
 | ||||
|  */ | ||||
| #define FANTASIE_IMPROMPTU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \ | ||||
|     E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_A4), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_CS6), E__NOTE(_DS6), E__NOTE(_B6), E__NOTE(_A6), E__NOTE(_GS6), E__NOTE(_FS6), E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_FS6), E__NOTE(_CS6), E__NOTE(_C5), E__NOTE(_DS6), E__NOTE(_A5), E__NOTE(_GS5), E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_FS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_DS5), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_B4), E__NOTE(_A4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), \ | ||||
|         E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_AS4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_DS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_REST), E__NOTE(_DS5), E__NOTE(_B5), E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_CS6), E__NOTE(_B5), E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_AS5), WD_NOTE(_GS5), | ||||
| 
 | ||||
| /* Title:            Nocturne Op. 9 No. 1 in B flat minor
 | ||||
|  * Author/Composer:  Chopin | ||||
|    License:          Public Domain | ||||
| */ | ||||
| #define NOCTURNE_OP_9_NO_1 \ | ||||
|   H__NOTE(_BF5), H__NOTE(_C6), H__NOTE(_DF6), H__NOTE(_A5), H__NOTE(_BF5), H__NOTE(_GF5), W__NOTE(_F5), W__NOTE(_F5), W__NOTE(_F5), \ | ||||
|   W__NOTE(_F5), H__NOTE(_GF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_C5), B__NOTE(_DF5), W__NOTE(_BF4), Q__NOTE(_BF5), \ | ||||
|   Q__NOTE(_C6), Q__NOTE(_DF6), Q__NOTE(_A5), Q__NOTE(_BF5), Q__NOTE(_A5), Q__NOTE(_GS5), Q__NOTE(_A5), Q__NOTE(_C6), \ | ||||
|   Q__NOTE(_BF5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_GF5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_BF5), Q__NOTE(_A5), \ | ||||
|   Q__NOTE(_AF5), Q__NOTE(_G5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), Q__NOTE(_D5), Q__NOTE(_DF5), \ | ||||
|   Q__NOTE(_C5), Q__NOTE(_DF5), Q__NOTE(_C5), Q__NOTE(_B4), Q__NOTE(_C5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), \ | ||||
|   B__NOTE(_DF5), W__NOTE(_BF4), W__NOTE(_BF5), W__NOTE(_BF5), W__NOTE(_BF5), BD_NOTE(_AF5), W__NOTE(_DF5), H__NOTE(_BF4), \ | ||||
|   H__NOTE(_C5), H__NOTE(_DF5), H__NOTE(_GF5), H__NOTE(_GF5), BD_NOTE(_F5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), \ | ||||
|   H__NOTE(_DF5), H__NOTE(_A4), B__NOTE(_AF4), W__NOTE(_DF5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_DF5), \ | ||||
|   H__NOTE(_EF5), BD_NOTE(_F5), | ||||
| 
 | ||||
| #define NOCTURNE_OP_9_NO_1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       \ | ||||
|     H__NOTE(_BF5), H__NOTE(_C6), H__NOTE(_DF6), H__NOTE(_A5), H__NOTE(_BF5), H__NOTE(_GF5), W__NOTE(_F5), W__NOTE(_F5), W__NOTE(_F5), W__NOTE(_F5), H__NOTE(_GF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_C5), B__NOTE(_DF5), W__NOTE(_BF4), Q__NOTE(_BF5), Q__NOTE(_C6), Q__NOTE(_DF6), Q__NOTE(_A5), Q__NOTE(_BF5), Q__NOTE(_A5), Q__NOTE(_GS5), Q__NOTE(_A5), Q__NOTE(_C6), Q__NOTE(_BF5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_GF5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_BF5), Q__NOTE(_A5), Q__NOTE(_AF5), Q__NOTE(_G5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), Q__NOTE(_D5), Q__NOTE(_DF5), Q__NOTE(_C5), Q__NOTE(_DF5), Q__NOTE(_C5), Q__NOTE(_B4), Q__NOTE(_C5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), B__NOTE(_DF5), W__NOTE(_BF4), W__NOTE(_BF5), W__NOTE(_BF5), W__NOTE(_BF5), BD_NOTE(_AF5), W__NOTE(_DF5), H__NOTE(_BF4), H__NOTE(_C5), H__NOTE(_DF5), H__NOTE(_GF5), H__NOTE(_GF5), BD_NOTE(_F5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_DF5), H__NOTE(_A4), B__NOTE(_AF4), \ | ||||
|         W__NOTE(_DF5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_DF5), H__NOTE(_EF5), BD_NOTE(_F5), | ||||
| 
 | ||||
| /* Removed sounds
 | ||||
|  +   This list is here solely for compatibility, so that removed songs don't just break things | ||||
|  |  | |||
|  | @ -19,40 +19,33 @@ | |||
| 
 | ||||
| // these are imported from audio.c
 | ||||
| extern uint16_t envelope_index; | ||||
| extern float note_timbre; | ||||
| extern float polyphony_rate; | ||||
| extern bool glissando; | ||||
| extern float    note_timbre; | ||||
| extern float    polyphony_rate; | ||||
| extern bool     glissando; | ||||
| 
 | ||||
| voice_type voice = default_voice; | ||||
| 
 | ||||
| void set_voice(voice_type v) { | ||||
|     voice = v; | ||||
| } | ||||
| void set_voice(voice_type v) { voice = v; } | ||||
| 
 | ||||
| void voice_iterate() { | ||||
|     voice = (voice + 1) % number_of_voices; | ||||
| } | ||||
| void voice_iterate() { voice = (voice + 1) % number_of_voices; } | ||||
| 
 | ||||
| void voice_deiterate() { | ||||
|     voice = (voice - 1 + number_of_voices) % number_of_voices; | ||||
| } | ||||
| void voice_deiterate() { voice = (voice - 1 + number_of_voices) % number_of_voices; } | ||||
| 
 | ||||
| float voice_envelope(float frequency) { | ||||
|     // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz
 | ||||
|     __attribute__ ((unused)) | ||||
|     uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); | ||||
|     __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); | ||||
| 
 | ||||
|     switch (voice) { | ||||
|         case default_voice: | ||||
|             glissando = false; | ||||
|             note_timbre = TIMBRE_50; | ||||
|             glissando      = false; | ||||
|             note_timbre    = TIMBRE_50; | ||||
|             polyphony_rate = 0; | ||||
| 	        break; | ||||
|             break; | ||||
| 
 | ||||
|     #ifdef AUDIO_VOICES | ||||
| #ifdef AUDIO_VOICES | ||||
| 
 | ||||
|         case something: | ||||
|             glissando = false; | ||||
|             glissando      = false; | ||||
|             polyphony_rate = 0; | ||||
|             switch (compensated_index) { | ||||
|                 case 0 ... 9: | ||||
|  | @ -74,25 +67,23 @@ float voice_envelope(float frequency) { | |||
|             break; | ||||
| 
 | ||||
|         case drums: | ||||
|             glissando = false; | ||||
|             glissando      = false; | ||||
|             polyphony_rate = 0; | ||||
|                 // switch (compensated_index) {
 | ||||
|                 //     case 0 ... 10:
 | ||||
|                 //         note_timbre = 0.5;
 | ||||
|                 //         break;
 | ||||
|                 //     case 11 ... 20:
 | ||||
|                 //         note_timbre = 0.5 * (21 - compensated_index) / 10;
 | ||||
|                 //         break;
 | ||||
|                 //     default:
 | ||||
|                 //         note_timbre = 0;
 | ||||
|                 //         break;
 | ||||
|                 // }
 | ||||
|                 // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
 | ||||
|             // switch (compensated_index) {
 | ||||
|             //     case 0 ... 10:
 | ||||
|             //         note_timbre = 0.5;
 | ||||
|             //         break;
 | ||||
|             //     case 11 ... 20:
 | ||||
|             //         note_timbre = 0.5 * (21 - compensated_index) / 10;
 | ||||
|             //         break;
 | ||||
|             //     default:
 | ||||
|             //         note_timbre = 0;
 | ||||
|             //         break;
 | ||||
|             // }
 | ||||
|             // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
 | ||||
| 
 | ||||
|             if (frequency < 80.0) { | ||||
| 
 | ||||
|             } else if (frequency < 160.0) { | ||||
| 
 | ||||
|                 // Bass drum: 60 - 100 Hz
 | ||||
|                 frequency = (rand() % (int)(40)) + 60; | ||||
|                 switch (envelope_index) { | ||||
|  | @ -108,8 +99,6 @@ float voice_envelope(float frequency) { | |||
|                 } | ||||
| 
 | ||||
|             } else if (frequency < 320.0) { | ||||
| 
 | ||||
| 
 | ||||
|                 // Snare drum: 1 - 2 KHz
 | ||||
|                 frequency = (rand() % (int)(1000)) + 1000; | ||||
|                 switch (envelope_index) { | ||||
|  | @ -125,7 +114,6 @@ float voice_envelope(float frequency) { | |||
|                 } | ||||
| 
 | ||||
|             } else if (frequency < 640.0) { | ||||
| 
 | ||||
|                 // Closed Hi-hat: 3 - 5 KHz
 | ||||
|                 frequency = (rand() % (int)(2000)) + 3000; | ||||
|                 switch (envelope_index) { | ||||
|  | @ -141,7 +129,6 @@ float voice_envelope(float frequency) { | |||
|                 } | ||||
| 
 | ||||
|             } else if (frequency < 1280.0) { | ||||
| 
 | ||||
|                 // Open Hi-hat: 3 - 5 KHz
 | ||||
|                 frequency = (rand() % (int)(2000)) + 3000; | ||||
|                 switch (envelope_index) { | ||||
|  | @ -155,141 +142,138 @@ float voice_envelope(float frequency) { | |||
|                         note_timbre = 0; | ||||
|                         break; | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             break; | ||||
|         case butts_fader: | ||||
|             glissando = true; | ||||
|             glissando      = true; | ||||
|             polyphony_rate = 0; | ||||
|             switch (compensated_index) { | ||||
|                 case 0 ... 9: | ||||
|                     frequency = frequency / 4; | ||||
|                     frequency   = frequency / 4; | ||||
|                     note_timbre = TIMBRE_12; | ||||
| 	                break; | ||||
|                     break; | ||||
| 
 | ||||
|                 case 10 ... 19: | ||||
|                     frequency = frequency / 2; | ||||
|                     frequency   = frequency / 2; | ||||
|                     note_timbre = TIMBRE_12; | ||||
| 	                break; | ||||
|                     break; | ||||
| 
 | ||||
|                 case 20 ... 200: | ||||
|                     note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; | ||||
| 	                break; | ||||
|                     note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2) * .125; | ||||
|                     break; | ||||
| 
 | ||||
|                 default: | ||||
|                     note_timbre = 0; | ||||
|                 	break; | ||||
|                     break; | ||||
|             } | ||||
|     	    break; | ||||
|             break; | ||||
| 
 | ||||
|         // case octave_crunch:
 | ||||
|         //     polyphony_rate = 0;
 | ||||
|         //     switch (compensated_index) {
 | ||||
|         //         case 0 ... 9:
 | ||||
|         //         case 20 ... 24:
 | ||||
|         //         case 30 ... 32:
 | ||||
|         //             frequency = frequency / 2;
 | ||||
|         //             note_timbre = TIMBRE_12;
 | ||||
|         //         break;
 | ||||
|             // case octave_crunch:
 | ||||
|             //     polyphony_rate = 0;
 | ||||
|             //     switch (compensated_index) {
 | ||||
|             //         case 0 ... 9:
 | ||||
|             //         case 20 ... 24:
 | ||||
|             //         case 30 ... 32:
 | ||||
|             //             frequency = frequency / 2;
 | ||||
|             //             note_timbre = TIMBRE_12;
 | ||||
|             //         break;
 | ||||
| 
 | ||||
|         //         case 10 ... 19:
 | ||||
|         //         case 25 ... 29:
 | ||||
|         //         case 33 ... 35:
 | ||||
|         //             frequency = frequency * 2;
 | ||||
|         //             note_timbre = TIMBRE_12;
 | ||||
| 	       //          break;
 | ||||
|             //         case 10 ... 19:
 | ||||
|             //         case 25 ... 29:
 | ||||
|             //         case 33 ... 35:
 | ||||
|             //             frequency = frequency * 2;
 | ||||
|             //             note_timbre = TIMBRE_12;
 | ||||
|             //          break;
 | ||||
| 
 | ||||
|         //         default:
 | ||||
|         //             note_timbre = TIMBRE_12;
 | ||||
|         //         	break;
 | ||||
|         //     }
 | ||||
| 	       //  break;
 | ||||
|             //         default:
 | ||||
|             //             note_timbre = TIMBRE_12;
 | ||||
|             //         	break;
 | ||||
|             //     }
 | ||||
|             //  break;
 | ||||
| 
 | ||||
|         case duty_osc: | ||||
|             // This slows the loop down a substantial amount, so higher notes may freeze
 | ||||
|             glissando = true; | ||||
|             glissando      = true; | ||||
|             polyphony_rate = 0; | ||||
|             switch (compensated_index) { | ||||
|                 default: | ||||
|                     #define OCS_SPEED 10 | ||||
|                     #define OCS_AMP   .25 | ||||
| #    define OCS_SPEED 10 | ||||
| #    define OCS_AMP .25 | ||||
|                     // sine wave is slow
 | ||||
|                     // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5;
 | ||||
|                     // triangle wave is a bit faster
 | ||||
|                     note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; | ||||
|                 	break; | ||||
|                     note_timbre = (float)abs((compensated_index * OCS_SPEED % 3000) - 1500) * (OCS_AMP / 1500) + (1 - OCS_AMP) / 2; | ||||
|                     break; | ||||
|             } | ||||
| 	        break; | ||||
|             break; | ||||
| 
 | ||||
|         case duty_octave_down: | ||||
|             glissando = true; | ||||
|             glissando      = true; | ||||
|             polyphony_rate = 0; | ||||
|             note_timbre = (envelope_index % 2) * .125 + .375 * 2; | ||||
|             if ((envelope_index % 4) == 0) | ||||
|                 note_timbre = 0.5; | ||||
|             if ((envelope_index % 8) == 0) | ||||
|                 note_timbre = 0; | ||||
|             note_timbre    = (envelope_index % 2) * .125 + .375 * 2; | ||||
|             if ((envelope_index % 4) == 0) note_timbre = 0.5; | ||||
|             if ((envelope_index % 8) == 0) note_timbre = 0; | ||||
|             break; | ||||
|         case delayed_vibrato: | ||||
|             glissando = true; | ||||
|             glissando      = true; | ||||
|             polyphony_rate = 0; | ||||
|             note_timbre = TIMBRE_50; | ||||
|             #define VOICE_VIBRATO_DELAY 150 | ||||
|             #define VOICE_VIBRATO_SPEED 50 | ||||
|             note_timbre    = TIMBRE_50; | ||||
| #    define VOICE_VIBRATO_DELAY 150 | ||||
| #    define VOICE_VIBRATO_SPEED 50 | ||||
|             switch (compensated_index) { | ||||
|                 case 0 ... VOICE_VIBRATO_DELAY: | ||||
|                     break; | ||||
|                 default: | ||||
|                     frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; | ||||
|                     frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1)) / 1000 * VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; | ||||
|                     break; | ||||
|             } | ||||
|             break; | ||||
|         // case delayed_vibrato_octave:
 | ||||
|         //     polyphony_rate = 0;
 | ||||
|         //     if ((envelope_index % 2) == 1) {
 | ||||
|         //         note_timbre = 0.55;
 | ||||
|         //     } else {
 | ||||
|         //         note_timbre = 0.45;
 | ||||
|         //     }
 | ||||
|         //     #define VOICE_VIBRATO_DELAY 150
 | ||||
|         //     #define VOICE_VIBRATO_SPEED 50
 | ||||
|         //     switch (compensated_index) {
 | ||||
|         //         case 0 ... VOICE_VIBRATO_DELAY:
 | ||||
|         //             break;
 | ||||
|         //         default:
 | ||||
|         //             frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)];
 | ||||
|         //             break;
 | ||||
|         //     }
 | ||||
|         //     break;
 | ||||
|         // case duty_fifth_down:
 | ||||
|         //     note_timbre = 0.5;
 | ||||
|         //     if ((envelope_index % 3) == 0)
 | ||||
|         //         note_timbre = 0.75;
 | ||||
|         //     break;
 | ||||
|         // case duty_fourth_down:
 | ||||
|         //     note_timbre = 0.0;
 | ||||
|         //     if ((envelope_index % 12) == 0)
 | ||||
|         //         note_timbre = 0.75;
 | ||||
|         //     if (((envelope_index % 12) % 4) != 1)
 | ||||
|         //         note_timbre = 0.75;
 | ||||
|         //     break;
 | ||||
|         // case duty_third_down:
 | ||||
|         //     note_timbre = 0.5;
 | ||||
|         //     if ((envelope_index % 5) == 0)
 | ||||
|         //         note_timbre = 0.75;
 | ||||
|         //     break;
 | ||||
|         // case duty_fifth_third_down:
 | ||||
|         //     note_timbre = 0.5;
 | ||||
|         //     if ((envelope_index % 5) == 0)
 | ||||
|         //         note_timbre = 0.75;
 | ||||
|         //     if ((envelope_index % 3) == 0)
 | ||||
|         //         note_timbre = 0.25;
 | ||||
|         //     break;
 | ||||
|             // case delayed_vibrato_octave:
 | ||||
|             //     polyphony_rate = 0;
 | ||||
|             //     if ((envelope_index % 2) == 1) {
 | ||||
|             //         note_timbre = 0.55;
 | ||||
|             //     } else {
 | ||||
|             //         note_timbre = 0.45;
 | ||||
|             //     }
 | ||||
|             //     #define VOICE_VIBRATO_DELAY 150
 | ||||
|             //     #define VOICE_VIBRATO_SPEED 50
 | ||||
|             //     switch (compensated_index) {
 | ||||
|             //         case 0 ... VOICE_VIBRATO_DELAY:
 | ||||
|             //             break;
 | ||||
|             //         default:
 | ||||
|             //             frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)];
 | ||||
|             //             break;
 | ||||
|             //     }
 | ||||
|             //     break;
 | ||||
|             // case duty_fifth_down:
 | ||||
|             //     note_timbre = 0.5;
 | ||||
|             //     if ((envelope_index % 3) == 0)
 | ||||
|             //         note_timbre = 0.75;
 | ||||
|             //     break;
 | ||||
|             // case duty_fourth_down:
 | ||||
|             //     note_timbre = 0.0;
 | ||||
|             //     if ((envelope_index % 12) == 0)
 | ||||
|             //         note_timbre = 0.75;
 | ||||
|             //     if (((envelope_index % 12) % 4) != 1)
 | ||||
|             //         note_timbre = 0.75;
 | ||||
|             //     break;
 | ||||
|             // case duty_third_down:
 | ||||
|             //     note_timbre = 0.5;
 | ||||
|             //     if ((envelope_index % 5) == 0)
 | ||||
|             //         note_timbre = 0.75;
 | ||||
|             //     break;
 | ||||
|             // case duty_fifth_third_down:
 | ||||
|             //     note_timbre = 0.5;
 | ||||
|             //     if ((envelope_index % 5) == 0)
 | ||||
|             //         note_timbre = 0.75;
 | ||||
|             //     if ((envelope_index % 3) == 0)
 | ||||
|             //         note_timbre = 0.25;
 | ||||
|             //     break;
 | ||||
| 
 | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
| 		default: | ||||
|    			break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     return frequency; | ||||
|  |  | |||
|  | @ -16,19 +16,19 @@ | |||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #if defined(__AVR__) | ||||
|     #include <avr/io.h> | ||||
| #    include <avr/io.h> | ||||
| #endif | ||||
| #include "wait.h" | ||||
| #include "luts.h" | ||||
| 
 | ||||
| #ifndef VOICES_H | ||||
| #define VOICES_H | ||||
| #    define VOICES_H | ||||
| 
 | ||||
| float voice_envelope(float frequency); | ||||
| 
 | ||||
| typedef enum { | ||||
|     default_voice, | ||||
|     #ifdef AUDIO_VOICES | ||||
| #    ifdef AUDIO_VOICES | ||||
|     something, | ||||
|     drums, | ||||
|     butts_fader, | ||||
|  | @ -36,13 +36,13 @@ typedef enum { | |||
|     duty_osc, | ||||
|     duty_octave_down, | ||||
|     delayed_vibrato, | ||||
|     // delayed_vibrato_octave,
 | ||||
|     // duty_fifth_down,
 | ||||
|     // duty_fourth_down,
 | ||||
|     // duty_third_down,
 | ||||
|     // duty_fifth_third_down,
 | ||||
|     #endif | ||||
|     number_of_voices // important that this is last
 | ||||
| // delayed_vibrato_octave,
 | ||||
| // duty_fifth_down,
 | ||||
| // duty_fourth_down,
 | ||||
| // duty_third_down,
 | ||||
| // duty_fifth_third_down,
 | ||||
| #    endif | ||||
|     number_of_voices  // important that this is last
 | ||||
| } voice_type; | ||||
| 
 | ||||
| void set_voice(voice_type v); | ||||
|  |  | |||
|  | @ -20,262 +20,17 @@ | |||
| 
 | ||||
| #define SINE_LENGTH 2048 | ||||
| 
 | ||||
| const uint8_t sinewave[] PROGMEM= //2048 values
 | ||||
| { | ||||
| 0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82, | ||||
| 0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85, | ||||
| 0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88, | ||||
| 0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c, | ||||
| 0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f, | ||||
| 0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92, | ||||
| 0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95, | ||||
| 0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98, | ||||
| 0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b, | ||||
| 0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e, | ||||
| 0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1, | ||||
| 0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4, | ||||
| 0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7, | ||||
| 0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa, | ||||
| 0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad, | ||||
| 0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0, | ||||
| 0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3, | ||||
| 0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6, | ||||
| 0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8, | ||||
| 0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb, | ||||
| 0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe, | ||||
| 0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1, | ||||
| 0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3, | ||||
| 0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6, | ||||
| 0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9, | ||||
| 0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb, | ||||
| 0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce, | ||||
| 0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0, | ||||
| 0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2, | ||||
| 0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5, | ||||
| 0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7, | ||||
| 0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9, | ||||
| 0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc, | ||||
| 0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde, | ||||
| 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0, | ||||
| 0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2, | ||||
| 0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4, | ||||
| 0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6, | ||||
| 0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8, | ||||
| 0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9, | ||||
| 0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb, | ||||
| 0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed, | ||||
| 0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee, | ||||
| 0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0, | ||||
| 0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1, | ||||
| 0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3, | ||||
| 0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4, | ||||
| 0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5, | ||||
| 0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6, | ||||
| 0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, | ||||
| 0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, | ||||
| 0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, | ||||
| 0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, | ||||
| 0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb, | ||||
| 0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc, | ||||
| 0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, | ||||
| 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, | ||||
| 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||||
| 0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd, | ||||
| 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, | ||||
| 0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, | ||||
| 0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb, | ||||
| 0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa, | ||||
| 0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, | ||||
| 0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, | ||||
| 0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, | ||||
| 0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, | ||||
| 0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5, | ||||
| 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4, | ||||
| 0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3, | ||||
| 0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2, | ||||
| 0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0, | ||||
| 0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef, | ||||
| 0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed, | ||||
| 0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb, | ||||
| 0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea, | ||||
| 0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8, | ||||
| 0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6, | ||||
| 0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4, | ||||
| 0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2, | ||||
| 0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0, | ||||
| 0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde, | ||||
| 0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc, | ||||
| 0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda, | ||||
| 0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8, | ||||
| 0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5, | ||||
| 0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3, | ||||
| 0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1, | ||||
| 0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce, | ||||
| 0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc, | ||||
| 0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9, | ||||
| 0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7, | ||||
| 0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4, | ||||
| 0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1, | ||||
| 0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf, | ||||
| 0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc, | ||||
| 0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9, | ||||
| 0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6, | ||||
| 0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4, | ||||
| 0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1, | ||||
| 0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae, | ||||
| 0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab, | ||||
| 0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8, | ||||
| 0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5, | ||||
| 0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2, | ||||
| 0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f, | ||||
| 0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c, | ||||
| 0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99, | ||||
| 0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96, | ||||
| 0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93, | ||||
| 0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f, | ||||
| 0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c, | ||||
| 0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89, | ||||
| 0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86, | ||||
| 0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83, | ||||
| 0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80, | ||||
| 0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d, | ||||
| 0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a, | ||||
| 0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77, | ||||
| 0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73, | ||||
| 0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70, | ||||
| 0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d, | ||||
| 0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a, | ||||
| 0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67, | ||||
| 0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64, | ||||
| 0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61, | ||||
| 0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e, | ||||
| 0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b, | ||||
| 0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58, | ||||
| 0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55, | ||||
| 0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52, | ||||
| 0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f, | ||||
| 0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c, | ||||
| 0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49, | ||||
| 0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47, | ||||
| 0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44, | ||||
| 0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41, | ||||
| 0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e, | ||||
| 0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c, | ||||
| 0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39, | ||||
| 0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36, | ||||
| 0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34, | ||||
| 0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31, | ||||
| 0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f, | ||||
| 0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d, | ||||
| 0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a, | ||||
| 0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28, | ||||
| 0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26, | ||||
| 0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23, | ||||
| 0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21, | ||||
| 0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f, | ||||
| 0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d, | ||||
| 0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b, | ||||
| 0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19, | ||||
| 0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17, | ||||
| 0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16, | ||||
| 0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14, | ||||
| 0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12, | ||||
| 0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11, | ||||
| 0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf, | ||||
| 0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe, | ||||
| 0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc, | ||||
| 0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb, | ||||
| 0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa, | ||||
| 0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9, | ||||
| 0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8, | ||||
| 0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7, | ||||
| 0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6, | ||||
| 0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, | ||||
| 0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4, | ||||
| 0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3, | ||||
| 0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3, | ||||
| 0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, | ||||
| 0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||||
| 0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||||
| 0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2, | ||||
| 0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, | ||||
| 0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3, | ||||
| 0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4, | ||||
| 0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5, | ||||
| 0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, | ||||
| 0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6, | ||||
| 0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7, | ||||
| 0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8, | ||||
| 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa, | ||||
| 0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb, | ||||
| 0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc, | ||||
| 0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd, | ||||
| 0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf, | ||||
| 0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10, | ||||
| 0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12, | ||||
| 0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14, | ||||
| 0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15, | ||||
| 0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17, | ||||
| 0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19, | ||||
| 0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b, | ||||
| 0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d, | ||||
| 0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f, | ||||
| 0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21, | ||||
| 0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23, | ||||
| 0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25, | ||||
| 0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27, | ||||
| 0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a, | ||||
| 0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c, | ||||
| 0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e, | ||||
| 0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31, | ||||
| 0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, | ||||
| 0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36, | ||||
| 0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38, | ||||
| 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b, | ||||
| 0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e, | ||||
| 0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40, | ||||
| 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43, | ||||
| 0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46, | ||||
| 0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49, | ||||
| 0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b, | ||||
| 0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e, | ||||
| 0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51, | ||||
| 0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54, | ||||
| 0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57, | ||||
| 0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a, | ||||
| 0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d, | ||||
| 0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60, | ||||
| 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, | ||||
| 0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66, | ||||
| 0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69, | ||||
| 0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c, | ||||
| 0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70, | ||||
| 0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73, | ||||
| 0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76, | ||||
| 0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, | ||||
| 0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, | ||||
| 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f | ||||
| }; | ||||
| const uint8_t sinewave[] PROGMEM =  // 2048 values
 | ||||
|     {0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbb, | ||||
|      0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, | ||||
|      0xe9, 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, | ||||
|      0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, | ||||
|      0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, | ||||
|      0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9d, | ||||
|      0x9d, 0x9d, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x98, 0x97, 0x97, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x86, 0x86, 0x85, 0x85, 0x85, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x75, 0x75, 0x75, 0x74, 0x74, 0x73, 0x73, 0x73, 0x72, 0x72, 0x71, 0x71, 0x71, 0x70, 0x70, 0x70, 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6c, 0x6c, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x68, 0x68, 0x67, 0x67, 0x67, 0x66, 0x66, 0x65, 0x65, 0x65, 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x62, 0x61, 0x61, 0x61, 0x60, | ||||
|      0x60, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x59, 0x59, 0x59, 0x58, 0x58, 0x58, 0x57, 0x57, 0x56, 0x56, 0x56, 0x55, 0x55, 0x55, 0x54, 0x54, 0x53, 0x53, 0x53, 0x52, 0x52, 0x52, 0x51, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f, 0x4f, 0x4e, 0x4e, 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b, 0x4b, 0x4a, 0x4a, 0x4a, 0x49, 0x49, 0x49, 0x48, 0x48, 0x48, 0x47, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x2d, 0x2d, 0x2d, 0x2d, 0x2c, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a, 0x2a, | ||||
|      0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x26, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf,  0xf,  0xf,  0xf,  0xf,  0xf,  0xe,  0xe,  0xe,  0xe,  0xe,  0xd,  0xd,  0xd,  0xd,  0xd,  0xd,  0xc,  0xc,  0xc,  0xc,  0xc,  0xc,  0xb,  0xb,  0xb,  0xb,  0xb,  0xb,  0xa,  0xa,  0xa,  0xa,  0xa,  0xa,  0xa,  0x9,  0x9,  0x9,  0x9,  0x9,  0x9,  0x9,  0x8,  0x8,  0x8,  0x8,  0x8, | ||||
|      0x8,  0x8,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1, | ||||
|      0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x1,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x2,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x3,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x4,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x5,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x6,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x7,  0x8,  0x8,  0x8,  0x8,  0x8,  0x8,  0x8,  0x9,  0x9,  0x9,  0x9,  0x9,  0x9,  0x9,  0xa,  0xa,  0xa,  0xa,  0xa,  0xa,  0xa,  0xb,  0xb,  0xb,  0xb,  0xb,  0xb,  0xc,  0xc,  0xc,  0xc,  0xc,  0xc,  0xd,  0xd,  0xd,  0xd,  0xd,  0xd,  0xe,  0xe,  0xe,  0xe,  0xe,  0xf,  0xf,  0xf,  0xf,  0xf,  0xf,  0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, | ||||
|      0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x46, | ||||
|      0x46, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f}; | ||||
|  |  | |||
							
								
								
									
										117
									
								
								quantum/color.c
									
										
									
									
									
								
							
							
						
						
									
										117
									
								
								quantum/color.c
									
										
									
									
									
								
							|  | @ -14,81 +14,76 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #include "color.h" | ||||
| #include "led_tables.h" | ||||
| #include "progmem.h" | ||||
| 
 | ||||
| RGB hsv_to_rgb( HSV hsv ) | ||||
| { | ||||
| 	RGB rgb; | ||||
| 	uint8_t region, remainder, p, q, t; | ||||
| 	uint16_t h, s, v; | ||||
| RGB hsv_to_rgb(HSV hsv) { | ||||
|     RGB      rgb; | ||||
|     uint8_t  region, remainder, p, q, t; | ||||
|     uint16_t h, s, v; | ||||
| 
 | ||||
| 	if ( hsv.s == 0 ) | ||||
| 	{ | ||||
|     if (hsv.s == 0) { | ||||
| #ifdef USE_CIE1931_CURVE | ||||
| 		rgb.r = rgb.g = rgb.b = pgm_read_byte( &CIE1931_CURVE[hsv.v] ); | ||||
|         rgb.r = rgb.g = rgb.b = pgm_read_byte(&CIE1931_CURVE[hsv.v]); | ||||
| #else | ||||
| 		rgb.r = hsv.v; | ||||
| 		rgb.g = hsv.v; | ||||
| 		rgb.b = hsv.v; | ||||
|         rgb.r = hsv.v; | ||||
|         rgb.g = hsv.v; | ||||
|         rgb.b = hsv.v; | ||||
| #endif | ||||
| 		return rgb; | ||||
| 	} | ||||
|         return rgb; | ||||
|     } | ||||
| 
 | ||||
| 	h = hsv.h; | ||||
| 	s = hsv.s; | ||||
| 	v = hsv.v; | ||||
|     h = hsv.h; | ||||
|     s = hsv.s; | ||||
|     v = hsv.v; | ||||
| 
 | ||||
| 	region = h * 6 / 255; | ||||
| 	remainder = (h * 2 - region * 85) * 3; | ||||
|     region    = h * 6 / 255; | ||||
|     remainder = (h * 2 - region * 85) * 3; | ||||
| 
 | ||||
| 	p = (v * (255 - s)) >> 8; | ||||
| 	q = (v * (255 - ((s * remainder) >> 8))) >> 8; | ||||
| 	t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; | ||||
|     p = (v * (255 - s)) >> 8; | ||||
|     q = (v * (255 - ((s * remainder) >> 8))) >> 8; | ||||
|     t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; | ||||
| 
 | ||||
| 	switch ( region ) | ||||
| 	{ | ||||
| 		case 6: | ||||
| 		case 0: | ||||
| 			rgb.r = v; | ||||
| 			rgb.g = t; | ||||
| 			rgb.b = p; | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			rgb.r = q; | ||||
| 			rgb.g = v; | ||||
| 			rgb.b = p; | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			rgb.r = p; | ||||
| 			rgb.g = v; | ||||
| 			rgb.b = t; | ||||
| 			break; | ||||
| 		case 3: | ||||
| 			rgb.r = p; | ||||
| 			rgb.g = q; | ||||
| 			rgb.b = v; | ||||
| 			break; | ||||
| 		case 4: | ||||
| 			rgb.r = t; | ||||
| 			rgb.g = p; | ||||
| 			rgb.b = v; | ||||
| 			break; | ||||
| 		default: | ||||
| 			rgb.r = v; | ||||
| 			rgb.g = p; | ||||
| 			rgb.b = q; | ||||
| 			break; | ||||
| 	} | ||||
|     switch (region) { | ||||
|         case 6: | ||||
|         case 0: | ||||
|             rgb.r = v; | ||||
|             rgb.g = t; | ||||
|             rgb.b = p; | ||||
|             break; | ||||
|         case 1: | ||||
|             rgb.r = q; | ||||
|             rgb.g = v; | ||||
|             rgb.b = p; | ||||
|             break; | ||||
|         case 2: | ||||
|             rgb.r = p; | ||||
|             rgb.g = v; | ||||
|             rgb.b = t; | ||||
|             break; | ||||
|         case 3: | ||||
|             rgb.r = p; | ||||
|             rgb.g = q; | ||||
|             rgb.b = v; | ||||
|             break; | ||||
|         case 4: | ||||
|             rgb.r = t; | ||||
|             rgb.g = p; | ||||
|             rgb.b = v; | ||||
|             break; | ||||
|         default: | ||||
|             rgb.r = v; | ||||
|             rgb.g = p; | ||||
|             rgb.b = q; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
| #ifdef USE_CIE1931_CURVE | ||||
| 	rgb.r = pgm_read_byte( &CIE1931_CURVE[rgb.r] ); | ||||
| 	rgb.g = pgm_read_byte( &CIE1931_CURVE[rgb.g] ); | ||||
| 	rgb.b = pgm_read_byte( &CIE1931_CURVE[rgb.b] ); | ||||
|     rgb.r = pgm_read_byte(&CIE1931_CURVE[rgb.r]); | ||||
|     rgb.g = pgm_read_byte(&CIE1931_CURVE[rgb.g]); | ||||
|     rgb.b = pgm_read_byte(&CIE1931_CURVE[rgb.b]); | ||||
| #endif | ||||
| 
 | ||||
| 	return rgb; | ||||
|     return rgb; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,60 +14,55 @@ | |||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef COLOR_H | ||||
| #define COLOR_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| 
 | ||||
| #if defined(__GNUC__) | ||||
| #define PACKED __attribute__ ((__packed__)) | ||||
| #    define PACKED __attribute__((__packed__)) | ||||
| #else | ||||
| #define PACKED | ||||
| #    define PACKED | ||||
| #endif | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
| #pragma pack( push, 1 ) | ||||
| #    pragma pack(push, 1) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RGBW | ||||
|   #define LED_TYPE cRGBW | ||||
| #    define LED_TYPE cRGBW | ||||
| #else | ||||
|   #define LED_TYPE RGB | ||||
| #    define LED_TYPE RGB | ||||
| #endif | ||||
| 
 | ||||
| // WS2812 specific layout
 | ||||
| typedef struct PACKED | ||||
| { | ||||
| 	uint8_t g; | ||||
| 	uint8_t r; | ||||
| 	uint8_t b; | ||||
| typedef struct PACKED { | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
|     uint8_t b; | ||||
| } cRGB; | ||||
| 
 | ||||
| typedef cRGB RGB; | ||||
| 
 | ||||
| // WS2812 specific layout
 | ||||
| typedef struct PACKED | ||||
| { | ||||
| 	uint8_t g; | ||||
| 	uint8_t r; | ||||
| 	uint8_t b; | ||||
| 	uint8_t w; | ||||
| typedef struct PACKED { | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
|     uint8_t b; | ||||
|     uint8_t w; | ||||
| } cRGBW; | ||||
| 
 | ||||
| typedef struct PACKED | ||||
| { | ||||
| 	uint8_t h; | ||||
| 	uint8_t s; | ||||
| 	uint8_t v; | ||||
| typedef struct PACKED { | ||||
|     uint8_t h; | ||||
|     uint8_t s; | ||||
|     uint8_t v; | ||||
| } HSV; | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
| #pragma pack( pop ) | ||||
| #    pragma pack(pop) | ||||
| #endif | ||||
| 
 | ||||
| RGB hsv_to_rgb(HSV hsv); | ||||
| 
 | ||||
| #endif // COLOR_H
 | ||||
| #endif  // COLOR_H
 | ||||
|  |  | |||
|  | @ -17,294 +17,295 @@ | |||
| #pragma once | ||||
| 
 | ||||
| /* diode directions */ | ||||
| #define COL2ROW       0 | ||||
| #define ROW2COL       1 | ||||
| #define COL2ROW 0 | ||||
| #define ROW2COL 1 | ||||
| #define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */ | ||||
| 
 | ||||
| // useful for direct pin mapping
 | ||||
| #define NO_PIN (~0) | ||||
| 
 | ||||
| #ifdef __AVR__ | ||||
|     #ifndef __ASSEMBLER__ | ||||
|       #include <avr/io.h> | ||||
|     #endif | ||||
|     #define PORT_SHIFTER 4 // this may be 4 for all AVR chips
 | ||||
| #    ifndef __ASSEMBLER__ | ||||
| #        include <avr/io.h> | ||||
| #    endif | ||||
| #    define PORT_SHIFTER 4  // this may be 4 for all AVR chips
 | ||||
| 
 | ||||
|     // If you want to add more to this list, reference the PINx definitions in these header
 | ||||
|     // files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
 | ||||
| // If you want to add more to this list, reference the PINx definitions in these header
 | ||||
| // files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
 | ||||
| 
 | ||||
|     #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) | ||||
|         #define ADDRESS_BASE 0x00 | ||||
|         #define PINB_ADDRESS 0x3 | ||||
|         #define PINC_ADDRESS 0x6 | ||||
|         #define PIND_ADDRESS 0x9 | ||||
|         #define PINE_ADDRESS 0xC | ||||
|         #define PINF_ADDRESS 0xF | ||||
|     #elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) | ||||
|         #define ADDRESS_BASE 0x00 | ||||
|         #define PINB_ADDRESS 0x3 | ||||
|         #define PINC_ADDRESS 0x6 | ||||
|         #define PIND_ADDRESS 0x9 | ||||
|     #elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) | ||||
|         #define ADDRESS_BASE 0x00 | ||||
|         #define PINA_ADDRESS 0x0 | ||||
|         #define PINB_ADDRESS 0x3 | ||||
|         #define PINC_ADDRESS 0x6 | ||||
|         #define PIND_ADDRESS 0x9 | ||||
|         #define PINE_ADDRESS 0xC | ||||
|         #define PINF_ADDRESS 0xF | ||||
|     #elif defined(__AVR_ATmega32A__) | ||||
|         #define ADDRESS_BASE 0x10 | ||||
|         #define PIND_ADDRESS 0x0 | ||||
|         #define PINC_ADDRESS 0x3 | ||||
|         #define PINB_ADDRESS 0x6 | ||||
|         #define PINA_ADDRESS 0x9 | ||||
|     #elif defined(__AVR_ATmega328P__) | ||||
|         #define ADDRESS_BASE 0x00 | ||||
|         #define PINB_ADDRESS 0x3 | ||||
|         #define PINC_ADDRESS 0x6 | ||||
|         #define PIND_ADDRESS 0x9 | ||||
|     #else | ||||
|         #error "Pins are not defined" | ||||
|     #endif | ||||
| #    if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) | ||||
| #        define ADDRESS_BASE 0x00 | ||||
| #        define PINB_ADDRESS 0x3 | ||||
| #        define PINC_ADDRESS 0x6 | ||||
| #        define PIND_ADDRESS 0x9 | ||||
| #        define PINE_ADDRESS 0xC | ||||
| #        define PINF_ADDRESS 0xF | ||||
| #    elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) | ||||
| #        define ADDRESS_BASE 0x00 | ||||
| #        define PINB_ADDRESS 0x3 | ||||
| #        define PINC_ADDRESS 0x6 | ||||
| #        define PIND_ADDRESS 0x9 | ||||
| #    elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) | ||||
| #        define ADDRESS_BASE 0x00 | ||||
| #        define PINA_ADDRESS 0x0 | ||||
| #        define PINB_ADDRESS 0x3 | ||||
| #        define PINC_ADDRESS 0x6 | ||||
| #        define PIND_ADDRESS 0x9 | ||||
| #        define PINE_ADDRESS 0xC | ||||
| #        define PINF_ADDRESS 0xF | ||||
| #    elif defined(__AVR_ATmega32A__) | ||||
| #        define ADDRESS_BASE 0x10 | ||||
| #        define PIND_ADDRESS 0x0 | ||||
| #        define PINC_ADDRESS 0x3 | ||||
| #        define PINB_ADDRESS 0x6 | ||||
| #        define PINA_ADDRESS 0x9 | ||||
| #    elif defined(__AVR_ATmega328P__) | ||||
| #        define ADDRESS_BASE 0x00 | ||||
| #        define PINB_ADDRESS 0x3 | ||||
| #        define PINC_ADDRESS 0x6 | ||||
| #        define PIND_ADDRESS 0x9 | ||||
| #    else | ||||
| #        error "Pins are not defined" | ||||
| #    endif | ||||
| 
 | ||||
|     /* I/O pins */ | ||||
|     #define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin) | ||||
| /* I/O pins */ | ||||
| #    define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin) | ||||
| 
 | ||||
|     #ifdef PORTA | ||||
|         #define A0 PINDEF(A, 0) | ||||
|         #define A1 PINDEF(A, 1) | ||||
|         #define A2 PINDEF(A, 2) | ||||
|         #define A3 PINDEF(A, 3) | ||||
|         #define A4 PINDEF(A, 4) | ||||
|         #define A5 PINDEF(A, 5) | ||||
|         #define A6 PINDEF(A, 6) | ||||
|         #define A7 PINDEF(A, 7) | ||||
|     #endif | ||||
|     #ifdef PORTB | ||||
|         #define B0 PINDEF(B, 0) | ||||
|         #define B1 PINDEF(B, 1) | ||||
|         #define B2 PINDEF(B, 2) | ||||
|         #define B3 PINDEF(B, 3) | ||||
|         #define B4 PINDEF(B, 4) | ||||
|         #define B5 PINDEF(B, 5) | ||||
|         #define B6 PINDEF(B, 6) | ||||
|         #define B7 PINDEF(B, 7) | ||||
|     #endif | ||||
|     #ifdef PORTC | ||||
|         #define C0 PINDEF(C, 0) | ||||
|         #define C1 PINDEF(C, 1) | ||||
|         #define C2 PINDEF(C, 2) | ||||
|         #define C3 PINDEF(C, 3) | ||||
|         #define C4 PINDEF(C, 4) | ||||
|         #define C5 PINDEF(C, 5) | ||||
|         #define C6 PINDEF(C, 6) | ||||
|         #define C7 PINDEF(C, 7) | ||||
|     #endif | ||||
|     #ifdef PORTD | ||||
|         #define D0 PINDEF(D, 0) | ||||
|         #define D1 PINDEF(D, 1) | ||||
|         #define D2 PINDEF(D, 2) | ||||
|         #define D3 PINDEF(D, 3) | ||||
|         #define D4 PINDEF(D, 4) | ||||
|         #define D5 PINDEF(D, 5) | ||||
|         #define D6 PINDEF(D, 6) | ||||
|         #define D7 PINDEF(D, 7) | ||||
|     #endif | ||||
|     #ifdef PORTE | ||||
|         #define E0 PINDEF(E, 0) | ||||
|         #define E1 PINDEF(E, 1) | ||||
|         #define E2 PINDEF(E, 2) | ||||
|         #define E3 PINDEF(E, 3) | ||||
|         #define E4 PINDEF(E, 4) | ||||
|         #define E5 PINDEF(E, 5) | ||||
|         #define E6 PINDEF(E, 6) | ||||
|         #define E7 PINDEF(E, 7) | ||||
|     #endif | ||||
|     #ifdef PORTF | ||||
|         #define F0 PINDEF(F, 0) | ||||
|         #define F1 PINDEF(F, 1) | ||||
|         #define F2 PINDEF(F, 2) | ||||
|         #define F3 PINDEF(F, 3) | ||||
|         #define F4 PINDEF(F, 4) | ||||
|         #define F5 PINDEF(F, 5) | ||||
|         #define F6 PINDEF(F, 6) | ||||
|         #define F7 PINDEF(F, 7) | ||||
|     #endif | ||||
| #    ifdef PORTA | ||||
| #        define A0 PINDEF(A, 0) | ||||
| #        define A1 PINDEF(A, 1) | ||||
| #        define A2 PINDEF(A, 2) | ||||
| #        define A3 PINDEF(A, 3) | ||||
| #        define A4 PINDEF(A, 4) | ||||
| #        define A5 PINDEF(A, 5) | ||||
| #        define A6 PINDEF(A, 6) | ||||
| #        define A7 PINDEF(A, 7) | ||||
| #    endif | ||||
| #    ifdef PORTB | ||||
| #        define B0 PINDEF(B, 0) | ||||
| #        define B1 PINDEF(B, 1) | ||||
| #        define B2 PINDEF(B, 2) | ||||
| #        define B3 PINDEF(B, 3) | ||||
| #        define B4 PINDEF(B, 4) | ||||
| #        define B5 PINDEF(B, 5) | ||||
| #        define B6 PINDEF(B, 6) | ||||
| #        define B7 PINDEF(B, 7) | ||||
| #    endif | ||||
| #    ifdef PORTC | ||||
| #        define C0 PINDEF(C, 0) | ||||
| #        define C1 PINDEF(C, 1) | ||||
| #        define C2 PINDEF(C, 2) | ||||
| #        define C3 PINDEF(C, 3) | ||||
| #        define C4 PINDEF(C, 4) | ||||
| #        define C5 PINDEF(C, 5) | ||||
| #        define C6 PINDEF(C, 6) | ||||
| #        define C7 PINDEF(C, 7) | ||||
| #    endif | ||||
| #    ifdef PORTD | ||||
| #        define D0 PINDEF(D, 0) | ||||
| #        define D1 PINDEF(D, 1) | ||||
| #        define D2 PINDEF(D, 2) | ||||
| #        define D3 PINDEF(D, 3) | ||||
| #        define D4 PINDEF(D, 4) | ||||
| #        define D5 PINDEF(D, 5) | ||||
| #        define D6 PINDEF(D, 6) | ||||
| #        define D7 PINDEF(D, 7) | ||||
| #    endif | ||||
| #    ifdef PORTE | ||||
| #        define E0 PINDEF(E, 0) | ||||
| #        define E1 PINDEF(E, 1) | ||||
| #        define E2 PINDEF(E, 2) | ||||
| #        define E3 PINDEF(E, 3) | ||||
| #        define E4 PINDEF(E, 4) | ||||
| #        define E5 PINDEF(E, 5) | ||||
| #        define E6 PINDEF(E, 6) | ||||
| #        define E7 PINDEF(E, 7) | ||||
| #    endif | ||||
| #    ifdef PORTF | ||||
| #        define F0 PINDEF(F, 0) | ||||
| #        define F1 PINDEF(F, 1) | ||||
| #        define F2 PINDEF(F, 2) | ||||
| #        define F3 PINDEF(F, 3) | ||||
| #        define F4 PINDEF(F, 4) | ||||
| #        define F5 PINDEF(F, 5) | ||||
| #        define F6 PINDEF(F, 6) | ||||
| #        define F7 PINDEF(F, 7) | ||||
| #    endif | ||||
| 
 | ||||
|   #ifndef __ASSEMBLER__ | ||||
|     #define _PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset) | ||||
|     // Port X Input Pins Address
 | ||||
|     #define PINx_ADDRESS(p)  _PIN_ADDRESS(p, 0) | ||||
|     // Port X Data Direction Register,  0:input 1:output
 | ||||
|     #define DDRx_ADDRESS(p)  _PIN_ADDRESS(p, 1) | ||||
|     // Port X Data Register
 | ||||
|     #define PORTx_ADDRESS(p) _PIN_ADDRESS(p, 2) | ||||
|   #endif | ||||
| #    ifndef __ASSEMBLER__ | ||||
| #        define _PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset) | ||||
| // Port X Input Pins Address
 | ||||
| #        define PINx_ADDRESS(p) _PIN_ADDRESS(p, 0) | ||||
| // Port X Data Direction Register,  0:input 1:output
 | ||||
| #        define DDRx_ADDRESS(p) _PIN_ADDRESS(p, 1) | ||||
| // Port X Data Register
 | ||||
| #        define PORTx_ADDRESS(p) _PIN_ADDRESS(p, 2) | ||||
| #    endif | ||||
| 
 | ||||
| #elif defined(PROTOCOL_CHIBIOS) | ||||
|   // Defines mapping for Proton C replacement
 | ||||
|   #ifdef CONVERT_TO_PROTON_C | ||||
|     // Left side (front)
 | ||||
|     #define D3 PAL_LINE(GPIOA, 9) | ||||
|     #define D2 PAL_LINE(GPIOA, 10) | ||||
|     //      GND
 | ||||
|     //      GND
 | ||||
|     #define D1 PAL_LINE(GPIOB, 7) | ||||
|     #define D0 PAL_LINE(GPIOB, 6) | ||||
|     #define D4 PAL_LINE(GPIOB, 5) | ||||
|     #define C6 PAL_LINE(GPIOB, 4) | ||||
|     #define D7 PAL_LINE(GPIOB, 3) | ||||
|     #define E6 PAL_LINE(GPIOB, 2) | ||||
|     #define B4 PAL_LINE(GPIOB, 1) | ||||
|     #define B5 PAL_LINE(GPIOB, 0) | ||||
| // Defines mapping for Proton C replacement
 | ||||
| #    ifdef CONVERT_TO_PROTON_C | ||||
| // Left side (front)
 | ||||
| #        define D3 PAL_LINE(GPIOA, 9) | ||||
| #        define D2 PAL_LINE(GPIOA, 10) | ||||
| //      GND
 | ||||
| //      GND
 | ||||
| #        define D1 PAL_LINE(GPIOB, 7) | ||||
| #        define D0 PAL_LINE(GPIOB, 6) | ||||
| #        define D4 PAL_LINE(GPIOB, 5) | ||||
| #        define C6 PAL_LINE(GPIOB, 4) | ||||
| #        define D7 PAL_LINE(GPIOB, 3) | ||||
| #        define E6 PAL_LINE(GPIOB, 2) | ||||
| #        define B4 PAL_LINE(GPIOB, 1) | ||||
| #        define B5 PAL_LINE(GPIOB, 0) | ||||
| 
 | ||||
|     // Right side (front)
 | ||||
|     //      RAW
 | ||||
|     //      GND
 | ||||
|     //      RESET
 | ||||
|     //      VCC
 | ||||
|     #define F4 PAL_LINE(GPIOA, 2) | ||||
|     #define F5 PAL_LINE(GPIOA, 1) | ||||
|     #define F6 PAL_LINE(GPIOA, 0) | ||||
|     #define F7 PAL_LINE(GPIOB, 8) | ||||
|     #define B1 PAL_LINE(GPIOB, 13) | ||||
|     #define B3 PAL_LINE(GPIOB, 14) | ||||
|     #define B2 PAL_LINE(GPIOB, 15) | ||||
|     #define B6 PAL_LINE(GPIOB, 9) | ||||
| // Right side (front)
 | ||||
| //      RAW
 | ||||
| //      GND
 | ||||
| //      RESET
 | ||||
| //      VCC
 | ||||
| #        define F4 PAL_LINE(GPIOA, 2) | ||||
| #        define F5 PAL_LINE(GPIOA, 1) | ||||
| #        define F6 PAL_LINE(GPIOA, 0) | ||||
| #        define F7 PAL_LINE(GPIOB, 8) | ||||
| #        define B1 PAL_LINE(GPIOB, 13) | ||||
| #        define B3 PAL_LINE(GPIOB, 14) | ||||
| #        define B2 PAL_LINE(GPIOB, 15) | ||||
| #        define B6 PAL_LINE(GPIOB, 9) | ||||
| 
 | ||||
|     // LEDs (only D5/C13 uses an actual LED)
 | ||||
|     #ifdef CONVERT_TO_PROTON_C_RXLED | ||||
|       #define D5 PAL_LINE(GPIOC, 13) | ||||
|       #define B0 PAL_LINE(GPIOC, 13) | ||||
|     #else | ||||
|       #define D5 PAL_LINE(GPIOC, 13) | ||||
|       #define B0 PAL_LINE(GPIOC, 14) | ||||
|     #endif | ||||
|   #else | ||||
|     #define A0  PAL_LINE(GPIOA, 0) | ||||
|     #define A1  PAL_LINE(GPIOA, 1) | ||||
|     #define A2  PAL_LINE(GPIOA, 2) | ||||
|     #define A3  PAL_LINE(GPIOA, 3) | ||||
|     #define A4  PAL_LINE(GPIOA, 4) | ||||
|     #define A5  PAL_LINE(GPIOA, 5) | ||||
|     #define A6  PAL_LINE(GPIOA, 6) | ||||
|     #define A7  PAL_LINE(GPIOA, 7) | ||||
|     #define A8  PAL_LINE(GPIOA, 8) | ||||
|     #define A9  PAL_LINE(GPIOA, 9) | ||||
|     #define A10 PAL_LINE(GPIOA, 10) | ||||
|     #define A11 PAL_LINE(GPIOA, 11) | ||||
|     #define A12 PAL_LINE(GPIOA, 12) | ||||
|     #define A13 PAL_LINE(GPIOA, 13) | ||||
|     #define A14 PAL_LINE(GPIOA, 14) | ||||
|     #define A15 PAL_LINE(GPIOA, 15) | ||||
|     #define B0  PAL_LINE(GPIOB, 0) | ||||
|     #define B1  PAL_LINE(GPIOB, 1) | ||||
|     #define B2  PAL_LINE(GPIOB, 2) | ||||
|     #define B3  PAL_LINE(GPIOB, 3) | ||||
|     #define B4  PAL_LINE(GPIOB, 4) | ||||
|     #define B5  PAL_LINE(GPIOB, 5) | ||||
|     #define B6  PAL_LINE(GPIOB, 6) | ||||
|     #define B7  PAL_LINE(GPIOB, 7) | ||||
|     #define B8  PAL_LINE(GPIOB, 8) | ||||
|     #define B9  PAL_LINE(GPIOB, 9) | ||||
|     #define B10 PAL_LINE(GPIOB, 10) | ||||
|     #define B11 PAL_LINE(GPIOB, 11) | ||||
|     #define B12 PAL_LINE(GPIOB, 12) | ||||
|     #define B13 PAL_LINE(GPIOB, 13) | ||||
|     #define B14 PAL_LINE(GPIOB, 14) | ||||
|     #define B15 PAL_LINE(GPIOB, 15) | ||||
|     #define B16 PAL_LINE(GPIOB, 16) | ||||
|     #define B17 PAL_LINE(GPIOB, 17) | ||||
|     #define C0  PAL_LINE(GPIOC, 0) | ||||
|     #define C1  PAL_LINE(GPIOC, 1) | ||||
|     #define C2  PAL_LINE(GPIOC, 2) | ||||
|     #define C3  PAL_LINE(GPIOC, 3) | ||||
|     #define C4  PAL_LINE(GPIOC, 4) | ||||
|     #define C5  PAL_LINE(GPIOC, 5) | ||||
|     #define C6  PAL_LINE(GPIOC, 6) | ||||
|     #define C7  PAL_LINE(GPIOC, 7) | ||||
|     #define C8  PAL_LINE(GPIOC, 8) | ||||
|     #define C9  PAL_LINE(GPIOC, 9) | ||||
|     #define C10 PAL_LINE(GPIOC, 10) | ||||
|     #define C11 PAL_LINE(GPIOC, 11) | ||||
|     #define C12 PAL_LINE(GPIOC, 12) | ||||
|     #define C13 PAL_LINE(GPIOC, 13) | ||||
|     #define C14 PAL_LINE(GPIOC, 14) | ||||
|     #define C15 PAL_LINE(GPIOC, 15) | ||||
|     #define D0  PAL_LINE(GPIOD, 0) | ||||
|     #define D1  PAL_LINE(GPIOD, 1) | ||||
|     #define D2  PAL_LINE(GPIOD, 2) | ||||
|     #define D3  PAL_LINE(GPIOD, 3) | ||||
|     #define D4  PAL_LINE(GPIOD, 4) | ||||
|     #define D5  PAL_LINE(GPIOD, 5) | ||||
|     #define D6  PAL_LINE(GPIOD, 6) | ||||
|     #define D7  PAL_LINE(GPIOD, 7) | ||||
|     #define D8  PAL_LINE(GPIOD, 8) | ||||
|     #define D9  PAL_LINE(GPIOD, 9) | ||||
|     #define D10 PAL_LINE(GPIOD, 10) | ||||
|     #define D11 PAL_LINE(GPIOD, 11) | ||||
|     #define D12 PAL_LINE(GPIOD, 12) | ||||
|     #define D13 PAL_LINE(GPIOD, 13) | ||||
|     #define D14 PAL_LINE(GPIOD, 14) | ||||
|     #define D15 PAL_LINE(GPIOD, 15) | ||||
|     #define E0  PAL_LINE(GPIOE, 0) | ||||
|     #define E1  PAL_LINE(GPIOE, 1) | ||||
|     #define E2  PAL_LINE(GPIOE, 2) | ||||
|     #define E3  PAL_LINE(GPIOE, 3) | ||||
|     #define E4  PAL_LINE(GPIOE, 4) | ||||
|     #define E5  PAL_LINE(GPIOE, 5) | ||||
|     #define E6  PAL_LINE(GPIOE, 6) | ||||
|     #define E7  PAL_LINE(GPIOE, 7) | ||||
|     #define E8  PAL_LINE(GPIOE, 8) | ||||
|     #define E9  PAL_LINE(GPIOE, 9) | ||||
|     #define E10 PAL_LINE(GPIOE, 10) | ||||
|     #define E11 PAL_LINE(GPIOE, 11) | ||||
|     #define E12 PAL_LINE(GPIOE, 12) | ||||
|     #define E13 PAL_LINE(GPIOE, 13) | ||||
|     #define E14 PAL_LINE(GPIOE, 14) | ||||
|     #define E15 PAL_LINE(GPIOE, 15) | ||||
|     #define F0  PAL_LINE(GPIOF, 0) | ||||
|     #define F1  PAL_LINE(GPIOF, 1) | ||||
|     #define F2  PAL_LINE(GPIOF, 2) | ||||
|     #define F3  PAL_LINE(GPIOF, 3) | ||||
|     #define F4  PAL_LINE(GPIOF, 4) | ||||
|     #define F5  PAL_LINE(GPIOF, 5) | ||||
|     #define F6  PAL_LINE(GPIOF, 6) | ||||
|     #define F7  PAL_LINE(GPIOF, 7) | ||||
|     #define F8  PAL_LINE(GPIOF, 8) | ||||
|     #define F9  PAL_LINE(GPIOF, 9) | ||||
|     #define F10 PAL_LINE(GPIOF, 10) | ||||
|     #define F11 PAL_LINE(GPIOF, 11) | ||||
|     #define F12 PAL_LINE(GPIOF, 12) | ||||
|     #define F13 PAL_LINE(GPIOF, 13) | ||||
|     #define F14 PAL_LINE(GPIOF, 14) | ||||
|     #define F15 PAL_LINE(GPIOF, 15) | ||||
|   #endif | ||||
| // LEDs (only D5/C13 uses an actual LED)
 | ||||
| #        ifdef CONVERT_TO_PROTON_C_RXLED | ||||
| #            define D5 PAL_LINE(GPIOC, 13) | ||||
| #            define B0 PAL_LINE(GPIOC, 13) | ||||
| #        else | ||||
| #            define D5 PAL_LINE(GPIOC, 13) | ||||
| #            define B0 PAL_LINE(GPIOC, 14) | ||||
| #        endif | ||||
| #    else | ||||
| #        define A0 PAL_LINE(GPIOA, 0) | ||||
| #        define A1 PAL_LINE(GPIOA, 1) | ||||
| #        define A2 PAL_LINE(GPIOA, 2) | ||||
| #        define A3 PAL_LINE(GPIOA, 3) | ||||
| #        define A4 PAL_LINE(GPIOA, 4) | ||||
| #        define A5 PAL_LINE(GPIOA, 5) | ||||
| #        define A6 PAL_LINE(GPIOA, 6) | ||||
| #        define A7 PAL_LINE(GPIOA, 7) | ||||
| #        define A8 PAL_LINE(GPIOA, 8) | ||||
| #        define A9 PAL_LINE(GPIOA, 9) | ||||
| #        define A10 PAL_LINE(GPIOA, 10) | ||||
| #        define A11 PAL_LINE(GPIOA, 11) | ||||
| #        define A12 PAL_LINE(GPIOA, 12) | ||||
| #        define A13 PAL_LINE(GPIOA, 13) | ||||
| #        define A14 PAL_LINE(GPIOA, 14) | ||||
| #        define A15 PAL_LINE(GPIOA, 15) | ||||
| #        define B0 PAL_LINE(GPIOB, 0) | ||||
| #        define B1 PAL_LINE(GPIOB, 1) | ||||
| #        define B2 PAL_LINE(GPIOB, 2) | ||||
| #        define B3 PAL_LINE(GPIOB, 3) | ||||
| #        define B4 PAL_LINE(GPIOB, 4) | ||||
| #        define B5 PAL_LINE(GPIOB, 5) | ||||
| #        define B6 PAL_LINE(GPIOB, 6) | ||||
| #        define B7 PAL_LINE(GPIOB, 7) | ||||
| #        define B8 PAL_LINE(GPIOB, 8) | ||||
| #        define B9 PAL_LINE(GPIOB, 9) | ||||
| #        define B10 PAL_LINE(GPIOB, 10) | ||||
| #        define B11 PAL_LINE(GPIOB, 11) | ||||
| #        define B12 PAL_LINE(GPIOB, 12) | ||||
| #        define B13 PAL_LINE(GPIOB, 13) | ||||
| #        define B14 PAL_LINE(GPIOB, 14) | ||||
| #        define B15 PAL_LINE(GPIOB, 15) | ||||
| #        define B16 PAL_LINE(GPIOB, 16) | ||||
| #        define B17 PAL_LINE(GPIOB, 17) | ||||
| #        define C0 PAL_LINE(GPIOC, 0) | ||||
| #        define C1 PAL_LINE(GPIOC, 1) | ||||
| #        define C2 PAL_LINE(GPIOC, 2) | ||||
| #        define C3 PAL_LINE(GPIOC, 3) | ||||
| #        define C4 PAL_LINE(GPIOC, 4) | ||||
| #        define C5 PAL_LINE(GPIOC, 5) | ||||
| #        define C6 PAL_LINE(GPIOC, 6) | ||||
| #        define C7 PAL_LINE(GPIOC, 7) | ||||
| #        define C8 PAL_LINE(GPIOC, 8) | ||||
| #        define C9 PAL_LINE(GPIOC, 9) | ||||
| #        define C10 PAL_LINE(GPIOC, 10) | ||||
| #        define C11 PAL_LINE(GPIOC, 11) | ||||
| #        define C12 PAL_LINE(GPIOC, 12) | ||||
| #        define C13 PAL_LINE(GPIOC, 13) | ||||
| #        define C14 PAL_LINE(GPIOC, 14) | ||||
| #        define C15 PAL_LINE(GPIOC, 15) | ||||
| #        define D0 PAL_LINE(GPIOD, 0) | ||||
| #        define D1 PAL_LINE(GPIOD, 1) | ||||
| #        define D2 PAL_LINE(GPIOD, 2) | ||||
| #        define D3 PAL_LINE(GPIOD, 3) | ||||
| #        define D4 PAL_LINE(GPIOD, 4) | ||||
| #        define D5 PAL_LINE(GPIOD, 5) | ||||
| #        define D6 PAL_LINE(GPIOD, 6) | ||||
| #        define D7 PAL_LINE(GPIOD, 7) | ||||
| #        define D8 PAL_LINE(GPIOD, 8) | ||||
| #        define D9 PAL_LINE(GPIOD, 9) | ||||
| #        define D10 PAL_LINE(GPIOD, 10) | ||||
| #        define D11 PAL_LINE(GPIOD, 11) | ||||
| #        define D12 PAL_LINE(GPIOD, 12) | ||||
| #        define D13 PAL_LINE(GPIOD, 13) | ||||
| #        define D14 PAL_LINE(GPIOD, 14) | ||||
| #        define D15 PAL_LINE(GPIOD, 15) | ||||
| #        define E0 PAL_LINE(GPIOE, 0) | ||||
| #        define E1 PAL_LINE(GPIOE, 1) | ||||
| #        define E2 PAL_LINE(GPIOE, 2) | ||||
| #        define E3 PAL_LINE(GPIOE, 3) | ||||
| #        define E4 PAL_LINE(GPIOE, 4) | ||||
| #        define E5 PAL_LINE(GPIOE, 5) | ||||
| #        define E6 PAL_LINE(GPIOE, 6) | ||||
| #        define E7 PAL_LINE(GPIOE, 7) | ||||
| #        define E8 PAL_LINE(GPIOE, 8) | ||||
| #        define E9 PAL_LINE(GPIOE, 9) | ||||
| #        define E10 PAL_LINE(GPIOE, 10) | ||||
| #        define E11 PAL_LINE(GPIOE, 11) | ||||
| #        define E12 PAL_LINE(GPIOE, 12) | ||||
| #        define E13 PAL_LINE(GPIOE, 13) | ||||
| #        define E14 PAL_LINE(GPIOE, 14) | ||||
| #        define E15 PAL_LINE(GPIOE, 15) | ||||
| #        define F0 PAL_LINE(GPIOF, 0) | ||||
| #        define F1 PAL_LINE(GPIOF, 1) | ||||
| #        define F2 PAL_LINE(GPIOF, 2) | ||||
| #        define F3 PAL_LINE(GPIOF, 3) | ||||
| #        define F4 PAL_LINE(GPIOF, 4) | ||||
| #        define F5 PAL_LINE(GPIOF, 5) | ||||
| #        define F6 PAL_LINE(GPIOF, 6) | ||||
| #        define F7 PAL_LINE(GPIOF, 7) | ||||
| #        define F8 PAL_LINE(GPIOF, 8) | ||||
| #        define F9 PAL_LINE(GPIOF, 9) | ||||
| #        define F10 PAL_LINE(GPIOF, 10) | ||||
| #        define F11 PAL_LINE(GPIOF, 11) | ||||
| #        define F12 PAL_LINE(GPIOF, 12) | ||||
| #        define F13 PAL_LINE(GPIOF, 13) | ||||
| #        define F14 PAL_LINE(GPIOF, 14) | ||||
| #        define F15 PAL_LINE(GPIOF, 15) | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| /* USART configuration */ | ||||
| #ifdef BLUETOOTH_ENABLE | ||||
| #   ifdef __AVR_ATmega32U4__ | ||||
| #      define SERIAL_UART_BAUD 9600 | ||||
| #      define SERIAL_UART_DATA UDR1 | ||||
| #      define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) | ||||
| #      define SERIAL_UART_RXD_VECT USART1_RX_vect | ||||
| #      define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) | ||||
| #      define SERIAL_UART_INIT() do { \ | ||||
|             /* baud rate */ \ | ||||
|             UBRR1L = SERIAL_UART_UBRR; \ | ||||
|             /* baud rate */ \ | ||||
|             UBRR1H = SERIAL_UART_UBRR >> 8; \ | ||||
|             /* enable TX */ \ | ||||
|             UCSR1B = _BV(TXEN1); \ | ||||
|             /* 8-bit data */ \ | ||||
|             UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ | ||||
|             sei(); \ | ||||
|         } while(0) | ||||
| #   else | ||||
| #       error "USART configuration is needed." | ||||
| #   endif | ||||
| #    ifdef __AVR_ATmega32U4__ | ||||
| #        define SERIAL_UART_BAUD 9600 | ||||
| #        define SERIAL_UART_DATA UDR1 | ||||
| #        define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) | ||||
| #        define SERIAL_UART_RXD_VECT USART1_RX_vect | ||||
| #        define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) | ||||
| #        define SERIAL_UART_INIT()                  \ | ||||
|             do {                                    \ | ||||
|                 /* baud rate */                     \ | ||||
|                 UBRR1L = SERIAL_UART_UBRR;          \ | ||||
|                 /* baud rate */                     \ | ||||
|                 UBRR1H = SERIAL_UART_UBRR >> 8;     \ | ||||
|                 /* enable TX */                     \ | ||||
|                 UCSR1B = _BV(TXEN1);                \ | ||||
|                 /* 8-bit data */                    \ | ||||
|                 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ | ||||
|                 sei();                              \ | ||||
|             } while (0) | ||||
| #    else | ||||
| #        error "USART configuration is needed." | ||||
| #    endif | ||||
| #endif | ||||
| 
 | ||||
| #define API_SYSEX_MAX_SIZE 32 | ||||
|  |  | |||
|  | @ -24,15 +24,15 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred. | |||
| #include <stdlib.h> | ||||
| 
 | ||||
| #ifndef DEBOUNCE | ||||
| #  define DEBOUNCE 5 | ||||
| #    define DEBOUNCE 5 | ||||
| #endif | ||||
| 
 | ||||
| #if (MATRIX_COLS <= 8) | ||||
| #  define ROW_SHIFTER ((uint8_t)1) | ||||
| #    define ROW_SHIFTER ((uint8_t)1) | ||||
| #elif (MATRIX_COLS <= 16) | ||||
| #  define ROW_SHIFTER ((uint16_t)1) | ||||
| #    define ROW_SHIFTER ((uint16_t)1) | ||||
| #elif (MATRIX_COLS <= 32) | ||||
| #  define ROW_SHIFTER ((uint32_t)1) | ||||
| #    define ROW_SHIFTER ((uint32_t)1) | ||||
| #endif | ||||
| 
 | ||||
| #define debounce_counter_t uint8_t | ||||
|  | @ -49,66 +49,66 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n | |||
| 
 | ||||
| // we use num_rows rather than MATRIX_ROWS to support split keyboards
 | ||||
| void debounce_init(uint8_t num_rows) { | ||||
|   debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); | ||||
|   int i             = 0; | ||||
|   for (uint8_t r = 0; r < num_rows; r++) { | ||||
|     for (uint8_t c = 0; c < MATRIX_COLS; c++) { | ||||
|       debounce_counters[i++] = DEBOUNCE_ELAPSED; | ||||
|     debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); | ||||
|     int i             = 0; | ||||
|     for (uint8_t r = 0; r < num_rows; r++) { | ||||
|         for (uint8_t c = 0; c < MATRIX_COLS; c++) { | ||||
|             debounce_counters[i++] = DEBOUNCE_ELAPSED; | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { | ||||
|   uint8_t current_time = timer_read() % MAX_DEBOUNCE; | ||||
|   if (counters_need_update) { | ||||
|     update_debounce_counters(num_rows, current_time); | ||||
|   } | ||||
|     uint8_t current_time = timer_read() % MAX_DEBOUNCE; | ||||
|     if (counters_need_update) { | ||||
|         update_debounce_counters(num_rows, current_time); | ||||
|     } | ||||
| 
 | ||||
|   if (changed || matrix_need_update) { | ||||
|     transfer_matrix_values(raw, cooked, num_rows, current_time); | ||||
|   } | ||||
|     if (changed || matrix_need_update) { | ||||
|         transfer_matrix_values(raw, cooked, num_rows, current_time); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // If the current time is > debounce counter, set the counter to enable input.
 | ||||
| void update_debounce_counters(uint8_t num_rows, uint8_t current_time) { | ||||
|   counters_need_update                 = false; | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < num_rows; row++) { | ||||
|     for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||
|       if (*debounce_pointer != DEBOUNCE_ELAPSED) { | ||||
|         if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { | ||||
|           *debounce_pointer = DEBOUNCE_ELAPSED; | ||||
|         } else { | ||||
|           counters_need_update = true; | ||||
|     counters_need_update                 = false; | ||||
|     debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|     for (uint8_t row = 0; row < num_rows; row++) { | ||||
|         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||
|             if (*debounce_pointer != DEBOUNCE_ELAPSED) { | ||||
|                 if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { | ||||
|                     *debounce_pointer = DEBOUNCE_ELAPSED; | ||||
|                 } else { | ||||
|                     counters_need_update = true; | ||||
|                 } | ||||
|             } | ||||
|             debounce_pointer++; | ||||
|         } | ||||
|       } | ||||
|       debounce_pointer++; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // upload from raw_matrix to final matrix;
 | ||||
| void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) { | ||||
|   matrix_need_update = false; | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < num_rows; row++) { | ||||
|     matrix_row_t delta        = raw[row] ^ cooked[row]; | ||||
|     matrix_row_t existing_row = cooked[row]; | ||||
|     for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||
|       matrix_row_t col_mask = (ROW_SHIFTER << col); | ||||
|       if (delta & col_mask) { | ||||
|         if (*debounce_pointer == DEBOUNCE_ELAPSED) { | ||||
|           *debounce_pointer    = current_time; | ||||
|           counters_need_update = true; | ||||
|           existing_row ^= col_mask;  // flip the bit.
 | ||||
|         } else { | ||||
|           matrix_need_update = true; | ||||
|     matrix_need_update                   = false; | ||||
|     debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|     for (uint8_t row = 0; row < num_rows; row++) { | ||||
|         matrix_row_t delta        = raw[row] ^ cooked[row]; | ||||
|         matrix_row_t existing_row = cooked[row]; | ||||
|         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||
|             matrix_row_t col_mask = (ROW_SHIFTER << col); | ||||
|             if (delta & col_mask) { | ||||
|                 if (*debounce_pointer == DEBOUNCE_ELAPSED) { | ||||
|                     *debounce_pointer    = current_time; | ||||
|                     counters_need_update = true; | ||||
|                     existing_row ^= col_mask;  // flip the bit.
 | ||||
|                 } else { | ||||
|                     matrix_need_update = true; | ||||
|                 } | ||||
|             } | ||||
|             debounce_pointer++; | ||||
|         } | ||||
|       } | ||||
|       debounce_pointer++; | ||||
|         cooked[row] = existing_row; | ||||
|     } | ||||
|     cooked[row] = existing_row; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| bool debounce_active(void) { return true; } | ||||
|  |  | |||
|  | @ -24,11 +24,11 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred. | |||
| #include <stdlib.h> | ||||
| 
 | ||||
| #ifndef DEBOUNCE | ||||
| #  define DEBOUNCE 5 | ||||
| #    define DEBOUNCE 5 | ||||
| #endif | ||||
| 
 | ||||
| #define debounce_counter_t uint8_t | ||||
| static bool                matrix_need_update; | ||||
| static bool matrix_need_update; | ||||
| 
 | ||||
| static debounce_counter_t *debounce_counters; | ||||
| static bool                counters_need_update; | ||||
|  | @ -41,60 +41,60 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n | |||
| 
 | ||||
| // we use num_rows rather than MATRIX_ROWS to support split keyboards
 | ||||
| void debounce_init(uint8_t num_rows) { | ||||
|   debounce_counters = (debounce_counter_t *)malloc(num_rows * sizeof(debounce_counter_t)); | ||||
|   for (uint8_t r = 0; r < num_rows; r++) { | ||||
|     debounce_counters[r] = DEBOUNCE_ELAPSED; | ||||
|   } | ||||
|     debounce_counters = (debounce_counter_t *)malloc(num_rows * sizeof(debounce_counter_t)); | ||||
|     for (uint8_t r = 0; r < num_rows; r++) { | ||||
|         debounce_counters[r] = DEBOUNCE_ELAPSED; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { | ||||
|   uint8_t current_time = timer_read() % MAX_DEBOUNCE; | ||||
|   bool needed_update = counters_need_update; | ||||
|   if (counters_need_update) { | ||||
|     update_debounce_counters(num_rows, current_time); | ||||
|   } | ||||
|     uint8_t current_time  = timer_read() % MAX_DEBOUNCE; | ||||
|     bool    needed_update = counters_need_update; | ||||
|     if (counters_need_update) { | ||||
|         update_debounce_counters(num_rows, current_time); | ||||
|     } | ||||
| 
 | ||||
|   if (changed || (needed_update && !counters_need_update) || matrix_need_update) { | ||||
|     transfer_matrix_values(raw, cooked, num_rows, current_time); | ||||
|   } | ||||
|     if (changed || (needed_update && !counters_need_update) || matrix_need_update) { | ||||
|         transfer_matrix_values(raw, cooked, num_rows, current_time); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // If the current time is > debounce counter, set the counter to enable input.
 | ||||
| void update_debounce_counters(uint8_t num_rows, uint8_t current_time) { | ||||
|   counters_need_update                 = false; | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < num_rows; row++) { | ||||
|     if (*debounce_pointer != DEBOUNCE_ELAPSED) { | ||||
|       if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { | ||||
|         *debounce_pointer = DEBOUNCE_ELAPSED; | ||||
|       } else { | ||||
|         counters_need_update = true; | ||||
|       } | ||||
|     counters_need_update                 = false; | ||||
|     debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|     for (uint8_t row = 0; row < num_rows; row++) { | ||||
|         if (*debounce_pointer != DEBOUNCE_ELAPSED) { | ||||
|             if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { | ||||
|                 *debounce_pointer = DEBOUNCE_ELAPSED; | ||||
|             } else { | ||||
|                 counters_need_update = true; | ||||
|             } | ||||
|         } | ||||
|         debounce_pointer++; | ||||
|     } | ||||
|     debounce_pointer++; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // upload from raw_matrix to final matrix;
 | ||||
| void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) { | ||||
|   matrix_need_update = false; | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < num_rows; row++) { | ||||
|     matrix_row_t existing_row = cooked[row]; | ||||
|     matrix_row_t raw_row      = raw[row]; | ||||
|     matrix_need_update                   = false; | ||||
|     debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|     for (uint8_t row = 0; row < num_rows; row++) { | ||||
|         matrix_row_t existing_row = cooked[row]; | ||||
|         matrix_row_t raw_row      = raw[row]; | ||||
| 
 | ||||
|     // determine new value basd on debounce pointer + raw value
 | ||||
|     if (existing_row != raw_row) { | ||||
|       if (*debounce_pointer == DEBOUNCE_ELAPSED) { | ||||
|         *debounce_pointer    = current_time; | ||||
|         cooked[row]          = raw_row; | ||||
|         counters_need_update = true; | ||||
|       } else { | ||||
|         matrix_need_update = true; | ||||
|       } | ||||
|         // determine new value basd on debounce pointer + raw value
 | ||||
|         if (existing_row != raw_row) { | ||||
|             if (*debounce_pointer == DEBOUNCE_ELAPSED) { | ||||
|                 *debounce_pointer    = current_time; | ||||
|                 cooked[row]          = raw_row; | ||||
|                 counters_need_update = true; | ||||
|             } else { | ||||
|                 matrix_need_update = true; | ||||
|             } | ||||
|         } | ||||
|         debounce_pointer++; | ||||
|     } | ||||
|     debounce_pointer++; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| bool debounce_active(void) { return true; } | ||||
|  |  | |||
|  | @ -20,38 +20,33 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state. | |||
| #include "timer.h" | ||||
| #include "quantum.h" | ||||
| #ifndef DEBOUNCE | ||||
|   #define DEBOUNCE 5 | ||||
| #    define DEBOUNCE 5 | ||||
| #endif | ||||
| 
 | ||||
| void debounce_init(uint8_t num_rows) {} | ||||
| void        debounce_init(uint8_t num_rows) {} | ||||
| static bool debouncing = false; | ||||
| 
 | ||||
| #if DEBOUNCE > 0 | ||||
| static uint16_t debouncing_time; | ||||
| void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) | ||||
| { | ||||
|   if (changed) { | ||||
|     debouncing = true; | ||||
|     debouncing_time = timer_read(); | ||||
|   } | ||||
| 
 | ||||
|   if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { | ||||
|     for (int i = 0; i < num_rows; i++) { | ||||
|       cooked[i] = raw[i]; | ||||
| void            debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { | ||||
|     if (changed) { | ||||
|         debouncing      = true; | ||||
|         debouncing_time = timer_read(); | ||||
|     } | ||||
| 
 | ||||
|     if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { | ||||
|         for (int i = 0; i < num_rows; i++) { | ||||
|             cooked[i] = raw[i]; | ||||
|         } | ||||
|         debouncing = false; | ||||
|     } | ||||
|     debouncing = false; | ||||
|   } | ||||
| } | ||||
| #else //no debouncing.
 | ||||
| void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) | ||||
| { | ||||
|   for (int i = 0; i < num_rows; i++) { | ||||
|     cooked[i] = raw[i]; | ||||
|   } | ||||
| #else  // no debouncing.
 | ||||
| void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { | ||||
|     for (int i = 0; i < num_rows; i++) { | ||||
|         cooked[i] = raw[i]; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| bool debounce_active(void) { | ||||
|   return debouncing; | ||||
| } | ||||
| 
 | ||||
| bool debounce_active(void) { return debouncing; } | ||||
|  |  | |||
|  | @ -15,224 +15,198 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "config.h" | ||||
| #include "keymap.h" // to get keymaps[][][] | ||||
| #include "keymap.h"  // to get keymaps[][][] | ||||
| #include "tmk_core/common/eeprom.h" | ||||
| #include "progmem.h" // to read default from flash | ||||
| #include "quantum.h" // for send_string() | ||||
| #include "progmem.h"  // to read default from flash | ||||
| #include "quantum.h"  // for send_string() | ||||
| #include "dynamic_keymap.h" | ||||
| 
 | ||||
| #ifdef DYNAMIC_KEYMAP_ENABLE | ||||
| 
 | ||||
| #ifndef DYNAMIC_KEYMAP_EEPROM_ADDR | ||||
| #error DYNAMIC_KEYMAP_EEPROM_ADDR not defined | ||||
| #endif | ||||
| #    ifndef DYNAMIC_KEYMAP_EEPROM_ADDR | ||||
| #        error DYNAMIC_KEYMAP_EEPROM_ADDR not defined | ||||
| #    endif | ||||
| 
 | ||||
| #ifndef DYNAMIC_KEYMAP_LAYER_COUNT | ||||
| #error DYNAMIC_KEYMAP_LAYER_COUNT not defined | ||||
| #endif | ||||
| #    ifndef DYNAMIC_KEYMAP_LAYER_COUNT | ||||
| #        error DYNAMIC_KEYMAP_LAYER_COUNT not defined | ||||
| #    endif | ||||
| 
 | ||||
| #ifndef DYNAMIC_KEYMAP_MACRO_COUNT | ||||
| #error DYNAMIC_KEYMAP_MACRO_COUNT not defined | ||||
| #endif | ||||
| #    ifndef DYNAMIC_KEYMAP_MACRO_COUNT | ||||
| #        error DYNAMIC_KEYMAP_MACRO_COUNT not defined | ||||
| #    endif | ||||
| 
 | ||||
| #ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR | ||||
| #error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined | ||||
| #endif | ||||
| #    ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR | ||||
| #        error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined | ||||
| #    endif | ||||
| 
 | ||||
| #ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE | ||||
| #error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined | ||||
| #endif | ||||
| #    ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE | ||||
| #        error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined | ||||
| #    endif | ||||
| 
 | ||||
| uint8_t dynamic_keymap_get_layer_count(void) | ||||
| { | ||||
| 	return DYNAMIC_KEYMAP_LAYER_COUNT; | ||||
| uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; } | ||||
| 
 | ||||
| void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) { | ||||
|     // TODO: optimize this with some left shifts
 | ||||
|     return ((void *)DYNAMIC_KEYMAP_EEPROM_ADDR) + (layer * MATRIX_ROWS * MATRIX_COLS * 2) + (row * MATRIX_COLS * 2) + (column * 2); | ||||
| } | ||||
| 
 | ||||
| void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) | ||||
| { | ||||
| 	// TODO: optimize this with some left shifts
 | ||||
| 	return ((void*)DYNAMIC_KEYMAP_EEPROM_ADDR) + ( layer * MATRIX_ROWS * MATRIX_COLS * 2 ) + | ||||
| 		( row * MATRIX_COLS * 2 ) + ( column * 2 ); | ||||
| uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) { | ||||
|     void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); | ||||
|     // Big endian, so we can read/write EEPROM directly from host if we want
 | ||||
|     uint16_t keycode = eeprom_read_byte(address) << 8; | ||||
|     keycode |= eeprom_read_byte(address + 1); | ||||
|     return keycode; | ||||
| } | ||||
| 
 | ||||
| uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) | ||||
| { | ||||
| 	void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); | ||||
| 	// Big endian, so we can read/write EEPROM directly from host if we want
 | ||||
| 	uint16_t keycode = eeprom_read_byte(address) << 8; | ||||
| 	keycode |= eeprom_read_byte(address + 1); | ||||
| 	return keycode; | ||||
| void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) { | ||||
|     void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); | ||||
|     // Big endian, so we can read/write EEPROM directly from host if we want
 | ||||
|     eeprom_update_byte(address, (uint8_t)(keycode >> 8)); | ||||
|     eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF)); | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) | ||||
| { | ||||
| 	void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); | ||||
| 	// Big endian, so we can read/write EEPROM directly from host if we want
 | ||||
| 	eeprom_update_byte(address, (uint8_t)(keycode >> 8)); | ||||
| 	eeprom_update_byte(address+1, (uint8_t)(keycode & 0xFF)); | ||||
| void dynamic_keymap_reset(void) { | ||||
|     // Reset the keymaps in EEPROM to what is in flash.
 | ||||
|     // All keyboards using dynamic keymaps should define a layout
 | ||||
|     // for the same number of layers as DYNAMIC_KEYMAP_LAYER_COUNT.
 | ||||
|     for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { | ||||
|         for (int row = 0; row < MATRIX_ROWS; row++) { | ||||
|             for (int column = 0; column < MATRIX_COLS; column++) { | ||||
|                 dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column])); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_reset(void) | ||||
| { | ||||
| 	// Reset the keymaps in EEPROM to what is in flash.
 | ||||
| 	// All keyboards using dynamic keymaps should define a layout
 | ||||
| 	// for the same number of layers as DYNAMIC_KEYMAP_LAYER_COUNT.
 | ||||
| 	for ( int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++ )	{ | ||||
| 		for ( int row = 0; row < MATRIX_ROWS; row++ ) { | ||||
| 			for ( int column = 0; column < MATRIX_COLS; column++ )	{ | ||||
| 				dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column])); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { | ||||
|     uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; | ||||
|     void *   source                     = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset); | ||||
|     uint8_t *target                     = data; | ||||
|     for (uint16_t i = 0; i < size; i++) { | ||||
|         if (offset + i < dynamic_keymap_eeprom_size) { | ||||
|             *target = eeprom_read_byte(source); | ||||
|         } else { | ||||
|             *target = 0x00; | ||||
|         } | ||||
|         source++; | ||||
|         target++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ) | ||||
| { | ||||
| 	uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; | ||||
| 	void *source = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset); | ||||
| 	uint8_t *target = data; | ||||
| 	for ( uint16_t i = 0; i < size; i++ ) { | ||||
| 		if ( offset + i < dynamic_keymap_eeprom_size ) { | ||||
| 			*target = eeprom_read_byte(source); | ||||
| 		} else { | ||||
| 			*target = 0x00; | ||||
| 		} | ||||
| 		source++; | ||||
| 		target++; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ) | ||||
| { | ||||
| 	uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; | ||||
| 	void *target = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset); | ||||
| 	uint8_t *source = data; | ||||
| 	for ( uint16_t i = 0; i < size; i++ ) { | ||||
| 		if ( offset + i < dynamic_keymap_eeprom_size ) { | ||||
| 			eeprom_update_byte(target, *source); | ||||
| 		} | ||||
| 		source++; | ||||
| 		target++; | ||||
| 	} | ||||
| void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { | ||||
|     uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; | ||||
|     void *   target                     = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset); | ||||
|     uint8_t *source                     = data; | ||||
|     for (uint16_t i = 0; i < size; i++) { | ||||
|         if (offset + i < dynamic_keymap_eeprom_size) { | ||||
|             eeprom_update_byte(target, *source); | ||||
|         } | ||||
|         source++; | ||||
|         target++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // This overrides the one in quantum/keymap_common.c
 | ||||
| uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | ||||
| { | ||||
| 	if ( layer < DYNAMIC_KEYMAP_LAYER_COUNT && | ||||
| 			key.row < MATRIX_ROWS && | ||||
| 			key.col < MATRIX_COLS ) { | ||||
| 		return dynamic_keymap_get_keycode(layer, key.row, key.col); | ||||
| 	} else { | ||||
| 		return KC_NO; | ||||
| 	} | ||||
| uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { | ||||
|     if (layer < DYNAMIC_KEYMAP_LAYER_COUNT && key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { | ||||
|         return dynamic_keymap_get_keycode(layer, key.row, key.col); | ||||
|     } else { | ||||
|         return KC_NO; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint8_t dynamic_keymap_macro_get_count(void) { return DYNAMIC_KEYMAP_MACRO_COUNT; } | ||||
| 
 | ||||
| uint16_t dynamic_keymap_macro_get_buffer_size(void) { return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; } | ||||
| 
 | ||||
| uint8_t dynamic_keymap_macro_get_count(void) | ||||
| { | ||||
| 	return DYNAMIC_KEYMAP_MACRO_COUNT; | ||||
| void dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { | ||||
|     void *   source = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); | ||||
|     uint8_t *target = data; | ||||
|     for (uint16_t i = 0; i < size; i++) { | ||||
|         if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) { | ||||
|             *target = eeprom_read_byte(source); | ||||
|         } else { | ||||
|             *target = 0x00; | ||||
|         } | ||||
|         source++; | ||||
|         target++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint16_t dynamic_keymap_macro_get_buffer_size(void) | ||||
| { | ||||
| 	return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; | ||||
| void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { | ||||
|     void *   target = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); | ||||
|     uint8_t *source = data; | ||||
|     for (uint16_t i = 0; i < size; i++) { | ||||
|         if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) { | ||||
|             eeprom_update_byte(target, *source); | ||||
|         } | ||||
|         source++; | ||||
|         target++; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ) | ||||
| { | ||||
| 	void *source = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset); | ||||
| 	uint8_t *target = data; | ||||
| 	for ( uint16_t i = 0; i < size; i++ ) { | ||||
| 		if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) { | ||||
| 			*target = eeprom_read_byte(source); | ||||
| 		} else { | ||||
| 			*target = 0x00; | ||||
| 		} | ||||
| 		source++; | ||||
| 		target++; | ||||
| 	} | ||||
| void dynamic_keymap_macro_reset(void) { | ||||
|     void *p   = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); | ||||
|     void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); | ||||
|     while (p != end) { | ||||
|         eeprom_update_byte(p, 0); | ||||
|         ++p; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ) | ||||
| { | ||||
| 	void *target = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset); | ||||
| 	uint8_t *source = data; | ||||
| 	for ( uint16_t i = 0; i < size; i++ ) { | ||||
| 		if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) { | ||||
| 			eeprom_update_byte(target, *source); | ||||
| 		} | ||||
| 		source++; | ||||
| 		target++; | ||||
| 	} | ||||
| void dynamic_keymap_macro_send(uint8_t id) { | ||||
|     if (id >= DYNAMIC_KEYMAP_MACRO_COUNT) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Check the last byte of the buffer.
 | ||||
|     // If it's not zero, then we are in the middle
 | ||||
|     // of buffer writing, possibly an aborted buffer
 | ||||
|     // write. So do nothing.
 | ||||
|     void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE - 1); | ||||
|     if (eeprom_read_byte(p) != 0) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Skip N null characters
 | ||||
|     // p will then point to the Nth macro
 | ||||
|     p         = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); | ||||
|     void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); | ||||
|     while (id > 0) { | ||||
|         // If we are past the end of the buffer, then the buffer
 | ||||
|         // contents are garbage, i.e. there were not DYNAMIC_KEYMAP_MACRO_COUNT
 | ||||
|         // nulls in the buffer.
 | ||||
|         if (p == end) { | ||||
|             return; | ||||
|         } | ||||
|         if (eeprom_read_byte(p) == 0) { | ||||
|             --id; | ||||
|         } | ||||
|         ++p; | ||||
|     } | ||||
| 
 | ||||
|     // Send the macro string one or two chars at a time
 | ||||
|     // by making temporary 1 or 2 char strings
 | ||||
|     char data[3] = {0, 0, 0}; | ||||
|     // We already checked there was a null at the end of
 | ||||
|     // the buffer, so this cannot go past the end
 | ||||
|     while (1) { | ||||
|         data[0] = eeprom_read_byte(p++); | ||||
|         data[1] = 0; | ||||
|         // Stop at the null terminator of this macro string
 | ||||
|         if (data[0] == 0) { | ||||
|             break; | ||||
|         } | ||||
|         // If the char is magic (tap, down, up),
 | ||||
|         // add the next char (key to use) and send a 2 char string.
 | ||||
|         if (data[0] == SS_TAP_CODE || data[0] == SS_DOWN_CODE || data[0] == SS_UP_CODE) { | ||||
|             data[1] = eeprom_read_byte(p++); | ||||
|             if (data[1] == 0) { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         send_string(data); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_macro_reset(void) | ||||
| { | ||||
| 	void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); | ||||
| 	void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); | ||||
| 	while ( p != end ) { | ||||
| 		eeprom_update_byte(p, 0); | ||||
| 		++p; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void dynamic_keymap_macro_send( uint8_t id ) | ||||
| { | ||||
| 	if ( id >= DYNAMIC_KEYMAP_MACRO_COUNT )	{ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Check the last byte of the buffer.
 | ||||
| 	// If it's not zero, then we are in the middle
 | ||||
| 	// of buffer writing, possibly an aborted buffer
 | ||||
| 	// write. So do nothing.
 | ||||
| 	void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE-1); | ||||
| 	if ( eeprom_read_byte(p) != 0 )	{ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Skip N null characters
 | ||||
| 	// p will then point to the Nth macro
 | ||||
| 	p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); | ||||
| 	void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); | ||||
| 	while ( id > 0 ) { | ||||
| 		// If we are past the end of the buffer, then the buffer
 | ||||
| 		// contents are garbage, i.e. there were not DYNAMIC_KEYMAP_MACRO_COUNT
 | ||||
| 		// nulls in the buffer.
 | ||||
| 		if ( p == end ) { | ||||
| 			return; | ||||
| 		} | ||||
| 		if ( eeprom_read_byte(p) == 0 ) { | ||||
| 			--id; | ||||
| 		} | ||||
| 		++p; | ||||
| 	} | ||||
| 
 | ||||
| 	// Send the macro string one or two chars at a time
 | ||||
| 	// by making temporary 1 or 2 char strings
 | ||||
| 	char data[3] = { 0, 0, 0 }; | ||||
| 	// We already checked there was a null at the end of
 | ||||
| 	// the buffer, so this cannot go past the end
 | ||||
| 	while ( 1 ) { | ||||
| 		data[0] = eeprom_read_byte(p++); | ||||
| 		data[1] = 0; | ||||
| 		// Stop at the null terminator of this macro string
 | ||||
| 		if ( data[0] == 0 ) { | ||||
| 			break; | ||||
| 		} | ||||
| 		// If the char is magic (tap, down, up),
 | ||||
| 		// add the next char (key to use) and send a 2 char string.
 | ||||
| 		if ( data[0] == SS_TAP_CODE || data[0] == SS_DOWN_CODE || data[0] == SS_UP_CODE ) { | ||||
| 			data[1] = eeprom_read_byte(p++); | ||||
| 			if ( data[1] == 0 ) { | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		send_string(data); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif // DYNAMIC_KEYMAP_ENABLE
 | ||||
| 
 | ||||
| #endif  // DYNAMIC_KEYMAP_ENABLE
 | ||||
|  |  | |||
|  | @ -18,11 +18,11 @@ | |||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| uint8_t dynamic_keymap_get_layer_count(void); | ||||
| void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column); | ||||
| uint8_t  dynamic_keymap_get_layer_count(void); | ||||
| void *   dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column); | ||||
| uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column); | ||||
| void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); | ||||
| void dynamic_keymap_reset(void); | ||||
| void     dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); | ||||
| void     dynamic_keymap_reset(void); | ||||
| // These get/set the keycodes as stored in the EEPROM buffer
 | ||||
| // Data is big-endian 16-bit values (the keycodes)
 | ||||
| // Order is by layer/row/column
 | ||||
|  | @ -31,14 +31,12 @@ void dynamic_keymap_reset(void); | |||
| // This is only really useful for host applications that want to get a whole keymap fast,
 | ||||
| // by reading 14 keycodes (28 bytes) at a time, reducing the number of raw HID transfers by
 | ||||
| // a factor of 14.
 | ||||
| void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ); | ||||
| void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ); | ||||
| void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data); | ||||
| void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data); | ||||
| 
 | ||||
| // This overrides the one in quantum/keymap_common.c
 | ||||
| // uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Note regarding dynamic_keymap_macro_set_buffer():
 | ||||
| // The last byte of the buffer is used as a valid flag,
 | ||||
| // so macro sending is disabled during writing a new buffer,
 | ||||
|  | @ -53,11 +51,10 @@ void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ); | |||
| // and it not being null means the buffer can be considered in an
 | ||||
| // invalid state.
 | ||||
| 
 | ||||
| uint8_t dynamic_keymap_macro_get_count(void); | ||||
| uint8_t  dynamic_keymap_macro_get_count(void); | ||||
| uint16_t dynamic_keymap_macro_get_buffer_size(void); | ||||
| void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ); | ||||
| void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ); | ||||
| void dynamic_keymap_macro_reset(void); | ||||
| 
 | ||||
| void dynamic_keymap_macro_send( uint8_t id ); | ||||
| void     dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data); | ||||
| void     dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data); | ||||
| void     dynamic_keymap_macro_reset(void); | ||||
| 
 | ||||
| void dynamic_keymap_macro_send(uint8_t id); | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ | |||
|  * there have been reports of it being too much in some users' cases, | ||||
|  * so 128 is considered a safe default. | ||||
|  */ | ||||
| #define DYNAMIC_MACRO_SIZE 128 | ||||
| #    define DYNAMIC_MACRO_SIZE 128 | ||||
| #endif | ||||
| 
 | ||||
| /* DYNAMIC_MACRO_RANGE must be set as the last element of user's
 | ||||
|  | @ -46,8 +46,7 @@ enum dynamic_macro_keycodes { | |||
| }; | ||||
| 
 | ||||
| /* Blink the LEDs to notify the user about some event. */ | ||||
| void dynamic_macro_led_blink(void) | ||||
| { | ||||
| void dynamic_macro_led_blink(void) { | ||||
| #ifdef BACKLIGHT_ENABLE | ||||
|     backlight_toggle(); | ||||
|     wait_ms(100); | ||||
|  | @ -59,10 +58,8 @@ void dynamic_macro_led_blink(void) | |||
|  * need a `direction` variable accessible at the call site. | ||||
|  */ | ||||
| #define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2) | ||||
| #define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) \ | ||||
|     ((int)(direction * ((POINTER) - (BEGIN)))) | ||||
| #define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) \ | ||||
|     ((int)(direction * ((END2) - (BEGIN)) + 1)) | ||||
| #define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) ((int)(direction * ((POINTER) - (BEGIN)))) | ||||
| #define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) ((int)(direction * ((END2) - (BEGIN)) + 1)) | ||||
| 
 | ||||
| /**
 | ||||
|  * Start recording of the dynamic macro. | ||||
|  | @ -70,9 +67,7 @@ void dynamic_macro_led_blink(void) | |||
|  * @param[out] macro_pointer The new macro buffer iterator. | ||||
|  * @param[in]  macro_buffer  The macro buffer used to initialize macro_pointer. | ||||
|  */ | ||||
| void dynamic_macro_record_start( | ||||
|     keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) | ||||
| { | ||||
| void dynamic_macro_record_start(keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) { | ||||
|     dprintln("dynamic macro recording: started"); | ||||
| 
 | ||||
|     dynamic_macro_led_blink(); | ||||
|  | @ -89,9 +84,7 @@ void dynamic_macro_record_start( | |||
|  * @param macro_end[in]    The element after the last macro buffer element. | ||||
|  * @param direction[in]    Either +1 or -1, which way to iterate the buffer. | ||||
|  */ | ||||
| void dynamic_macro_play( | ||||
|     keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) | ||||
| { | ||||
| void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) { | ||||
|     dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT()); | ||||
| 
 | ||||
|     uint32_t saved_layer_state = layer_state; | ||||
|  | @ -118,13 +111,7 @@ void dynamic_macro_play( | |||
|  * @param direction[in]  Either +1 or -1, which way to iterate the buffer. | ||||
|  * @param record[in]     The current keypress. | ||||
|  */ | ||||
| void dynamic_macro_record_key( | ||||
|     keyrecord_t *macro_buffer, | ||||
|     keyrecord_t **macro_pointer, | ||||
|     keyrecord_t *macro2_end, | ||||
|     int8_t direction, | ||||
|     keyrecord_t *record) | ||||
| { | ||||
| void dynamic_macro_record_key(keyrecord_t *macro_buffer, keyrecord_t **macro_pointer, keyrecord_t *macro2_end, int8_t direction, keyrecord_t *record) { | ||||
|     /* If we've just started recording, ignore all the key releases. */ | ||||
|     if (!record->event.pressed && *macro_pointer == macro_buffer) { | ||||
|         dprintln("dynamic macro: ignoring a leading key-up event"); | ||||
|  | @ -141,38 +128,25 @@ void dynamic_macro_record_key( | |||
|         dynamic_macro_led_blink(); | ||||
|     } | ||||
| 
 | ||||
|     dprintf( | ||||
|         "dynamic macro: slot %d length: %d/%d\n", | ||||
|         DYNAMIC_MACRO_CURRENT_SLOT(), | ||||
|         DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer), | ||||
|         DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end)); | ||||
|     dprintf("dynamic macro: slot %d length: %d/%d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer), DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end)); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * End recording of the dynamic macro. Essentially just update the | ||||
|  * pointer to the end of the macro. | ||||
|  */ | ||||
| void dynamic_macro_record_end( | ||||
|     keyrecord_t *macro_buffer, | ||||
|     keyrecord_t *macro_pointer, | ||||
|     int8_t direction, | ||||
|     keyrecord_t **macro_end) | ||||
| { | ||||
| void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_pointer, int8_t direction, keyrecord_t **macro_end) { | ||||
|     dynamic_macro_led_blink(); | ||||
| 
 | ||||
|     /* Do not save the keys being held when stopping the recording,
 | ||||
|      * i.e. the keys used to access the layer DYN_REC_STOP is on. | ||||
|      */ | ||||
|     while (macro_pointer != macro_buffer && | ||||
|            (macro_pointer - direction)->event.pressed) { | ||||
|     while (macro_pointer != macro_buffer && (macro_pointer - direction)->event.pressed) { | ||||
|         dprintln("dynamic macro: trimming a trailing key-down event"); | ||||
|         macro_pointer -= direction; | ||||
|     } | ||||
| 
 | ||||
|     dprintf( | ||||
|         "dynamic macro: slot %d saved, length: %d\n", | ||||
|         DYNAMIC_MACRO_CURRENT_SLOT(), | ||||
|         DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer)); | ||||
|     dprintf("dynamic macro: slot %d saved, length: %d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer)); | ||||
| 
 | ||||
|     *macro_end = macro_pointer; | ||||
| } | ||||
|  | @ -187,8 +161,7 @@ void dynamic_macro_record_end( | |||
|  *       <...THE REST OF THE FUNCTION...> | ||||
|  *   } | ||||
|  */ | ||||
| bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) | ||||
| { | ||||
| bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) { | ||||
|     /* Both macros use the same buffer but read/write on different
 | ||||
|      * ends of it. | ||||
|      * | ||||
|  | @ -239,57 +212,57 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) | |||
|         /* No macro recording in progress. */ | ||||
|         if (!record->event.pressed) { | ||||
|             switch (keycode) { | ||||
|             case DYN_REC_START1: | ||||
|                 dynamic_macro_record_start(¯o_pointer, macro_buffer); | ||||
|                 macro_id = 1; | ||||
|                 return false; | ||||
|             case DYN_REC_START2: | ||||
|                 dynamic_macro_record_start(¯o_pointer, r_macro_buffer); | ||||
|                 macro_id = 2; | ||||
|                 return false; | ||||
|             case DYN_MACRO_PLAY1: | ||||
|                 dynamic_macro_play(macro_buffer, macro_end, +1); | ||||
|                 return false; | ||||
|             case DYN_MACRO_PLAY2: | ||||
|                 dynamic_macro_play(r_macro_buffer, r_macro_end, -1); | ||||
|                 return false; | ||||
|                 case DYN_REC_START1: | ||||
|                     dynamic_macro_record_start(¯o_pointer, macro_buffer); | ||||
|                     macro_id = 1; | ||||
|                     return false; | ||||
|                 case DYN_REC_START2: | ||||
|                     dynamic_macro_record_start(¯o_pointer, r_macro_buffer); | ||||
|                     macro_id = 2; | ||||
|                     return false; | ||||
|                 case DYN_MACRO_PLAY1: | ||||
|                     dynamic_macro_play(macro_buffer, macro_end, +1); | ||||
|                     return false; | ||||
|                 case DYN_MACRO_PLAY2: | ||||
|                     dynamic_macro_play(r_macro_buffer, r_macro_end, -1); | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         /* A macro is being recorded right now. */ | ||||
|         switch (keycode) { | ||||
|         case DYN_REC_STOP: | ||||
|             /* Stop the macro recording. */ | ||||
|             if (record->event.pressed) { /* Ignore the initial release
 | ||||
|                                           * just after the recoding | ||||
|                                           * starts. */ | ||||
|                 switch (macro_id) { | ||||
|                 case 1: | ||||
|                     dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); | ||||
|                     break; | ||||
|                 case 2: | ||||
|                     dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); | ||||
|                     break; | ||||
|             case DYN_REC_STOP: | ||||
|                 /* Stop the macro recording. */ | ||||
|                 if (record->event.pressed) { /* Ignore the initial release
 | ||||
|                                               * just after the recoding | ||||
|                                               * starts. */ | ||||
|                     switch (macro_id) { | ||||
|                         case 1: | ||||
|                             dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); | ||||
|                             break; | ||||
|                         case 2: | ||||
|                             dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); | ||||
|                             break; | ||||
|                     } | ||||
|                     macro_id = 0; | ||||
|                 } | ||||
|                 macro_id = 0; | ||||
|             } | ||||
|             return false; | ||||
|         case DYN_MACRO_PLAY1: | ||||
|         case DYN_MACRO_PLAY2: | ||||
|             dprintln("dynamic macro: ignoring macro play key while recording"); | ||||
|             return false; | ||||
|         default: | ||||
|             /* Store the key in the macro buffer and process it normally. */ | ||||
|             switch (macro_id) { | ||||
|             case 1: | ||||
|                 dynamic_macro_record_key(macro_buffer, ¯o_pointer, r_macro_end, +1, record); | ||||
|                 return false; | ||||
|             case DYN_MACRO_PLAY1: | ||||
|             case DYN_MACRO_PLAY2: | ||||
|                 dprintln("dynamic macro: ignoring macro play key while recording"); | ||||
|                 return false; | ||||
|             default: | ||||
|                 /* Store the key in the macro buffer and process it normally. */ | ||||
|                 switch (macro_id) { | ||||
|                     case 1: | ||||
|                         dynamic_macro_record_key(macro_buffer, ¯o_pointer, r_macro_end, +1, record); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         dynamic_macro_record_key(r_macro_buffer, ¯o_pointer, macro_end, -1, record); | ||||
|                         break; | ||||
|                 } | ||||
|                 return true; | ||||
|                 break; | ||||
|             case 2: | ||||
|                 dynamic_macro_record_key(r_macro_buffer, ¯o_pointer, macro_end, -1, record); | ||||
|                 break; | ||||
|             } | ||||
|             return true; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,27 +17,25 @@ | |||
| 
 | ||||
| #include "encoder.h" | ||||
| #ifdef SPLIT_KEYBOARD | ||||
|   #include "split_util.h" | ||||
| #    include "split_util.h" | ||||
| #endif | ||||
| 
 | ||||
| // for memcpy
 | ||||
| #include <string.h> | ||||
| 
 | ||||
| 
 | ||||
| #ifndef ENCODER_RESOLUTION | ||||
|   #define ENCODER_RESOLUTION 4 | ||||
| #    define ENCODER_RESOLUTION 4 | ||||
| #endif | ||||
| 
 | ||||
| #if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) | ||||
|   #error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" | ||||
| #    error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a)/sizeof(pin_t)) | ||||
| #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) | ||||
| static pin_t encoders_pad_a[] = ENCODERS_PAD_A; | ||||
| static pin_t encoders_pad_b[] = ENCODERS_PAD_B; | ||||
| 
 | ||||
| static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; | ||||
| static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; | ||||
| 
 | ||||
| static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; | ||||
| 
 | ||||
|  | @ -48,64 +46,58 @@ static int8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; | |||
| static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; | ||||
| #endif | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| void encoder_update_user(int8_t index, bool clockwise) { } | ||||
| __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| void encoder_update_kb(int8_t index, bool clockwise) { | ||||
|   encoder_update_user(index, clockwise); | ||||
| } | ||||
| __attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } | ||||
| 
 | ||||
| void encoder_init(void) { | ||||
| #if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) | ||||
|   if (!isLeftHand) { | ||||
|     const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; | ||||
|     const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; | ||||
|     for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|       encoders_pad_a[i] = encoders_pad_a_right[i]; | ||||
|       encoders_pad_b[i] = encoders_pad_b_right[i]; | ||||
|     if (!isLeftHand) { | ||||
|         const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; | ||||
|         const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; | ||||
|         for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|             encoders_pad_a[i] = encoders_pad_a_right[i]; | ||||
|             encoders_pad_b[i] = encoders_pad_b_right[i]; | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
| 
 | ||||
|   for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|     setPinInputHigh(encoders_pad_a[i]); | ||||
|     setPinInputHigh(encoders_pad_b[i]); | ||||
|     for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|         setPinInputHigh(encoders_pad_a[i]); | ||||
|         setPinInputHigh(encoders_pad_b[i]); | ||||
| 
 | ||||
|     encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | ||||
|   } | ||||
|         encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void encoder_read(void) { | ||||
|   for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|     encoder_state[i] <<= 2; | ||||
|     encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | ||||
|     encoder_value[i] += encoder_LUT[encoder_state[i] & 0xF]; | ||||
|     if (encoder_value[i] >= ENCODER_RESOLUTION) { | ||||
|         encoder_update_kb(i, false); | ||||
|     for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|         encoder_state[i] <<= 2; | ||||
|         encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | ||||
|         encoder_value[i] += encoder_LUT[encoder_state[i] & 0xF]; | ||||
|         if (encoder_value[i] >= ENCODER_RESOLUTION) { | ||||
|             encoder_update_kb(i, false); | ||||
|         } | ||||
|         if (encoder_value[i] <= -ENCODER_RESOLUTION) {  // direction is arbitrary here, but this clockwise
 | ||||
|             encoder_update_kb(i, true); | ||||
|         } | ||||
|         encoder_value[i] %= ENCODER_RESOLUTION; | ||||
|     } | ||||
|     if (encoder_value[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
 | ||||
|         encoder_update_kb(i, true); | ||||
|     } | ||||
|     encoder_value[i] %= ENCODER_RESOLUTION; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #ifdef SPLIT_KEYBOARD | ||||
| void encoder_state_raw(uint8_t* slave_state) { | ||||
|   memcpy(slave_state, encoder_state, sizeof(encoder_state)); | ||||
| } | ||||
| void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, encoder_state, sizeof(encoder_state)); } | ||||
| 
 | ||||
| void encoder_update_raw(uint8_t* slave_state) { | ||||
|   for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|     encoder_value[NUMBER_OF_ENCODERS + i] += encoder_LUT[slave_state[i] & 0xF]; | ||||
|     if (encoder_value[NUMBER_OF_ENCODERS + i] >= ENCODER_RESOLUTION) { | ||||
|         encoder_update_kb(NUMBER_OF_ENCODERS + i, false); | ||||
|     for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | ||||
|         encoder_value[NUMBER_OF_ENCODERS + i] += encoder_LUT[slave_state[i] & 0xF]; | ||||
|         if (encoder_value[NUMBER_OF_ENCODERS + i] >= ENCODER_RESOLUTION) { | ||||
|             encoder_update_kb(NUMBER_OF_ENCODERS + i, false); | ||||
|         } | ||||
|         if (encoder_value[NUMBER_OF_ENCODERS + i] <= -ENCODER_RESOLUTION) {  // direction is arbitrary here, but this clockwise
 | ||||
|             encoder_update_kb(NUMBER_OF_ENCODERS + i, true); | ||||
|         } | ||||
|         encoder_value[NUMBER_OF_ENCODERS + i] %= ENCODER_RESOLUTION; | ||||
|     } | ||||
|     if (encoder_value[NUMBER_OF_ENCODERS + i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
 | ||||
|         encoder_update_kb(NUMBER_OF_ENCODERS + i, true); | ||||
|     } | ||||
|     encoder_value[NUMBER_OF_ENCODERS + i] %= ENCODER_RESOLUTION; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -20,23 +20,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include <stdbool.h> | ||||
| #include <musical_notes.h> | ||||
| 
 | ||||
| bool fauxclicky_enabled = true; | ||||
| uint16_t note_start = 0; | ||||
| bool note_playing = false; | ||||
| uint16_t note_period = 0; | ||||
| bool     fauxclicky_enabled = true; | ||||
| uint16_t note_start         = 0; | ||||
| bool     note_playing       = false; | ||||
| uint16_t note_period        = 0; | ||||
| 
 | ||||
| void fauxclicky_init() | ||||
| { | ||||
| void fauxclicky_init() { | ||||
|     // Set port PC6 (OC3A and /OC4A) as output
 | ||||
|     DDRC |= _BV(PORTC6); | ||||
| 
 | ||||
|     // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
 | ||||
|     TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | ||||
|     TCCR3B = (1 << WGM33)  | (1 << WGM32)  | (0 << CS32)  | (1 << CS31) | (0 << CS30); | ||||
|     TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); | ||||
| } | ||||
| 
 | ||||
| void fauxclicky_stop() | ||||
| { | ||||
| void fauxclicky_stop() { | ||||
|     FAUXCLICKY_DISABLE_OUTPUT; | ||||
|     note_playing = false; | ||||
| } | ||||
|  | @ -45,10 +43,10 @@ void fauxclicky_play(float note[]) { | |||
|     if (!fauxclicky_enabled) return; | ||||
|     if (note_playing) fauxclicky_stop(); | ||||
|     FAUXCLICKY_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (note[0] * (float)FAUXCLICKY_CPU_PRESCALER)); | ||||
|     FAUXCLICKY_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (note[0] * (float)FAUXCLICKY_CPU_PRESCALER)) / (float)2); | ||||
|     note_playing = true; | ||||
|     note_period = (note[1] / (float)16) * ((float)60 / (float)FAUXCLICKY_TEMPO) * 1000; | ||||
|     note_start = timer_read(); | ||||
|     FAUXCLICKY_DUTY_CYCLE   = (uint16_t)((((float)F_CPU) / (note[0] * (float)FAUXCLICKY_CPU_PRESCALER)) / (float)2); | ||||
|     note_playing            = true; | ||||
|     note_period             = (note[1] / (float)16) * ((float)60 / (float)FAUXCLICKY_TEMPO) * 1000; | ||||
|     note_start              = timer_read(); | ||||
|     FAUXCLICKY_ENABLE_OUTPUT; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,18 +14,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| */ | ||||
| 
 | ||||
| #ifdef AUDIO_ENABLE | ||||
| #error "AUDIO_ENABLE and FAUXCLICKY_ENABLE cannot be both enabled" | ||||
| #    error "AUDIO_ENABLE and FAUXCLICKY_ENABLE cannot be both enabled" | ||||
| #endif | ||||
| 
 | ||||
| #include "musical_notes.h" | ||||
| #include "stdbool.h" | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_D4, 0.25); | ||||
| __attribute__ ((weak)) | ||||
| float fauxclicky_released_note[2] = MUSICAL_NOTE(_C4, 0.125); | ||||
| __attribute__ ((weak)) | ||||
| float fauxclicky_beep_note[2] = MUSICAL_NOTE(_C4, 0.25); | ||||
| __attribute__((weak)) float fauxclicky_pressed_note[2]  = MUSICAL_NOTE(_D4, 0.25); | ||||
| __attribute__((weak)) float fauxclicky_released_note[2] = MUSICAL_NOTE(_C4, 0.125); | ||||
| __attribute__((weak)) float fauxclicky_beep_note[2]     = MUSICAL_NOTE(_C4, 0.25); | ||||
| 
 | ||||
| bool fauxclicky_enabled; | ||||
| 
 | ||||
|  | @ -34,7 +31,7 @@ bool fauxclicky_enabled; | |||
| //
 | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_TEMPO | ||||
| #define FAUXCLICKY_TEMPO TEMPO_DEFAULT | ||||
| #    define FAUXCLICKY_TEMPO TEMPO_DEFAULT | ||||
| #endif | ||||
| 
 | ||||
| // beep on press
 | ||||
|  | @ -50,42 +47,44 @@ bool fauxclicky_enabled; | |||
| #define FAUXCLICKY_ON fauxclicky_enabled = true | ||||
| 
 | ||||
| // disable
 | ||||
| #define FAUXCLICKY_OFF do { \ | ||||
|     fauxclicky_enabled = false; \ | ||||
|     fauxclicky_stop(); \ | ||||
| } while (0) | ||||
| #define FAUXCLICKY_OFF              \ | ||||
|     do {                            \ | ||||
|         fauxclicky_enabled = false; \ | ||||
|         fauxclicky_stop();          \ | ||||
|     } while (0) | ||||
| 
 | ||||
| // toggle
 | ||||
| #define FAUXCLICKY_TOGGLE do { \ | ||||
|     if (fauxclicky_enabled) { \ | ||||
|         FAUXCLICKY_OFF; \ | ||||
|     } else { \ | ||||
|         FAUXCLICKY_ON; \ | ||||
|     } \ | ||||
| } while (0) | ||||
| #define FAUXCLICKY_TOGGLE         \ | ||||
|     do {                          \ | ||||
|         if (fauxclicky_enabled) { \ | ||||
|             FAUXCLICKY_OFF;       \ | ||||
|         } else {                  \ | ||||
|             FAUXCLICKY_ON;        \ | ||||
|         }                         \ | ||||
|     } while (0) | ||||
| 
 | ||||
| //
 | ||||
| // pin configuration
 | ||||
| //
 | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_CPU_PRESCALER | ||||
| #define FAUXCLICKY_CPU_PRESCALER 8 | ||||
| #    define FAUXCLICKY_CPU_PRESCALER 8 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_ENABLE_OUTPUT | ||||
| #define FAUXCLICKY_ENABLE_OUTPUT TCCR3A |= _BV(COM3A1) | ||||
| #    define FAUXCLICKY_ENABLE_OUTPUT TCCR3A |= _BV(COM3A1) | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_DISABLE_OUTPUT | ||||
| #define FAUXCLICKY_DISABLE_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)) | ||||
| #    define FAUXCLICKY_DISABLE_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)) | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_TIMER_PERIOD | ||||
| #define FAUXCLICKY_TIMER_PERIOD ICR3 | ||||
| #    define FAUXCLICKY_TIMER_PERIOD ICR3 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FAUXCLICKY_DUTY_CYCLE | ||||
| #define FAUXCLICKY_DUTY_CYCLE OCR3A | ||||
| #    define FAUXCLICKY_DUTY_CYCLE OCR3A | ||||
| #endif | ||||
| 
 | ||||
| //
 | ||||
|  | @ -96,4 +95,3 @@ void fauxclicky_init(void); | |||
| void fauxclicky_stop(void); | ||||
| void fauxclicky_play(float note[2]); | ||||
| void fauxclicky_check(void); | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ extern keymap_config_t keymap_config; | |||
|  * and will return the corrected keycode, when appropriate. | ||||
|  */ | ||||
| uint16_t keycode_config(uint16_t keycode) { | ||||
| 
 | ||||
|     switch (keycode) { | ||||
|         case KC_CAPSLOCK: | ||||
|         case KC_LOCKING_CAPS: | ||||
|  | @ -56,7 +55,7 @@ uint16_t keycode_config(uint16_t keycode) { | |||
|                 return KC_LALT; | ||||
|             } | ||||
|             if (keymap_config.swap_lctl_lgui) { | ||||
|               return KC_LCTRL; | ||||
|                 return KC_LCTRL; | ||||
|             } | ||||
|             if (keymap_config.no_gui) { | ||||
|                 return KC_NO; | ||||
|  | @ -83,7 +82,7 @@ uint16_t keycode_config(uint16_t keycode) { | |||
|                 return KC_RALT; | ||||
|             } | ||||
|             if (keymap_config.swap_rctl_rgui) { | ||||
|               return KC_RCTL; | ||||
|                 return KC_RCTL; | ||||
|             } | ||||
|             if (keymap_config.no_gui) { | ||||
|                 return KC_NO; | ||||
|  | @ -140,22 +139,22 @@ uint8_t mod_config(uint8_t mod) { | |||
|         } | ||||
|     } | ||||
|     if (keymap_config.swap_lctl_lgui) { | ||||
|       if ((mod & MOD_RGUI) == MOD_LGUI) { | ||||
|         mod &= ~MOD_LGUI; | ||||
|         mod |= MOD_LCTL; | ||||
|       } else if ((mod & MOD_RCTL) == MOD_LCTL) { | ||||
|         mod &= ~MOD_LCTL; | ||||
|         mod |= MOD_LGUI; | ||||
|       } | ||||
|         if ((mod & MOD_RGUI) == MOD_LGUI) { | ||||
|             mod &= ~MOD_LGUI; | ||||
|             mod |= MOD_LCTL; | ||||
|         } else if ((mod & MOD_RCTL) == MOD_LCTL) { | ||||
|             mod &= ~MOD_LCTL; | ||||
|             mod |= MOD_LGUI; | ||||
|         } | ||||
|     } | ||||
|     if (keymap_config.swap_rctl_rgui) { | ||||
|       if ((mod & MOD_RGUI) == MOD_RGUI) { | ||||
|         mod &= ~MOD_RGUI; | ||||
|         mod |= MOD_RCTL; | ||||
|       } else if ((mod & MOD_RCTL) == MOD_RCTL) { | ||||
|         mod &= ~MOD_RCTL; | ||||
|         mod |= MOD_RGUI; | ||||
|       } | ||||
|         if ((mod & MOD_RGUI) == MOD_RGUI) { | ||||
|             mod &= ~MOD_RGUI; | ||||
|             mod |= MOD_RCTL; | ||||
|         } else if ((mod & MOD_RCTL) == MOD_RCTL) { | ||||
|             mod &= ~MOD_RCTL; | ||||
|             mod |= MOD_RGUI; | ||||
|         } | ||||
|     } | ||||
|     if (keymap_config.no_gui) { | ||||
|         mod &= ~MOD_LGUI; | ||||
|  |  | |||
|  | @ -19,25 +19,25 @@ | |||
| #include "action_code.h" | ||||
| 
 | ||||
| #ifndef KEYCODE_CONFIG_H | ||||
| #define KEYCODE_CONFIG_H | ||||
| #    define KEYCODE_CONFIG_H | ||||
| 
 | ||||
| uint16_t keycode_config(uint16_t keycode); | ||||
| uint8_t mod_config(uint8_t mod); | ||||
| uint8_t  mod_config(uint8_t mod); | ||||
| 
 | ||||
| /* NOTE: Not portable. Bit field order depends on implementation */ | ||||
| typedef union { | ||||
|     uint16_t raw; | ||||
|     struct { | ||||
|         bool swap_control_capslock:1; | ||||
|         bool capslock_to_control:1; | ||||
|         bool swap_lalt_lgui:1; | ||||
|         bool swap_ralt_rgui:1; | ||||
|         bool no_gui:1; | ||||
|         bool swap_grave_esc:1; | ||||
|         bool swap_backslash_backspace:1; | ||||
|         bool nkro:1; | ||||
|         bool swap_lctl_lgui:1; | ||||
|         bool swap_rctl_rgui:1; | ||||
|         bool swap_control_capslock : 1; | ||||
|         bool capslock_to_control : 1; | ||||
|         bool swap_lalt_lgui : 1; | ||||
|         bool swap_ralt_rgui : 1; | ||||
|         bool no_gui : 1; | ||||
|         bool swap_grave_esc : 1; | ||||
|         bool swap_backslash_backspace : 1; | ||||
|         bool nkro : 1; | ||||
|         bool swap_lctl_lgui : 1; | ||||
|         bool swap_rctl_rgui : 1; | ||||
|     }; | ||||
| } keymap_config_t; | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,10 +22,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include <stdbool.h> | ||||
| #include "action.h" | ||||
| #if defined(__AVR__) | ||||
| #include <avr/pgmspace.h> | ||||
| #    include <avr/pgmspace.h> | ||||
| #elif defined PROTOCOL_CHIBIOS | ||||
| //We need to ensure that chibios is include before redefining reset
 | ||||
| #include "ch.h" | ||||
| // We need to ensure that chibios is include before redefining reset
 | ||||
| #    include "ch.h" | ||||
| #endif | ||||
| #include "keycode.h" | ||||
| #include "action_macro.h" | ||||
|  | @ -38,7 +38,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| // ChibiOS uses RESET in its FlagStatus enumeration
 | ||||
| // Therefore define it as QK_RESET here, to avoid name collision
 | ||||
| #if defined(PROTOCOL_CHIBIOS) | ||||
| #define RESET QK_RESET | ||||
| #    define RESET QK_RESET | ||||
| #endif | ||||
| 
 | ||||
| #include "quantum_keycodes.h" | ||||
|  | @ -47,10 +47,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); | ||||
| 
 | ||||
| // translates function id to action
 | ||||
| uint16_t keymap_function_id_to_action( uint16_t function_id ); | ||||
| uint16_t keymap_function_id_to_action(uint16_t function_id); | ||||
| 
 | ||||
| extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | ||||
| extern const uint16_t fn_actions[]; | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -20,8 +20,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "keycode.h" | ||||
| #include "action_layer.h" | ||||
| #if defined(__AVR__) | ||||
| #include <util/delay.h> | ||||
| #include <stdio.h> | ||||
| #    include <util/delay.h> | ||||
| #    include <stdio.h> | ||||
| #endif | ||||
| #include "action.h" | ||||
| #include "action_macro.h" | ||||
|  | @ -30,7 +30,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "quantum.h" | ||||
| 
 | ||||
| #ifdef MIDI_ENABLE | ||||
| 	#include "process_midi.h" | ||||
| #    include "process_midi.h" | ||||
| #endif | ||||
| 
 | ||||
| extern keymap_config_t keymap_config; | ||||
|  | @ -38,8 +38,7 @@ extern keymap_config_t keymap_config; | |||
| #include <inttypes.h> | ||||
| 
 | ||||
| /* converts key to action */ | ||||
| action_t action_for_key(uint8_t layer, keypos_t key) | ||||
| { | ||||
| action_t action_for_key(uint8_t layer, keypos_t key) { | ||||
|     // 16bit keycodes - important
 | ||||
|     uint16_t keycode = keymap_key_to_keycode(layer, key); | ||||
| 
 | ||||
|  | @ -47,7 +46,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
|     keycode = keycode_config(keycode); | ||||
| 
 | ||||
|     action_t action; | ||||
|     uint8_t action_layer, when, mod; | ||||
|     uint8_t  action_layer, when, mod; | ||||
| 
 | ||||
|     switch (keycode) { | ||||
|         case KC_FN0 ... KC_FN31: | ||||
|  | @ -69,18 +68,18 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
|         case KC_TRNS: | ||||
|             action.code = ACTION_TRANSPARENT; | ||||
|             break; | ||||
|         case QK_MODS ... QK_MODS_MAX: ; | ||||
|         case QK_MODS ... QK_MODS_MAX:; | ||||
|             // Has a modifier
 | ||||
|             // Split it up
 | ||||
|             action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key
 | ||||
|             action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF);  // adds modifier to key
 | ||||
|             break; | ||||
|         case QK_FUNCTION ... QK_FUNCTION_MAX: ; | ||||
|         case QK_FUNCTION ... QK_FUNCTION_MAX:; | ||||
|             // Is a shortcut for function action_layer, pull last 12bits
 | ||||
|             // This means we have 4,096 FN macros at our disposal
 | ||||
|             action.code = keymap_function_id_to_action( (int)keycode & 0xFFF ); | ||||
|             action.code = keymap_function_id_to_action((int)keycode & 0xFFF); | ||||
|             break; | ||||
|         case QK_MACRO ... QK_MACRO_MAX: | ||||
|             if (keycode & 0x800) // tap macros have upper bit set
 | ||||
|             if (keycode & 0x800)  // tap macros have upper bit set
 | ||||
|                 action.code = ACTION_MACRO_TAP(keycode & 0xFF); | ||||
|             else | ||||
|                 action.code = ACTION_MACRO(keycode & 0xFF); | ||||
|  | @ -88,50 +87,50 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
|         case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: | ||||
|             action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); | ||||
|             break; | ||||
|         case QK_TO ... QK_TO_MAX: ; | ||||
|         case QK_TO ... QK_TO_MAX:; | ||||
|             // Layer set "GOTO"
 | ||||
|             when = (keycode >> 0x4) & 0x3; | ||||
|             when         = (keycode >> 0x4) & 0x3; | ||||
|             action_layer = keycode & 0xF; | ||||
|             action.code = ACTION_LAYER_SET(action_layer, when); | ||||
|             action.code  = ACTION_LAYER_SET(action_layer, when); | ||||
|             break; | ||||
|         case QK_MOMENTARY ... QK_MOMENTARY_MAX: ; | ||||
|         case QK_MOMENTARY ... QK_MOMENTARY_MAX:; | ||||
|             // Momentary action_layer
 | ||||
|             action_layer = keycode & 0xFF; | ||||
|             action.code = ACTION_LAYER_MOMENTARY(action_layer); | ||||
|             action.code  = ACTION_LAYER_MOMENTARY(action_layer); | ||||
|             break; | ||||
|         case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: ; | ||||
|         case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:; | ||||
|             // Set default action_layer
 | ||||
|             action_layer = keycode & 0xFF; | ||||
|             action.code = ACTION_DEFAULT_LAYER_SET(action_layer); | ||||
|             action.code  = ACTION_DEFAULT_LAYER_SET(action_layer); | ||||
|             break; | ||||
|         case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: ; | ||||
|         case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:; | ||||
|             // Set toggle
 | ||||
|             action_layer = keycode & 0xFF; | ||||
|             action.code = ACTION_LAYER_TOGGLE(action_layer); | ||||
|             action.code  = ACTION_LAYER_TOGGLE(action_layer); | ||||
|             break; | ||||
|         case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: ; | ||||
|         case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:; | ||||
|             // OSL(action_layer) - One-shot action_layer
 | ||||
|             action_layer = keycode & 0xFF; | ||||
|             action.code = ACTION_LAYER_ONESHOT(action_layer); | ||||
|             action.code  = ACTION_LAYER_ONESHOT(action_layer); | ||||
|             break; | ||||
|         case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: ; | ||||
|         case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:; | ||||
|             // OSM(mod) - One-shot mod
 | ||||
|             mod = mod_config(keycode & 0xFF); | ||||
|             mod         = mod_config(keycode & 0xFF); | ||||
|             action.code = ACTION_MODS_ONESHOT(mod); | ||||
|             break; | ||||
|         case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: | ||||
|             action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF); | ||||
|             break; | ||||
|         case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: | ||||
|             mod = mod_config(keycode & 0xF); | ||||
|             mod          = mod_config(keycode & 0xF); | ||||
|             action_layer = (keycode >> 4) & 0xF; | ||||
|             action.code = ACTION_LAYER_MODS(action_layer, mod); | ||||
|             action.code  = ACTION_LAYER_MODS(action_layer, mod); | ||||
|             break; | ||||
|         case QK_MOD_TAP ... QK_MOD_TAP_MAX: | ||||
|             mod = mod_config((keycode >> 0x8) & 0x1F); | ||||
|             mod         = mod_config((keycode >> 0x8) & 0x1F); | ||||
|             action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF); | ||||
|             break; | ||||
|     #ifdef BACKLIGHT_ENABLE | ||||
| #ifdef BACKLIGHT_ENABLE | ||||
|         case BL_ON: | ||||
|             action.code = ACTION_BACKLIGHT_ON(); | ||||
|             break; | ||||
|  | @ -150,12 +149,12 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
|         case BL_STEP: | ||||
|             action.code = ACTION_BACKLIGHT_STEP(); | ||||
|             break; | ||||
|     #endif | ||||
|     #ifdef SWAP_HANDS_ENABLE | ||||
| #endif | ||||
| #ifdef SWAP_HANDS_ENABLE | ||||
|         case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: | ||||
|             action.code = ACTION(ACT_SWAP_HANDS, keycode & 0xff); | ||||
|             break; | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
|         default: | ||||
|             action.code = ACTION_NO; | ||||
|  | @ -164,42 +163,30 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
|     return action; | ||||
| } | ||||
| 
 | ||||
| __attribute__ ((weak)) | ||||
| const uint16_t PROGMEM fn_actions[] = { | ||||
| __attribute__((weak)) const uint16_t PROGMEM fn_actions[] = { | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| /* Macro */ | ||||
| __attribute__ ((weak)) | ||||
| const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | ||||
| { | ||||
|     return MACRO_NONE; | ||||
| } | ||||
| __attribute__((weak)) const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; } | ||||
| 
 | ||||
| /* Function */ | ||||
| __attribute__ ((weak)) | ||||
| void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) | ||||
| { | ||||
| } | ||||
| __attribute__((weak)) void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {} | ||||
| 
 | ||||
| // translates key to keycode
 | ||||
| __attribute__ ((weak)) | ||||
| uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | ||||
| { | ||||
| __attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { | ||||
|     // Read entire word (16bits)
 | ||||
|     return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); | ||||
| } | ||||
| 
 | ||||
| // translates function id to action
 | ||||
| __attribute__ ((weak)) | ||||
| uint16_t keymap_function_id_to_action( uint16_t function_id ) | ||||
| { | ||||
|     // The compiler sees the empty (weak) fn_actions and generates a warning
 | ||||
|     // This function should not be called in that case, so the warning is too strict
 | ||||
|     // If this function is called however, the keymap should have overridden fn_actions, and then the compile
 | ||||
|     // is comparing against the wrong array
 | ||||
|     #pragma GCC diagnostic push | ||||
|     #pragma GCC diagnostic ignored "-Warray-bounds" | ||||
| 	return pgm_read_word(&fn_actions[function_id]); | ||||
|     #pragma GCC diagnostic pop | ||||
| __attribute__((weak)) uint16_t keymap_function_id_to_action(uint16_t function_id) { | ||||
| // The compiler sees the empty (weak) fn_actions and generates a warning
 | ||||
| // This function should not be called in that case, so the warning is too strict
 | ||||
| // If this function is called however, the keymap should have overridden fn_actions, and then the compile
 | ||||
| // is comparing against the wrong array
 | ||||
| #pragma GCC diagnostic push | ||||
| #pragma GCC diagnostic ignored "-Warray-bounds" | ||||
|     return pgm_read_word(&fn_actions[function_id]); | ||||
| #pragma GCC diagnostic pop | ||||
| } | ||||
|  |  | |||
|  | @ -20,86 +20,86 @@ | |||
| 
 | ||||
| // Normal characters
 | ||||
| // Line 1
 | ||||
| #define BE_SUP2	KC_GRV | ||||
| #define BE_AMP	KC_1 | ||||
| #define BE_EACU	KC_2 | ||||
| #define BE_QUOT	KC_3 | ||||
| #define BE_APOS	KC_4 | ||||
| #define BE_LPRN	KC_5 | ||||
| #define BE_PARA	KC_6 | ||||
| #define BE_EGRV	KC_7 | ||||
| #define BE_EXLM	KC_8 | ||||
| #define BE_CCED	KC_9 | ||||
| #define BE_AGRV	KC_0 | ||||
| #define BE_RPRN	KC_MINS | ||||
| #define BE_MINS	KC_EQL | ||||
| #define BE_SUP2 KC_GRV | ||||
| #define BE_AMP KC_1 | ||||
| #define BE_EACU KC_2 | ||||
| #define BE_QUOT KC_3 | ||||
| #define BE_APOS KC_4 | ||||
| #define BE_LPRN KC_5 | ||||
| #define BE_PARA KC_6 | ||||
| #define BE_EGRV KC_7 | ||||
| #define BE_EXLM KC_8 | ||||
| #define BE_CCED KC_9 | ||||
| #define BE_AGRV KC_0 | ||||
| #define BE_RPRN KC_MINS | ||||
| #define BE_MINS KC_EQL | ||||
| 
 | ||||
| // Line 2
 | ||||
| #define BE_A    KC_Q | ||||
| #define BE_Z	  KC_W | ||||
| #define	BE_CIRC	KC_LBRC | ||||
| #define BE_DLR	KC_RBRC | ||||
| #define BE_A KC_Q | ||||
| #define BE_Z KC_W | ||||
| #define BE_CIRC KC_LBRC | ||||
| #define BE_DLR KC_RBRC | ||||
| 
 | ||||
| // Line 3
 | ||||
| #define BE_Q 	  KC_A | ||||
| #define BE_M 	  KC_SCLN | ||||
| #define BE_UGRV	KC_QUOT | ||||
| #define BE_MU 	KC_NUHS | ||||
| #define BE_Q KC_A | ||||
| #define BE_M KC_SCLN | ||||
| #define BE_UGRV KC_QUOT | ||||
| #define BE_MU KC_NUHS | ||||
| 
 | ||||
| // Line 4
 | ||||
| #define BE_LESS	KC_NUBS | ||||
| #define BE_W	  KC_Z | ||||
| #define BE_COMM	KC_M | ||||
| #define BE_SCLN	KC_COMM | ||||
| #define BE_COLN	KC_DOT | ||||
| #define BE_EQL	KC_SLSH | ||||
| #define BE_LESS KC_NUBS | ||||
| #define BE_W KC_Z | ||||
| #define BE_COMM KC_M | ||||
| #define BE_SCLN KC_COMM | ||||
| #define BE_COLN KC_DOT | ||||
| #define BE_EQL KC_SLSH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| // Line 1
 | ||||
| #define BE_SUP3 KC_TILD | ||||
| #define BE_1  	LSFT(KC_1) | ||||
| #define BE_2 	  LSFT(KC_2) | ||||
| #define BE_3 	  LSFT(KC_3) | ||||
| #define BE_4 	  LSFT(KC_4) | ||||
| #define BE_5 	  LSFT(KC_5) | ||||
| #define BE_6 	  LSFT(KC_6) | ||||
| #define BE_7 	  LSFT(KC_7) | ||||
| #define BE_8 	  LSFT(KC_8) | ||||
| #define BE_9 	  LSFT(KC_9) | ||||
| #define BE_0 	  LSFT(KC_0) | ||||
| #define BE_OVRR	KC_UNDS | ||||
| #define BE_1 LSFT(KC_1) | ||||
| #define BE_2 LSFT(KC_2) | ||||
| #define BE_3 LSFT(KC_3) | ||||
| #define BE_4 LSFT(KC_4) | ||||
| #define BE_5 LSFT(KC_5) | ||||
| #define BE_6 LSFT(KC_6) | ||||
| #define BE_7 LSFT(KC_7) | ||||
| #define BE_8 LSFT(KC_8) | ||||
| #define BE_9 LSFT(KC_9) | ||||
| #define BE_0 LSFT(KC_0) | ||||
| #define BE_OVRR KC_UNDS | ||||
| #define BE_UNDS KC_PLUS | ||||
| 
 | ||||
| // Line 2
 | ||||
| #define BE_UMLT	LSFT(BE_CIRC) | ||||
| #define BE_PND	LSFT(BE_DLR) | ||||
| #define BE_UMLT LSFT(BE_CIRC) | ||||
| #define BE_PND LSFT(BE_DLR) | ||||
| 
 | ||||
| // Line 3
 | ||||
| #define	BE_PERC	LSFT(BE_UGRV) | ||||
| #define BE_PERC LSFT(BE_UGRV) | ||||
| 
 | ||||
| // Line 4
 | ||||
| #define BE_GRTR	LSFT(BE_LESS) | ||||
| #define BE_QUES	LSFT(BE_COMM) | ||||
| #define BE_DOT	LSFT(BE_SCLN) | ||||
| #define BE_SLSH	LSFT(BE_COLN) | ||||
| #define BE_PLUS	LSFT(BE_EQL) | ||||
| #define BE_GRTR LSFT(BE_LESS) | ||||
| #define BE_QUES LSFT(BE_COMM) | ||||
| #define BE_DOT LSFT(BE_SCLN) | ||||
| #define BE_SLSH LSFT(BE_COLN) | ||||
| #define BE_PLUS LSFT(BE_EQL) | ||||
| 
 | ||||
| // Alt Gr-ed characters
 | ||||
| // Line 1
 | ||||
| #define BE_PIPE ALGR(KC_1) | ||||
| #define BE_AT	  ALGR(KC_2) | ||||
| #define BE_HASH	ALGR(KC_3) | ||||
| #define BE_AT ALGR(KC_2) | ||||
| #define BE_HASH ALGR(KC_3) | ||||
| #define BE_LCBR ALGR(KC_9) | ||||
| #define BE_RCBR	ALGR(KC_0) | ||||
| #define BE_RCBR ALGR(KC_0) | ||||
| 
 | ||||
| // Line 2
 | ||||
| #define BE_EURO	ALGR(KC_E) | ||||
| #define BE_EURO ALGR(KC_E) | ||||
| #define BE_LSBR ALGR(BE_CIRC) | ||||
| #define BE_RSBR ALGR(BE_DLR) | ||||
| 
 | ||||
| // Line 3
 | ||||
| #define BE_ACUT ALGR(BE_UGRV) | ||||
| #define BE_GRV	ALGR(BE_MU) | ||||
| #define BE_GRV ALGR(BE_MU) | ||||
| 
 | ||||
| // Line 4
 | ||||
| #define BE_BSLS ALGR(BE_LESS) | ||||
|  |  | |||
|  | @ -21,297 +21,297 @@ | |||
| 
 | ||||
| // Normal characters
 | ||||
| // First row (on usual keyboards)
 | ||||
| #define BP_DOLLAR           KC_GRAVE            // $
 | ||||
| #define BP_DLR              BP_DOLLAR | ||||
| #define BP_DOUBLE_QUOTE     KC_1                // "
 | ||||
| #define BP_DQOT             BP_DOUBLE_QUOTE | ||||
| #define BP_LEFT_GUILLEMET   KC_2                // «
 | ||||
| #define BP_LGIL             BP_LEFT_GUILLEMET | ||||
| #define BP_RIGHT_GUILLEMET  KC_3                // »
 | ||||
| #define BP_RGIL             BP_RIGHT_GUILLEMET | ||||
| #define BP_LEFT_PAREN       KC_4                // (
 | ||||
| #define BP_LPRN             BP_LEFT_PAREN | ||||
| #define BP_RIGHT_PAREN      KC_5                // )
 | ||||
| #define BP_RPRN             BP_RIGHT_PAREN | ||||
| #define BP_AT               KC_6                // @
 | ||||
| #define BP_PLUS             KC_7                // +
 | ||||
| #define BP_MINUS            KC_8                // -
 | ||||
| #define BP_MINS             BP_MINUS | ||||
| #define BP_SLASH            KC_9                // /
 | ||||
| #define BP_SLSH             BP_SLASH | ||||
| #define BP_ASTERISK         KC_0                // *
 | ||||
| #define BP_ASTR             BP_ASTERISK | ||||
| #define BP_EQUAL            KC_MINUS            // =
 | ||||
| #define BP_EQL              BP_EQUAL | ||||
| #define BP_PERCENT          KC_EQUAL            // %
 | ||||
| #define BP_PERC             BP_PERCENT | ||||
| #define BP_DOLLAR KC_GRAVE  // $
 | ||||
| #define BP_DLR BP_DOLLAR | ||||
| #define BP_DOUBLE_QUOTE KC_1  // "
 | ||||
| #define BP_DQOT BP_DOUBLE_QUOTE | ||||
| #define BP_LEFT_GUILLEMET KC_2  // «
 | ||||
| #define BP_LGIL BP_LEFT_GUILLEMET | ||||
| #define BP_RIGHT_GUILLEMET KC_3  // »
 | ||||
| #define BP_RGIL BP_RIGHT_GUILLEMET | ||||
| #define BP_LEFT_PAREN KC_4  // (
 | ||||
| #define BP_LPRN BP_LEFT_PAREN | ||||
| #define BP_RIGHT_PAREN KC_5  // )
 | ||||
| #define BP_RPRN BP_RIGHT_PAREN | ||||
| #define BP_AT KC_6     // @
 | ||||
| #define BP_PLUS KC_7   // +
 | ||||
| #define BP_MINUS KC_8  // -
 | ||||
| #define BP_MINS BP_MINUS | ||||
| #define BP_SLASH KC_9  // /
 | ||||
| #define BP_SLSH BP_SLASH | ||||
| #define BP_ASTERISK KC_0  // *
 | ||||
| #define BP_ASTR BP_ASTERISK | ||||
| #define BP_EQUAL KC_MINUS  // =
 | ||||
| #define BP_EQL BP_EQUAL | ||||
| #define BP_PERCENT KC_EQUAL  // %
 | ||||
| #define BP_PERC BP_PERCENT | ||||
| 
 | ||||
| // Second row
 | ||||
| #define BP_B                KC_Q | ||||
| #define BP_E_ACUTE          KC_W        // é
 | ||||
| #define BP_ECUT             BP_E_ACUTE | ||||
| #define BP_P                KC_E | ||||
| #define BP_O                KC_R | ||||
| #define BP_E_GRAVE          KC_T        // è
 | ||||
| #define BP_EGRV             BP_E_GRAVE | ||||
| #define BP_DEAD_CIRCUMFLEX  KC_Y        // dead ^
 | ||||
| #define BP_DCRC             BP_DEAD_CIRCUMFLEX | ||||
| #define BP_V                KC_U | ||||
| #define BP_D                KC_I | ||||
| #define BP_L                KC_O | ||||
| #define BP_J                KC_P | ||||
| #define BP_Z                KC_LBRACKET | ||||
| #define BP_W                KC_RBRACKET | ||||
| #define BP_B KC_Q | ||||
| #define BP_E_ACUTE KC_W  // é
 | ||||
| #define BP_ECUT BP_E_ACUTE | ||||
| #define BP_P KC_E | ||||
| #define BP_O KC_R | ||||
| #define BP_E_GRAVE KC_T  // è
 | ||||
| #define BP_EGRV BP_E_GRAVE | ||||
| #define BP_DEAD_CIRCUMFLEX KC_Y  // dead ^
 | ||||
| #define BP_DCRC BP_DEAD_CIRCUMFLEX | ||||
| #define BP_V KC_U | ||||
| #define BP_D KC_I | ||||
| #define BP_L KC_O | ||||
| #define BP_J KC_P | ||||
| #define BP_Z KC_LBRACKET | ||||
| #define BP_W KC_RBRACKET | ||||
| 
 | ||||
| // Third row
 | ||||
| #define BP_A            KC_A | ||||
| #define BP_U            KC_S | ||||
| #define BP_I            KC_D | ||||
| #define BP_E            KC_F | ||||
| #define BP_COMMA        KC_G        // ,
 | ||||
| #define BP_COMM         BP_COMMA | ||||
| #define BP_C            KC_H | ||||
| #define BP_T            KC_J | ||||
| #define BP_S            KC_K | ||||
| #define BP_R            KC_L | ||||
| #define BP_N            KC_SCOLON | ||||
| #define BP_M            KC_QUOTE | ||||
| #define BP_C_CEDILLA    KC_BSLASH   // ç
 | ||||
| #define BP_CCED         BP_C_CEDILLA | ||||
| #define BP_A KC_A | ||||
| #define BP_U KC_S | ||||
| #define BP_I KC_D | ||||
| #define BP_E KC_F | ||||
| #define BP_COMMA KC_G  // ,
 | ||||
| #define BP_COMM BP_COMMA | ||||
| #define BP_C KC_H | ||||
| #define BP_T KC_J | ||||
| #define BP_S KC_K | ||||
| #define BP_R KC_L | ||||
| #define BP_N KC_SCOLON | ||||
| #define BP_M KC_QUOTE | ||||
| #define BP_C_CEDILLA KC_BSLASH  // ç
 | ||||
| #define BP_CCED BP_C_CEDILLA | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define BP_E_CIRCUMFLEX     KC_NONUS_BSLASH // ê
 | ||||
| #define BP_ECRC             BP_E_CIRCUMFLEX | ||||
| #define BP_A_GRAVE          KC_Z            // à
 | ||||
| #define BP_AGRV             BP_A_GRAVE | ||||
| #define BP_Y                KC_X | ||||
| #define BP_X                KC_C | ||||
| #define BP_DOT              KC_V            // .
 | ||||
| #define BP_K                KC_B | ||||
| #define BP_APOSTROPHE       KC_N | ||||
| #define BP_APOS             BP_APOSTROPHE   // '
 | ||||
| #define BP_Q                KC_M | ||||
| #define BP_G                KC_COMMA | ||||
| #define BP_H                KC_DOT | ||||
| #define BP_F                KC_SLASH | ||||
| #define BP_E_CIRCUMFLEX KC_NONUS_BSLASH  // ê
 | ||||
| #define BP_ECRC BP_E_CIRCUMFLEX | ||||
| #define BP_A_GRAVE KC_Z  // à
 | ||||
| #define BP_AGRV BP_A_GRAVE | ||||
| #define BP_Y KC_X | ||||
| #define BP_X KC_C | ||||
| #define BP_DOT KC_V  // .
 | ||||
| #define BP_K KC_B | ||||
| #define BP_APOSTROPHE KC_N | ||||
| #define BP_APOS BP_APOSTROPHE  // '
 | ||||
| #define BP_Q KC_M | ||||
| #define BP_G KC_COMMA | ||||
| #define BP_H KC_DOT | ||||
| #define BP_F KC_SLASH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| // First row
 | ||||
| #define BP_HASH     LSFT(BP_DOLLAR)     // #
 | ||||
| #define BP_1        LSFT(KC_1) | ||||
| #define BP_2        LSFT(KC_2) | ||||
| #define BP_3        LSFT(KC_3) | ||||
| #define BP_4        LSFT(KC_4) | ||||
| #define BP_5        LSFT(KC_5) | ||||
| #define BP_6        LSFT(KC_6) | ||||
| #define BP_7        LSFT(KC_7) | ||||
| #define BP_8        LSFT(KC_8) | ||||
| #define BP_9        LSFT(KC_9) | ||||
| #define BP_0        LSFT(KC_0) | ||||
| #define BP_DEGREE   LSFT(BP_EQUAL)      // °
 | ||||
| #define BP_DEGR     BP_DEGREE | ||||
| #define BP_GRAVE    LSFT(BP_PERCENT)    // `
 | ||||
| #define BP_GRV      BP_GRAVE | ||||
| #define BP_HASH LSFT(BP_DOLLAR)  // #
 | ||||
| #define BP_1 LSFT(KC_1) | ||||
| #define BP_2 LSFT(KC_2) | ||||
| #define BP_3 LSFT(KC_3) | ||||
| #define BP_4 LSFT(KC_4) | ||||
| #define BP_5 LSFT(KC_5) | ||||
| #define BP_6 LSFT(KC_6) | ||||
| #define BP_7 LSFT(KC_7) | ||||
| #define BP_8 LSFT(KC_8) | ||||
| #define BP_9 LSFT(KC_9) | ||||
| #define BP_0 LSFT(KC_0) | ||||
| #define BP_DEGREE LSFT(BP_EQUAL)  // °
 | ||||
| #define BP_DEGR BP_DEGREE | ||||
| #define BP_GRAVE LSFT(BP_PERCENT)  // `
 | ||||
| #define BP_GRV BP_GRAVE | ||||
| 
 | ||||
| // Second row
 | ||||
| #define BP_EXCLAIM  LSFT(BP_DEAD_CIRCUMFLEX)    // !
 | ||||
| #define BP_EXLM     BP_EXCLAIM | ||||
| #define BP_EXCLAIM LSFT(BP_DEAD_CIRCUMFLEX)  // !
 | ||||
| #define BP_EXLM BP_EXCLAIM | ||||
| 
 | ||||
| // Third row
 | ||||
| #define BP_SCOLON   LSFT(BP_COMMA)  // ;
 | ||||
| #define BP_SCLN     BP_SCOLON | ||||
| #define BP_SCOLON LSFT(BP_COMMA)  // ;
 | ||||
| #define BP_SCLN BP_SCOLON | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define BP_COLON    LSFT(BP_DOT)    // :
 | ||||
| #define BP_COLN     BP_COLON | ||||
| #define BP_COLON LSFT(BP_DOT)  // :
 | ||||
| #define BP_COLN BP_COLON | ||||
| #define BP_QUESTION LSFT(BP_APOS)  // ?
 | ||||
| #define BP_QEST     BP_QUESTION | ||||
| #define BP_QEST BP_QUESTION | ||||
| 
 | ||||
| // Space bar
 | ||||
| #define BP_NON_BREAKING_SPACE   LSFT(KC_SPACE) | ||||
| #define BP_NBSP                 BP_NON_BREAKING_SPACE | ||||
| #define BP_NON_BREAKING_SPACE LSFT(KC_SPACE) | ||||
| #define BP_NBSP BP_NON_BREAKING_SPACE | ||||
| 
 | ||||
| // AltGr-ed characters
 | ||||
| // First row
 | ||||
| #define BP_EN_DASH          ALGR(BP_DOLLAR)     // –
 | ||||
| #define BP_NDSH             BP_EN_DASH | ||||
| #define BP_EM_DASH          ALGR(KC_1)          // —
 | ||||
| #define BP_MDSH             BP_EM_DASH | ||||
| #define BP_LESS             ALGR(KC_2)          // <
 | ||||
| #define BP_GREATER          ALGR(KC_3)          // >
 | ||||
| #define BP_GRTR             BP_GREATER | ||||
| #define BP_LBRACKET         ALGR(KC_4)          // [
 | ||||
| #define BP_LBRC             BP_LBRACKET | ||||
| #define BP_RBRACKET         ALGR(KC_5)          // ]
 | ||||
| #define BP_RBRC             BP_RBRACKET | ||||
| #define BP_CIRCUMFLEX       ALGR(KC_6)          // ^
 | ||||
| #define BP_CIRC             BP_CIRCUMFLEX | ||||
| #define BP_PLUS_MINUS       ALGR(KC_7)          // ±
 | ||||
| #define BP_PSMS             BP_PLUS_MINUS | ||||
| #define BP_MATH_MINUS       ALGR(KC_8)          // −
 | ||||
| #define BP_MMNS             BP_MATH_MINUS | ||||
| #define BP_OBELUS           ALGR(KC_9)          // ÷
 | ||||
| #define BP_OBEL             BP_OBELUS | ||||
| #define BP_EN_DASH ALGR(BP_DOLLAR)  // –
 | ||||
| #define BP_NDSH BP_EN_DASH | ||||
| #define BP_EM_DASH ALGR(KC_1)  // —
 | ||||
| #define BP_MDSH BP_EM_DASH | ||||
| #define BP_LESS ALGR(KC_2)     // <
 | ||||
| #define BP_GREATER ALGR(KC_3)  // >
 | ||||
| #define BP_GRTR BP_GREATER | ||||
| #define BP_LBRACKET ALGR(KC_4)  // [
 | ||||
| #define BP_LBRC BP_LBRACKET | ||||
| #define BP_RBRACKET ALGR(KC_5)  // ]
 | ||||
| #define BP_RBRC BP_RBRACKET | ||||
| #define BP_CIRCUMFLEX ALGR(KC_6)  // ^
 | ||||
| #define BP_CIRC BP_CIRCUMFLEX | ||||
| #define BP_PLUS_MINUS ALGR(KC_7)  // ±
 | ||||
| #define BP_PSMS BP_PLUS_MINUS | ||||
| #define BP_MATH_MINUS ALGR(KC_8)  // −
 | ||||
| #define BP_MMNS BP_MATH_MINUS | ||||
| #define BP_OBELUS ALGR(KC_9)  // ÷
 | ||||
| #define BP_OBEL BP_OBELUS | ||||
| // more conventional name of the symbol
 | ||||
| #define BP_DIVISION_SIGN    BP_OBELUS | ||||
| #define BP_DVSN             BP_DIVISION_SIGN | ||||
| #define BP_TIMES            ALGR(KC_0)          // ×
 | ||||
| #define BP_TIMS             BP_TIMES | ||||
| #define BP_DIFFERENT        ALGR(BP_EQUAL)      // ≠
 | ||||
| #define BP_DIFF             BP_DIFFERENT | ||||
| #define BP_PERMILLE         ALGR(BP_PERCENT)    // ‰
 | ||||
| #define BP_PMIL             BP_PERMILLE | ||||
| #define BP_DIVISION_SIGN BP_OBELUS | ||||
| #define BP_DVSN BP_DIVISION_SIGN | ||||
| #define BP_TIMES ALGR(KC_0)  // ×
 | ||||
| #define BP_TIMS BP_TIMES | ||||
| #define BP_DIFFERENT ALGR(BP_EQUAL)  // ≠
 | ||||
| #define BP_DIFF BP_DIFFERENT | ||||
| #define BP_PERMILLE ALGR(BP_PERCENT)  // ‰
 | ||||
| #define BP_PMIL BP_PERMILLE | ||||
| 
 | ||||
| // Second row
 | ||||
| #define BP_PIPE                 ALGR(BP_B)          // |
 | ||||
| #define BP_DEAD_ACUTE           ALGR(BP_E_ACUTE)    // dead ´
 | ||||
| #define BP_DACT                 BP_DEAD_ACUTE | ||||
| #define BP_AMPERSAND            ALGR(BP_P)          // &
 | ||||
| #define BP_AMPR                 BP_AMPERSAND | ||||
| #define BP_OE_LIGATURE          ALGR(BP_O)          // œ
 | ||||
| #define BP_OE                   BP_OE_LIGATURE | ||||
| #define BP_DEAD_GRAVE           ALGR(BP_E_GRAVE)    // `
 | ||||
| #define BP_DGRV                 BP_DEAD_GRAVE | ||||
| #define BP_INVERTED_EXCLAIM     ALGR(BP_DEAD_CIRCUMFLEX)    // ¡
 | ||||
| #define BP_IXLM                 BP_INVERTED_EXCLAIM | ||||
| #define BP_DEAD_CARON           ALGR(BP_V)          // dead ˇ
 | ||||
| #define BP_DCAR                 BP_DEAD_CARON | ||||
| #define BP_ETH                  ALGR(BP_D)          // ð
 | ||||
| #define BP_DEAD_SLASH           ALGR(BP_L)          // dead /
 | ||||
| #define BP_DSLH                 BP_DEAD_SLASH | ||||
| #define BP_IJ_LIGATURE          ALGR(BP_J)          // ij
 | ||||
| #define BP_IJ                   BP_IJ_LIGATURE | ||||
| #define BP_SCHWA                ALGR(BP_Z)          // ə
 | ||||
| #define BP_SCWA                 BP_SCHWA | ||||
| #define BP_DEAD_BREVE           ALGR(BP_W)          // dead ˘
 | ||||
| #define BP_DBRV                 BP_DEAD_BREVE | ||||
| #define BP_PIPE ALGR(BP_B)              // |
 | ||||
| #define BP_DEAD_ACUTE ALGR(BP_E_ACUTE)  // dead ´
 | ||||
| #define BP_DACT BP_DEAD_ACUTE | ||||
| #define BP_AMPERSAND ALGR(BP_P)  // &
 | ||||
| #define BP_AMPR BP_AMPERSAND | ||||
| #define BP_OE_LIGATURE ALGR(BP_O)  // œ
 | ||||
| #define BP_OE BP_OE_LIGATURE | ||||
| #define BP_DEAD_GRAVE ALGR(BP_E_GRAVE)  // `
 | ||||
| #define BP_DGRV BP_DEAD_GRAVE | ||||
| #define BP_INVERTED_EXCLAIM ALGR(BP_DEAD_CIRCUMFLEX)  // ¡
 | ||||
| #define BP_IXLM BP_INVERTED_EXCLAIM | ||||
| #define BP_DEAD_CARON ALGR(BP_V)  // dead ˇ
 | ||||
| #define BP_DCAR BP_DEAD_CARON | ||||
| #define BP_ETH ALGR(BP_D)         // ð
 | ||||
| #define BP_DEAD_SLASH ALGR(BP_L)  // dead /
 | ||||
| #define BP_DSLH BP_DEAD_SLASH | ||||
| #define BP_IJ_LIGATURE ALGR(BP_J)  // ij
 | ||||
| #define BP_IJ BP_IJ_LIGATURE | ||||
| #define BP_SCHWA ALGR(BP_Z)  // ə
 | ||||
| #define BP_SCWA BP_SCHWA | ||||
| #define BP_DEAD_BREVE ALGR(BP_W)  // dead ˘
 | ||||
| #define BP_DBRV BP_DEAD_BREVE | ||||
| 
 | ||||
| // Third row
 | ||||
| #define BP_AE_LIGATURE              ALGR(BP_A)          // æ
 | ||||
| #define BP_AE                       BP_AE_LIGATURE | ||||
| #define BP_U_GRAVE                  ALGR(BP_U)          // ù
 | ||||
| #define BP_UGRV                     BP_U_GRAVE | ||||
| #define BP_DEAD_TREMA               ALGR(BP_I)          // dead ¨ (trema/umlaut/diaresis)
 | ||||
| #define BP_DTRM                     BP_DEAD_TREMA | ||||
| #define BP_EURO                     ALGR(BP_E)          // €
 | ||||
| #define BP_TYPOGRAPHICAL_APOSTROPHE ALGR(BP_COMMA)      // ’
 | ||||
| #define BP_TAPO                     BP_TYPOGRAPHICAL_APOSTROPHE | ||||
| #define BP_COPYRIGHT                ALGR(BP_C)          // ©
 | ||||
| #define BP_CPRT                     BP_COPYRIGHT | ||||
| #define BP_THORN                    ALGR(BP_T)          // þ
 | ||||
| #define BP_THRN                     BP_THORN | ||||
| #define BP_SHARP_S                  ALGR(BP_S)          // ß
 | ||||
| #define BP_SRPS                     BP_SHARP_S | ||||
| #define BP_REGISTERED_TRADEMARK     ALGR(BP_R)          // ®
 | ||||
| #define BP_RTM                      BP_REGISTERED_TRADEMARK | ||||
| #define BP_DEAD_TILDE               ALGR(BP_N)          // dead ~
 | ||||
| #define BP_DTLD                     BP_DEAD_TILDE | ||||
| #define BP_DEAD_MACRON              ALGR(BP_M)          // dead ¯
 | ||||
| #define BP_DMCR                     BP_DEAD_MACRON | ||||
| #define BP_DEAD_CEDILLA             ALGR(BP_C_CEDILLA)  // dead ¸
 | ||||
| #define BP_DCED                     BP_DEAD_CEDILLA | ||||
| #define BP_AE_LIGATURE ALGR(BP_A)  // æ
 | ||||
| #define BP_AE BP_AE_LIGATURE | ||||
| #define BP_U_GRAVE ALGR(BP_U)  // ù
 | ||||
| #define BP_UGRV BP_U_GRAVE | ||||
| #define BP_DEAD_TREMA ALGR(BP_I)  // dead ¨ (trema/umlaut/diaresis)
 | ||||
| #define BP_DTRM BP_DEAD_TREMA | ||||
| #define BP_EURO ALGR(BP_E)                          // €
 | ||||
| #define BP_TYPOGRAPHICAL_APOSTROPHE ALGR(BP_COMMA)  // ’
 | ||||
| #define BP_TAPO BP_TYPOGRAPHICAL_APOSTROPHE | ||||
| #define BP_COPYRIGHT ALGR(BP_C)  // ©
 | ||||
| #define BP_CPRT BP_COPYRIGHT | ||||
| #define BP_THORN ALGR(BP_T)  // þ
 | ||||
| #define BP_THRN BP_THORN | ||||
| #define BP_SHARP_S ALGR(BP_S)  // ß
 | ||||
| #define BP_SRPS BP_SHARP_S | ||||
| #define BP_REGISTERED_TRADEMARK ALGR(BP_R)  // ®
 | ||||
| #define BP_RTM BP_REGISTERED_TRADEMARK | ||||
| #define BP_DEAD_TILDE ALGR(BP_N)  // dead ~
 | ||||
| #define BP_DTLD BP_DEAD_TILDE | ||||
| #define BP_DEAD_MACRON ALGR(BP_M)  // dead ¯
 | ||||
| #define BP_DMCR BP_DEAD_MACRON | ||||
| #define BP_DEAD_CEDILLA ALGR(BP_C_CEDILLA)  // dead ¸
 | ||||
| #define BP_DCED BP_DEAD_CEDILLA | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define BP_NONUS_SLASH          ALGR(BP_E_CIRCUMFLEX)   // / on non-us backslash key (102nd key, ê in bépo)
 | ||||
| #define BP_NUSL                 BP_NONUS_SLASH | ||||
| #define BP_BACKSLASH            ALGR(BP_A_GRAVE)        /* \ */ | ||||
| #define BP_BSLS                 BP_BACKSLASH | ||||
| #define BP_LEFT_CURLY_BRACE     ALGR(BP_Y)              // {
 | ||||
| #define BP_LCBR                 BP_LEFT_CURLY_BRACE | ||||
| #define BP_RIGHT_CURLY_BRACE    ALGR(BP_X)              // }
 | ||||
| #define BP_RCBR                 BP_RIGHT_CURLY_BRACE | ||||
| #define BP_ELLIPSIS             ALGR(BP_DOT)            // …
 | ||||
| #define BP_ELPS                 BP_ELLIPSIS | ||||
| #define BP_TILDE                ALGR(BP_K)              // ~
 | ||||
| #define BP_TILD                 BP_TILDE | ||||
| #define BP_INVERTED_QUESTION    ALGR(BP_QUESTION)       // ¿
 | ||||
| #define BP_IQST                 BP_INVERTED_QUESTION | ||||
| #define BP_DEAD_RING            ALGR(BP_Q)              // dead °
 | ||||
| #define BP_DRNG                 BP_DEAD_RING | ||||
| #define BP_DEAD_GREEK           ALGR(BP_G)              // dead Greek key (following key will make a Greek letter)
 | ||||
| #define BP_DGRK                 BP_DEAD_GREEK | ||||
| #define BP_DAGGER               ALGR(BP_H)              // †
 | ||||
| #define BP_DAGR                 BP_DAGGER | ||||
| #define BP_DEAD_OGONEK          ALGR(BP_F)              // dead ˛
 | ||||
| #define BP_DOGO                 BP_DEAD_OGONEK | ||||
| #define BP_NONUS_SLASH ALGR(BP_E_CIRCUMFLEX)  // / on non-us backslash key (102nd key, ê in bépo)
 | ||||
| #define BP_NUSL BP_NONUS_SLASH | ||||
| #define BP_BACKSLASH ALGR(BP_A_GRAVE) /* \ */ | ||||
| #define BP_BSLS BP_BACKSLASH | ||||
| #define BP_LEFT_CURLY_BRACE ALGR(BP_Y)  // {
 | ||||
| #define BP_LCBR BP_LEFT_CURLY_BRACE | ||||
| #define BP_RIGHT_CURLY_BRACE ALGR(BP_X)  // }
 | ||||
| #define BP_RCBR BP_RIGHT_CURLY_BRACE | ||||
| #define BP_ELLIPSIS ALGR(BP_DOT)  // …
 | ||||
| #define BP_ELPS BP_ELLIPSIS | ||||
| #define BP_TILDE ALGR(BP_K)  // ~
 | ||||
| #define BP_TILD BP_TILDE | ||||
| #define BP_INVERTED_QUESTION ALGR(BP_QUESTION)  // ¿
 | ||||
| #define BP_IQST BP_INVERTED_QUESTION | ||||
| #define BP_DEAD_RING ALGR(BP_Q)  // dead °
 | ||||
| #define BP_DRNG BP_DEAD_RING | ||||
| #define BP_DEAD_GREEK ALGR(BP_G)  // dead Greek key (following key will make a Greek letter)
 | ||||
| #define BP_DGRK BP_DEAD_GREEK | ||||
| #define BP_DAGGER ALGR(BP_H)  // †
 | ||||
| #define BP_DAGR BP_DAGGER | ||||
| #define BP_DEAD_OGONEK ALGR(BP_F)  // dead ˛
 | ||||
| #define BP_DOGO BP_DEAD_OGONEK | ||||
| 
 | ||||
| // Space bar
 | ||||
| #define BP_UNDERSCORE   ALGR(KC_SPACE)      // _
 | ||||
| #define BP_UNDS         BP_UNDERSCORE | ||||
| #define BP_UNDERSCORE ALGR(KC_SPACE)  // _
 | ||||
| #define BP_UNDS BP_UNDERSCORE | ||||
| 
 | ||||
| // AltGr-Shifted characters (different from capitalised AltGr-ed characters)
 | ||||
| // First row
 | ||||
| #define BP_PARAGRAPH            ALGR(BP_HASH)       // ¶
 | ||||
| #define BP_PARG                 BP_PARAGRAPH | ||||
| #define BP_LOW_DOUBLE_QUOTE     ALGR(BP_1)          // „
 | ||||
| #define BP_LWQT                 BP_LOW_DOUBLE_QUOTE | ||||
| #define BP_LEFT_DOUBLE_QUOTE    ALGR(BP_2)          // “
 | ||||
| #define BP_LDQT                 BP_LEFT_DOUBLE_QUOTE | ||||
| #define BP_RIGHT_DOUBLE_QUOTE   ALGR(BP_3)          // ”
 | ||||
| #define BP_RDQT                 BP_RIGHT_DOUBLE_QUOTE | ||||
| #define BP_LESS_OR_EQUAL        ALGR(BP_4)          // ≤
 | ||||
| #define BP_LEQL                 BP_LESS_OR_EQUAL | ||||
| #define BP_GREATER_OR_EQUAL     ALGR(BP_5)          // ≥
 | ||||
| #define BP_GEQL                 BP_GREATER_OR_EQUAL | ||||
| #define BP_PARAGRAPH ALGR(BP_HASH)  // ¶
 | ||||
| #define BP_PARG BP_PARAGRAPH | ||||
| #define BP_LOW_DOUBLE_QUOTE ALGR(BP_1)  // „
 | ||||
| #define BP_LWQT BP_LOW_DOUBLE_QUOTE | ||||
| #define BP_LEFT_DOUBLE_QUOTE ALGR(BP_2)  // “
 | ||||
| #define BP_LDQT BP_LEFT_DOUBLE_QUOTE | ||||
| #define BP_RIGHT_DOUBLE_QUOTE ALGR(BP_3)  // ”
 | ||||
| #define BP_RDQT BP_RIGHT_DOUBLE_QUOTE | ||||
| #define BP_LESS_OR_EQUAL ALGR(BP_4)  // ≤
 | ||||
| #define BP_LEQL BP_LESS_OR_EQUAL | ||||
| #define BP_GREATER_OR_EQUAL ALGR(BP_5)  // ≥
 | ||||
| #define BP_GEQL BP_GREATER_OR_EQUAL | ||||
| // nothing on ALGR(BP_6)
 | ||||
| #define BP_NEGATION             ALGR(BP_7)          // ¬
 | ||||
| #define BP_NEGT                 BP_NEGATION | ||||
| #define BP_ONE_QUARTER          ALGR(BP_8)          // ¼
 | ||||
| #define BP_1QRT                 BP_ONE_QUARTER | ||||
| #define BP_ONE_HALF             ALGR(BP_9)          // ½
 | ||||
| #define BP_1HLF                 BP_ONE_HALF | ||||
| #define BP_THREE_QUARTERS       ALGR(BP_0)          // ¾
 | ||||
| #define BP_3QRT                 BP_THREE_QUARTERS | ||||
| #define BP_MINUTES              ALGR(BP_DEGREE)     // ′
 | ||||
| #define BP_MNUT                 BP_MINUTES | ||||
| #define BP_SECONDS              ALGR(BP_GRAVE)      // ″
 | ||||
| #define BP_SCND                 BP_SECONDS | ||||
| #define BP_NEGATION ALGR(BP_7)  // ¬
 | ||||
| #define BP_NEGT BP_NEGATION | ||||
| #define BP_ONE_QUARTER ALGR(BP_8)  // ¼
 | ||||
| #define BP_1QRT BP_ONE_QUARTER | ||||
| #define BP_ONE_HALF ALGR(BP_9)  // ½
 | ||||
| #define BP_1HLF BP_ONE_HALF | ||||
| #define BP_THREE_QUARTERS ALGR(BP_0)  // ¾
 | ||||
| #define BP_3QRT BP_THREE_QUARTERS | ||||
| #define BP_MINUTES ALGR(BP_DEGREE)  // ′
 | ||||
| #define BP_MNUT BP_MINUTES | ||||
| #define BP_SECONDS ALGR(BP_GRAVE)  // ″
 | ||||
| #define BP_SCND BP_SECONDS | ||||
| 
 | ||||
| // Second row
 | ||||
| #define BP_BROKEN_PIPE          LSFT(BP_PIPE)           // ¦
 | ||||
| #define BP_BPIP                 BP_BROKEN_PIPE | ||||
| #define BP_DEAD_DOUBLE_ACUTE    LSFT(BP_DEAD_ACUTE)     // ˝
 | ||||
| #define BP_DDCT                 BP_DEAD_DOUBLE_ACUTE | ||||
| #define BP_SECTION              ALGR(LSFT(BP_P))        // §
 | ||||
| #define BP_SECT                 BP_SECTION | ||||
| #define BP_BROKEN_PIPE LSFT(BP_PIPE)  // ¦
 | ||||
| #define BP_BPIP BP_BROKEN_PIPE | ||||
| #define BP_DEAD_DOUBLE_ACUTE LSFT(BP_DEAD_ACUTE)  // ˝
 | ||||
| #define BP_DDCT BP_DEAD_DOUBLE_ACUTE | ||||
| #define BP_SECTION ALGR(LSFT(BP_P))  // §
 | ||||
| #define BP_SECT BP_SECTION | ||||
| // LSFT(BP_DEAD_GRAVE) is actually the same character as LSFT(BP_PERCENT)
 | ||||
| #define BP_GRAVE_BIS            LSFT(BP_DEAD_GRAVE)     // `
 | ||||
| #define BP_GRVB                 BP_GRAVE_BIS | ||||
| #define BP_GRAVE_BIS LSFT(BP_DEAD_GRAVE)  // `
 | ||||
| #define BP_GRVB BP_GRAVE_BIS | ||||
| 
 | ||||
| // Third row
 | ||||
| #define BP_DEAD_DOT_ABOVE       LSFT(BP_DEAD_TREMA)     // dead ˙
 | ||||
| #define BP_DDTA                 BP_DEAD_DOT_ABOVE | ||||
| #define BP_DEAD_CURRENCY        LSFT(BP_EURO)           // dead ¤ (next key will generate a currency code like ¥ or £)
 | ||||
| #define BP_DCUR                 BP_DEAD_CURRENCY | ||||
| #define BP_DEAD_HORN            LSFT(ALGR(BP_COMMA))    // dead ̛
 | ||||
| #define BP_DHRN                 BP_DEAD_HORN | ||||
| #define BP_LONG_S               LSFT(ALGR(BP_C))        // ſ
 | ||||
| #define BP_LNGS                 BP_LONG_S | ||||
| #define BP_TRADEMARK            LSFT(BP_REGISTERED_TRADEMARK)   // ™
 | ||||
| #define BP_TM                   BP_TRADEMARK | ||||
| #define BP_ORDINAL_INDICATOR_O  LSFT(ALGR(BP_M))        // º
 | ||||
| #define BP_ORDO                 BP_ORDINAL_INDICATOR_O | ||||
| #define BP_DEAD_COMMA           LSFT(BP_DEAD_CEDILLA)   // dead ˛
 | ||||
| #define BP_DCOM                 BP_DEAD_COMMA | ||||
| #define BP_DEAD_DOT_ABOVE LSFT(BP_DEAD_TREMA)  // dead ˙
 | ||||
| #define BP_DDTA BP_DEAD_DOT_ABOVE | ||||
| #define BP_DEAD_CURRENCY LSFT(BP_EURO)  // dead ¤ (next key will generate a currency code like ¥ or £)
 | ||||
| #define BP_DCUR BP_DEAD_CURRENCY | ||||
| #define BP_DEAD_HORN LSFT(ALGR(BP_COMMA))  // dead ̛
 | ||||
| #define BP_DHRN BP_DEAD_HORN | ||||
| #define BP_LONG_S LSFT(ALGR(BP_C))  // ſ
 | ||||
| #define BP_LNGS BP_LONG_S | ||||
| #define BP_TRADEMARK LSFT(BP_REGISTERED_TRADEMARK)  // ™
 | ||||
| #define BP_TM BP_TRADEMARK | ||||
| #define BP_ORDINAL_INDICATOR_O LSFT(ALGR(BP_M))  // º
 | ||||
| #define BP_ORDO BP_ORDINAL_INDICATOR_O | ||||
| #define BP_DEAD_COMMA LSFT(BP_DEAD_CEDILLA)  // dead ˛
 | ||||
| #define BP_DCOM BP_DEAD_COMMA | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define BP_LEFT_QUOTE           LSFT(ALGR(BP_Y))        // ‘
 | ||||
| #define BP_LQOT                 BP_LEFT_QUOTE | ||||
| #define BP_RIGHT_QUOTE          LSFT(ALGR(BP_X))        // ’
 | ||||
| #define BP_RQOT                 BP_RIGHT_QUOTE | ||||
| #define BP_INTERPUNCT           LSFT(ALGR(BP_DOT))      // ·
 | ||||
| #define BP_IPCT                 BP_INTERPUNCT | ||||
| #define BP_DEAD_HOOK_ABOVE      LSFT(ALGR(BP_QUESTION)) // dead ̉
 | ||||
| #define BP_DHKA                 BP_DEAD_HOOK_ABOVE | ||||
| #define BP_DEAD_UNDERDOT        LSFT(BP_DEAD_RING)      // dead ̣
 | ||||
| #define BP_DUDT                 BP_DEAD_UNDERDOT | ||||
| #define BP_DOUBLE_DAGGER        LSFT(BP_DAGGER)         // ‡
 | ||||
| #define BP_DDGR                 BP_DOUBLE_DAGGER | ||||
| #define BP_ORDINAL_INDICATOR_A  LSFT(ALGR(BP_F))        // ª
 | ||||
| #define BP_ORDA                 BP_ORDINAL_INDICATOR_A | ||||
| #define BP_LEFT_QUOTE LSFT(ALGR(BP_Y))  // ‘
 | ||||
| #define BP_LQOT BP_LEFT_QUOTE | ||||
| #define BP_RIGHT_QUOTE LSFT(ALGR(BP_X))  // ’
 | ||||
| #define BP_RQOT BP_RIGHT_QUOTE | ||||
| #define BP_INTERPUNCT LSFT(ALGR(BP_DOT))  // ·
 | ||||
| #define BP_IPCT BP_INTERPUNCT | ||||
| #define BP_DEAD_HOOK_ABOVE LSFT(ALGR(BP_QUESTION))  // dead ̉
 | ||||
| #define BP_DHKA BP_DEAD_HOOK_ABOVE | ||||
| #define BP_DEAD_UNDERDOT LSFT(BP_DEAD_RING)  // dead ̣
 | ||||
| #define BP_DUDT BP_DEAD_UNDERDOT | ||||
| #define BP_DOUBLE_DAGGER LSFT(BP_DAGGER)  // ‡
 | ||||
| #define BP_DDGR BP_DOUBLE_DAGGER | ||||
| #define BP_ORDINAL_INDICATOR_A LSFT(ALGR(BP_F))  // ª
 | ||||
| #define BP_ORDA BP_ORDINAL_INDICATOR_A | ||||
| 
 | ||||
| // Space bar
 | ||||
| #define BP_NARROW_NON_BREAKING_SPACE    ALGR(BP_NON_BREAKING_SPACE) | ||||
| #define BP_NNBS                         BP_NARROW_NON_BREAKING_SPACE | ||||
| #define BP_NARROW_NON_BREAKING_SPACE ALGR(BP_NON_BREAKING_SPACE) | ||||
| #define BP_NNBS BP_NARROW_NON_BREAKING_SPACE | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -21,54 +21,54 @@ | |||
| 
 | ||||
| /* Scan codes for the Brazilian ABNT2 keyboard layout */ | ||||
| 
 | ||||
| #define BR_CCDL KC_SCLN      //  Ç   same scancode as ;: on US layout
 | ||||
| #define BR_SCLN KC_SLSH      //  ;:  same scancode as /? on US layout
 | ||||
| #define BR_QUOT KC_GRV       //  '"  same scancode as `~ on US layout
 | ||||
| #define BR_TILD KC_QUOT      //  ~^  dead keys, same scancode as '" on US layout
 | ||||
| #define BR_ACUT KC_LBRC      //  ´`  dead keys, same scancode as [{ on US layout
 | ||||
| #define BR_LBRC KC_RBRC      //  [{  same scancode as ]} on US layout
 | ||||
| #define BR_RBRC KC_BSLS      //  ]}  same scancode as \| on US layout
 | ||||
| #define BR_BSLS KC_NUBS      //  \|  uses the non-US hash scancode (#~, sometimes §±)
 | ||||
| #define BR_SLSH KC_INT1      //  /?  uses the INTL1 scancode
 | ||||
| #define BR_CCDL KC_SCLN  //  Ç   same scancode as ;: on US layout
 | ||||
| #define BR_SCLN KC_SLSH  //  ;:  same scancode as /? on US layout
 | ||||
| #define BR_QUOT KC_GRV   //  '"  same scancode as `~ on US layout
 | ||||
| #define BR_TILD KC_QUOT  //  ~^  dead keys, same scancode as '" on US layout
 | ||||
| #define BR_ACUT KC_LBRC  //  ´`  dead keys, same scancode as [{ on US layout
 | ||||
| #define BR_LBRC KC_RBRC  //  [{  same scancode as ]} on US layout
 | ||||
| #define BR_RBRC KC_BSLS  //  ]}  same scancode as \| on US layout
 | ||||
| #define BR_BSLS KC_NUBS  //  \|  uses the non-US hash scancode (#~, sometimes §±)
 | ||||
| #define BR_SLSH KC_INT1  //  /?  uses the INTL1 scancode
 | ||||
| 
 | ||||
| #define BR_COLN LSFT(BR_SCLN)   // shifted :
 | ||||
| #define BR_DQT  LSFT(BR_QUOT)   // shifted "
 | ||||
| #define BR_CIRC LSFT(BR_TILD)   // shifted ^ (dead key)
 | ||||
| #define BR_GRAV LSFT(BR_ACUT)   // shifted ` (dead key)
 | ||||
| #define BR_LCBR LSFT(BR_LBRC)   // shifted {
 | ||||
| #define BR_RCBR LSFT(BR_RBRC)   // shifted }
 | ||||
| #define BR_PIPE LSFT(BR_BSLS)   // shifted |
 | ||||
| #define BR_QUES LSFT(BR_SLSH)   // shifted ?
 | ||||
| #define BR_TRMA LSFT(KC_6)      // shifted ¨ (dead key - trema accent)
 | ||||
| #define BR_COLN LSFT(BR_SCLN)  // shifted :
 | ||||
| #define BR_DQT LSFT(BR_QUOT)   // shifted "
 | ||||
| #define BR_CIRC LSFT(BR_TILD)  // shifted ^ (dead key)
 | ||||
| #define BR_GRAV LSFT(BR_ACUT)  // shifted ` (dead key)
 | ||||
| #define BR_LCBR LSFT(BR_LBRC)  // shifted {
 | ||||
| #define BR_RCBR LSFT(BR_RBRC)  // shifted }
 | ||||
| #define BR_PIPE LSFT(BR_BSLS)  // shifted |
 | ||||
| #define BR_QUES LSFT(BR_SLSH)  // shifted ?
 | ||||
| #define BR_TRMA LSFT(KC_6)     // shifted ¨ (dead key - trema accent)
 | ||||
| 
 | ||||
| // On the ABNT2 the keypad comma and the keypad dot scancodes are switched
 | ||||
| // (presumably because in Brazil comma is used as the decimal separator)
 | ||||
| #define BR_KPDT KC_KP_COMMA  //  keypad .
 | ||||
| #define BR_KPCM KC_KP_DOT    //  keypad ,
 | ||||
| 
 | ||||
| #define BR_1UP    LALT(KC_1)      // 1 superscript                    ¹   alt+1
 | ||||
| #define BR_2UP    LALT(KC_2)      // 2 superscript                    ²   alt+2
 | ||||
| #define BR_3UP    LALT(KC_3)      // 3 superscript                    ³   alt+3
 | ||||
| #define BR_PND    LALT(KC_4)      // Pound sign                       £   alt+4
 | ||||
| #define BR_CENT   LALT(KC_5)      // Cent sign                        ¢   alt+5
 | ||||
| #define BR_NOT    LALT(KC_6)      // Not sign                         ¬   alt+6
 | ||||
| #define BR_SECT   LALT(KC_EQL)    // Section sign                     §   alt+=
 | ||||
| #define BR_FORD   LALT(BR_LBRC)   // Feminine Ordinal Sign            ª   alt+[
 | ||||
| #define BR_MORD   LALT(BR_RBRC)   // Masculine Ordinal Sign           º   alt+]
 | ||||
| #define BR_DGRE   LALT(BR_SLSH)   // Degree sign                      °   alt+/
 | ||||
| #define BR_1UP LALT(KC_1)      // 1 superscript                    ¹   alt+1
 | ||||
| #define BR_2UP LALT(KC_2)      // 2 superscript                    ²   alt+2
 | ||||
| #define BR_3UP LALT(KC_3)      // 3 superscript                    ³   alt+3
 | ||||
| #define BR_PND LALT(KC_4)      // Pound sign                       £   alt+4
 | ||||
| #define BR_CENT LALT(KC_5)     // Cent sign                        ¢   alt+5
 | ||||
| #define BR_NOT LALT(KC_6)      // Not sign                         ¬   alt+6
 | ||||
| #define BR_SECT LALT(KC_EQL)   // Section sign                     §   alt+=
 | ||||
| #define BR_FORD LALT(BR_LBRC)  // Feminine Ordinal Sign            ª   alt+[
 | ||||
| #define BR_MORD LALT(BR_RBRC)  // Masculine Ordinal Sign           º   alt+]
 | ||||
| #define BR_DGRE LALT(BR_SLSH)  // Degree sign                      °   alt+/
 | ||||
| 
 | ||||
| #define BR_EURO   LALT(KC_E)      // Euro sign                        €   alt+e
 | ||||
| #define BR_NDTD   LALT(BR_TILD)   // Non-dead key tilde               ~   alt+~
 | ||||
| #define BR_NDAC   LALT(BR_ACUT)   // Non-dead key acute accent        ´   alt+´
 | ||||
| #define BR_NDGV   LALT(BR_QUOT)   // Non-dead key grave accent        `   alt+'
 | ||||
| #define BR_NDCR   LALT(BR_CIRC)   // Non-dead key circumflex accent   ^   alt+^ (alt+shift+~)
 | ||||
| #define BR_NDTR   LALT(BR_TRMA)   // Non-dead key trema accent        ¨   alt+¨ (alt+shift+6)
 | ||||
| #define BR_EURO LALT(KC_E)     // Euro sign                        €   alt+e
 | ||||
| #define BR_NDTD LALT(BR_TILD)  // Non-dead key tilde               ~   alt+~
 | ||||
| #define BR_NDAC LALT(BR_ACUT)  // Non-dead key acute accent        ´   alt+´
 | ||||
| #define BR_NDGV LALT(BR_QUOT)  // Non-dead key grave accent        `   alt+'
 | ||||
| #define BR_NDCR LALT(BR_CIRC)  // Non-dead key circumflex accent   ^   alt+^ (alt+shift+~)
 | ||||
| #define BR_NDTR LALT(BR_TRMA)  // Non-dead key trema accent        ¨   alt+¨ (alt+shift+6)
 | ||||
| 
 | ||||
| // For 101-key keyboard layouts, the ABNT2 layout allows
 | ||||
| // the slash and question mark to be typed using alt+q and alt+w.
 | ||||
| // The shortcuts are provided here for completeness' sake,
 | ||||
| // but it's recommended to use BR_SLSH and BR_QUES instead
 | ||||
| #define BR_ASLS   LALT(KC_Q) | ||||
| #define BR_AQST   LALT(KC_W) | ||||
| #define BR_ASLS LALT(KC_Q) | ||||
| #define BR_AQST LALT(KC_W) | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -19,241 +19,241 @@ | |||
| #include "keymap.h" | ||||
| 
 | ||||
| #ifndef GR2A | ||||
| #define GR2A(kc)    RCTL(kc) | ||||
| #    define GR2A(kc) RCTL(kc) | ||||
| #endif | ||||
| 
 | ||||
| // Normal characters
 | ||||
| // First row
 | ||||
| #define CSA_SLASH   KC_GRV      // /
 | ||||
| #define CSA_SLSH    CSA_SLASH | ||||
| #define CSA_SLASH KC_GRV  // /
 | ||||
| #define CSA_SLSH CSA_SLASH | ||||
| 
 | ||||
| // Second row
 | ||||
| #define CSA_DEAD_CIRCUMFLEX     KC_LBRACKET         // dead ^
 | ||||
| #define CSA_DCRC                CSA_DEAD_CIRCUMFLEX | ||||
| #define CSA_C_CEDILLA           KC_RBRACKET         // Ç
 | ||||
| #define CSA_CCED                CSA_C_CEDILLA | ||||
| #define CSA_DEAD_CIRCUMFLEX KC_LBRACKET  // dead ^
 | ||||
| #define CSA_DCRC CSA_DEAD_CIRCUMFLEX | ||||
| #define CSA_C_CEDILLA KC_RBRACKET  // Ç
 | ||||
| #define CSA_CCED CSA_C_CEDILLA | ||||
| 
 | ||||
| // Third row
 | ||||
| #define CSA_E_GRAVE     KC_QUOT     // è
 | ||||
| #define CSA_EGRV        CSA_E_GRAVE | ||||
| #define CSA_A_GRAVE     KC_BSLASH   // à
 | ||||
| #define CSA_AGRV        CSA_A_GRAVE | ||||
| #define CSA_E_GRAVE KC_QUOT  // è
 | ||||
| #define CSA_EGRV CSA_E_GRAVE | ||||
| #define CSA_A_GRAVE KC_BSLASH  // à
 | ||||
| #define CSA_AGRV CSA_A_GRAVE | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define CSA_U_GRAVE     KC_NONUS_BSLASH     // ù
 | ||||
| #define CSA_UGRV        CSA_U_GRAVE | ||||
| #define CSA_E_ACUTE     KC_SLSH             // é
 | ||||
| #define CSA_ECUT        CSA_E_ACUTE | ||||
| #define CSA_U_GRAVE KC_NONUS_BSLASH  // ù
 | ||||
| #define CSA_UGRV CSA_U_GRAVE | ||||
| #define CSA_E_ACUTE KC_SLSH  // é
 | ||||
| #define CSA_ECUT CSA_E_ACUTE | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| // First row
 | ||||
| #define CSA_BACKSLASH   LSFT(CSA_SLASH) /* \ */ | ||||
| #define CSA_BSLS        CSA_BACKSLASH | ||||
| #define CSA_QUESTION    LSFT(KC_6)      // ?
 | ||||
| #define CSA_QEST        CSA_QUESTION | ||||
| #define CSA_BACKSLASH LSFT(CSA_SLASH) /* \ */ | ||||
| #define CSA_BSLS CSA_BACKSLASH | ||||
| #define CSA_QUESTION LSFT(KC_6)  // ?
 | ||||
| #define CSA_QEST CSA_QUESTION | ||||
| 
 | ||||
| // Second row
 | ||||
| #define CSA_DEAD_TREMA  LSFT(CSA_DEAD_CIRCUMFLEX)    // dead trema/umlaut/diaresis for ä ë ï ö ü
 | ||||
| #define CSA_DTRM        CSA_DEAD_TREMA | ||||
| #define CSA_DEAD_TREMA LSFT(CSA_DEAD_CIRCUMFLEX)  // dead trema/umlaut/diaresis for ä ë ï ö ü
 | ||||
| #define CSA_DTRM CSA_DEAD_TREMA | ||||
| 
 | ||||
| // Third row
 | ||||
| // all same as US-QWERTY, or capitalised character of the non-shifted key
 | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define CSA_APOSTROPHE      LSFT(KC_COMMA)  // '
 | ||||
| #define CSA_APOS            CSA_APOSTROPHE | ||||
| #define CSA_DOUBLE_QUOTE    LSFT(KC_DOT)    // "
 | ||||
| #define CSA_DQOT            CSA_DOUBLE_QUOTE | ||||
| #define CSA_APOSTROPHE LSFT(KC_COMMA)  // '
 | ||||
| #define CSA_APOS CSA_APOSTROPHE | ||||
| #define CSA_DOUBLE_QUOTE LSFT(KC_DOT)  // "
 | ||||
| #define CSA_DQOT CSA_DOUBLE_QUOTE | ||||
| 
 | ||||
| // Alt Gr-ed characters
 | ||||
| // First row
 | ||||
| #define CSA_PIPE                ALGR(CSA_SLASH)         // |
 | ||||
| #define CSA_CURRENCY            ALGR(KC_4)              // ¤
 | ||||
| #define CSA_CURR                CSA_CURRENCY | ||||
| #define CSA_LEFT_CURLY_BRACE    ALGR(KC_7)              // {
 | ||||
| #define CSA_LCBR                CSA_LEFT_CURLY_BRACE | ||||
| #define CSA_RIGHT_CURLY_BRACE   ALGR(KC_8)              // }
 | ||||
| #define CSA_RCBR                CSA_RIGHT_CURLY_BRACE | ||||
| #define CSA_LBRACKET            ALGR(KC_9)              // [
 | ||||
| #define CSA_LBRC                CSA_LBRACKET | ||||
| #define CSA_RBRACKET            ALGR(KC_0)              // ]
 | ||||
| #define CSA_RBRC                CSA_RBRACKET | ||||
| #define CSA_NEGATION            ALGR(KC_EQUAL)          // ¬
 | ||||
| #define CSA_NEGT                CSA_NEGATION | ||||
| #define CSA_PIPE ALGR(CSA_SLASH)  // |
 | ||||
| #define CSA_CURRENCY ALGR(KC_4)   // ¤
 | ||||
| #define CSA_CURR CSA_CURRENCY | ||||
| #define CSA_LEFT_CURLY_BRACE ALGR(KC_7)  // {
 | ||||
| #define CSA_LCBR CSA_LEFT_CURLY_BRACE | ||||
| #define CSA_RIGHT_CURLY_BRACE ALGR(KC_8)  // }
 | ||||
| #define CSA_RCBR CSA_RIGHT_CURLY_BRACE | ||||
| #define CSA_LBRACKET ALGR(KC_9)  // [
 | ||||
| #define CSA_LBRC CSA_LBRACKET | ||||
| #define CSA_RBRACKET ALGR(KC_0)  // ]
 | ||||
| #define CSA_RBRC CSA_RBRACKET | ||||
| #define CSA_NEGATION ALGR(KC_EQUAL)  // ¬
 | ||||
| #define CSA_NEGT CSA_NEGATION | ||||
| 
 | ||||
| // Second row
 | ||||
| // euro symbol not available on Linux? (X.org)
 | ||||
| #define CSA_EURO        ALGR(KC_E)                  // €
 | ||||
| #define CSA_DEAD_GRAVE  ALGR(CSA_DEAD_CIRCUMFLEX) | ||||
| #define CSA_DGRV        CSA_DEAD_GRAVE              // dead `
 | ||||
| #define CSA_DEAD_TILDE  ALGR(CSA_C_CEDILLA)         // ~
 | ||||
| #define CSA_DTLD        CSA_DEAD_TILDE | ||||
| #define CSA_EURO ALGR(KC_E)  // €
 | ||||
| #define CSA_DEAD_GRAVE ALGR(CSA_DEAD_CIRCUMFLEX) | ||||
| #define CSA_DGRV CSA_DEAD_GRAVE             // dead `
 | ||||
| #define CSA_DEAD_TILDE ALGR(CSA_C_CEDILLA)  // ~
 | ||||
| #define CSA_DTLD CSA_DEAD_TILDE | ||||
| 
 | ||||
| // Third row
 | ||||
| #define CSA_DEGREE  ALGR(KC_SCOLON)     // °
 | ||||
| #define CSA_DEGR    CSA_DEGREE | ||||
| #define CSA_DEGREE ALGR(KC_SCOLON)  // °
 | ||||
| #define CSA_DEGR CSA_DEGREE | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define CSA_LEFT_GUILLEMET      ALGR(KC_Z)          // «
 | ||||
| #define CSA_LGIL                CSA_LEFT_GUILLEMET | ||||
| #define CSA_RIGHT_GUILLEMET     ALGR(KC_X)          // »
 | ||||
| #define CSA_RGIL                CSA_RIGHT_GUILLEMET | ||||
| #define CSA_LESS                ALGR(KC_COMMA)      // <
 | ||||
| #define CSA_GREATER             ALGR(KC_DOT)        // >
 | ||||
| #define CSA_GRTR                CSA_GREATER | ||||
| #define CSA_LEFT_GUILLEMET ALGR(KC_Z)  // «
 | ||||
| #define CSA_LGIL CSA_LEFT_GUILLEMET | ||||
| #define CSA_RIGHT_GUILLEMET ALGR(KC_X)  // »
 | ||||
| #define CSA_RGIL CSA_RIGHT_GUILLEMET | ||||
| #define CSA_LESS ALGR(KC_COMMA)   // <
 | ||||
| #define CSA_GREATER ALGR(KC_DOT)  // >
 | ||||
| #define CSA_GRTR CSA_GREATER | ||||
| 
 | ||||
| // Space bar
 | ||||
| #define CSA_NON_BREAKING_SPACE  ALGR(KC_SPACE) | ||||
| #define CSA_NBSP                CSA_NON_BREAKING_SPACE | ||||
| #define CSA_NON_BREAKING_SPACE ALGR(KC_SPACE) | ||||
| #define CSA_NBSP CSA_NON_BREAKING_SPACE | ||||
| 
 | ||||
| // GR2A-ed characters
 | ||||
| // First row
 | ||||
| #define CSA_SUPERSCRIPT_ONE     GR2A(KC_1)  // ¹
 | ||||
| #define CSA_SUP1                CSA_SUPERSCRIPT_ONE | ||||
| #define CSA_SUPERSCRIPT_TWO     GR2A(KC_2)  // ²
 | ||||
| #define CSA_SUP2                CSA_SUPERSCRIPT_TWO | ||||
| #define CSA_SUPERSCRIPT_THREE   GR2A(KC_3)  // ³
 | ||||
| #define CSA_SUP3                CSA_SUPERSCRIPT_THREE | ||||
| #define CSA_ONE_QUARTER         GR2A(KC_4)  // ¼
 | ||||
| #define CSA_1QRT                CSA_ONE_QUARTER | ||||
| #define CSA_ONE_HALF            GR2A(KC_5)  // ½
 | ||||
| #define CSA_1HLF                CSA_ONE_HALF | ||||
| #define CSA_THREE_QUARTERS      GR2A(KC_6)  // ¾
 | ||||
| #define CSA_3QRT                CSA_THREE_QUARTERS | ||||
| #define CSA_SUPERSCRIPT_ONE GR2A(KC_1)  // ¹
 | ||||
| #define CSA_SUP1 CSA_SUPERSCRIPT_ONE | ||||
| #define CSA_SUPERSCRIPT_TWO GR2A(KC_2)  // ²
 | ||||
| #define CSA_SUP2 CSA_SUPERSCRIPT_TWO | ||||
| #define CSA_SUPERSCRIPT_THREE GR2A(KC_3)  // ³
 | ||||
| #define CSA_SUP3 CSA_SUPERSCRIPT_THREE | ||||
| #define CSA_ONE_QUARTER GR2A(KC_4)  // ¼
 | ||||
| #define CSA_1QRT CSA_ONE_QUARTER | ||||
| #define CSA_ONE_HALF GR2A(KC_5)  // ½
 | ||||
| #define CSA_1HLF CSA_ONE_HALF | ||||
| #define CSA_THREE_QUARTERS GR2A(KC_6)  // ¾
 | ||||
| #define CSA_3QRT CSA_THREE_QUARTERS | ||||
| // nothing on 7-0 and -
 | ||||
| #define CSA_DEAD_CEDILLA        GR2A(KC_EQUAL)  // dead ¸
 | ||||
| #define CSA_DCED                CSA_DEAD_CEDILLA | ||||
| #define CSA_DEAD_CEDILLA GR2A(KC_EQUAL)  // dead ¸
 | ||||
| #define CSA_DCED CSA_DEAD_CEDILLA | ||||
| 
 | ||||
| // Second row
 | ||||
| #define CSA_OMEGA           GR2A(KC_Q)  // ω
 | ||||
| #define CSA_OMEG            CSA_OMEGA | ||||
| #define CSA_L_STROKE        GR2A(KC_W)  // ł
 | ||||
| #define CSA_LSTK            CSA_L_STROKE | ||||
| #define CSA_OE_LIGATURE     GR2A(KC_E)  // œ
 | ||||
| #define CSA_OE              CSA_OE_LIGATURE | ||||
| #define CSA_PARAGRAPH       GR2A(KC_R)  // ¶
 | ||||
| #define CSA_PARG            CSA_PARAGRAPH | ||||
| #define CSA_T_STROKE        GR2A(KC_T)  // ŧ
 | ||||
| #define CSA_LEFT_ARROW      GR2A(KC_Y)  // ←
 | ||||
| #define CSA_LARW            CSA_LEFT_ARROW | ||||
| #define CSA_DOWN_ARROW      GR2A(KC_U)  // ↓
 | ||||
| #define CSA_DARW            CSA_DOWN_ARROW | ||||
| #define CSA_RIGHT_ARROW     GR2A(KC_I)  // →
 | ||||
| #define CSA_RARW            CSA_RIGHT_ARROW | ||||
| #define CSA_O_STROKE        GR2A(KC_O)  // ø
 | ||||
| #define CSA_OSTK            CSA_O_STROKE | ||||
| #define CSA_THORN           GR2A(KC_P)  // þ
 | ||||
| #define CSA_THRN            CSA_THORN | ||||
| #define CSA_OMEGA GR2A(KC_Q)  // ω
 | ||||
| #define CSA_OMEG CSA_OMEGA | ||||
| #define CSA_L_STROKE GR2A(KC_W)  // ł
 | ||||
| #define CSA_LSTK CSA_L_STROKE | ||||
| #define CSA_OE_LIGATURE GR2A(KC_E)  // œ
 | ||||
| #define CSA_OE CSA_OE_LIGATURE | ||||
| #define CSA_PARAGRAPH GR2A(KC_R)  // ¶
 | ||||
| #define CSA_PARG CSA_PARAGRAPH | ||||
| #define CSA_T_STROKE GR2A(KC_T)    // ŧ
 | ||||
| #define CSA_LEFT_ARROW GR2A(KC_Y)  // ←
 | ||||
| #define CSA_LARW CSA_LEFT_ARROW | ||||
| #define CSA_DOWN_ARROW GR2A(KC_U)  // ↓
 | ||||
| #define CSA_DARW CSA_DOWN_ARROW | ||||
| #define CSA_RIGHT_ARROW GR2A(KC_I)  // →
 | ||||
| #define CSA_RARW CSA_RIGHT_ARROW | ||||
| #define CSA_O_STROKE GR2A(KC_O)  // ø
 | ||||
| #define CSA_OSTK CSA_O_STROKE | ||||
| #define CSA_THORN GR2A(KC_P)  // þ
 | ||||
| #define CSA_THRN CSA_THORN | ||||
| // nothing on ^
 | ||||
| #define CSA_TILDE           GR2A(CSA_C_CEDILLA)  // dead ~
 | ||||
| #define CSA_TILD            CSA_TILDE | ||||
| #define CSA_TILDE GR2A(CSA_C_CEDILLA)  // dead ~
 | ||||
| #define CSA_TILD CSA_TILDE | ||||
| 
 | ||||
| // Third row
 | ||||
| #define CSA_AE_LIGATURE     GR2A(KC_A)      // æ
 | ||||
| #define CSA_AE              CSA_AE_LIGATURE | ||||
| #define CSA_SHARP_S         GR2A(KC_S)      // ß
 | ||||
| #define CSA_SRPS            CSA_SHARP_S | ||||
| #define CSA_ETH             GR2A(KC_D)      // ð
 | ||||
| #define CSA_AE_LIGATURE GR2A(KC_A)  // æ
 | ||||
| #define CSA_AE CSA_AE_LIGATURE | ||||
| #define CSA_SHARP_S GR2A(KC_S)  // ß
 | ||||
| #define CSA_SRPS CSA_SHARP_S | ||||
| #define CSA_ETH GR2A(KC_D)  // ð
 | ||||
| // nothing on F
 | ||||
| #define CSA_ENG             GR2A(KC_G)      // ŋ
 | ||||
| #define CSA_H_SRTOKE        GR2A(KC_H)      // ħ
 | ||||
| #define CSA_HSTK            CSA_H_SRTOKE | ||||
| #define CSA_IJ_LIGATURE     GR2A(KC_J)      // ij
 | ||||
| #define CSA_IJ              CSA_IJ_LIGATURE | ||||
| #define CSA_KRA             GR2A(KC_K)      // ĸ
 | ||||
| #define CSA_L_FLOWN_DOT     GR2A(KC_L)      // ŀ
 | ||||
| #define CSA_LFLD            CSA_L_FLOWN_DOT | ||||
| #define CSA_DEAD_ACUTE      GR2A(KC_SCLN)   // dead acute accent
 | ||||
| #define CSA_DACT            CSA_DEAD_ACUTE | ||||
| #define CSA_ENG GR2A(KC_G)       // ŋ
 | ||||
| #define CSA_H_SRTOKE GR2A(KC_H)  // ħ
 | ||||
| #define CSA_HSTK CSA_H_SRTOKE | ||||
| #define CSA_IJ_LIGATURE GR2A(KC_J)  // ij
 | ||||
| #define CSA_IJ CSA_IJ_LIGATURE | ||||
| #define CSA_KRA GR2A(KC_K)          // ĸ
 | ||||
| #define CSA_L_FLOWN_DOT GR2A(KC_L)  // ŀ
 | ||||
| #define CSA_LFLD CSA_L_FLOWN_DOT | ||||
| #define CSA_DEAD_ACUTE GR2A(KC_SCLN)  // dead acute accent
 | ||||
| #define CSA_DACT CSA_DEAD_ACUTE | ||||
| // nothing on È & À
 | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define CSA_CENT                GR2A(KC_C)  // ¢
 | ||||
| #define CSA_LEFT_DOUBLE_QUOTE   GR2A(KC_V)  // “
 | ||||
| #define CSA_LDQT                CSA_LEFT_DOUBLE_QUOTE | ||||
| #define CSA_RIGHT_DOUBLE_QUOTE  GR2A(KC_B)  // ”
 | ||||
| #define CSA_RDQT                CSA_RIGHT_DOUBLE_QUOTE | ||||
| #define CSA_N_APOSTROPHE        GR2A(KC_N)  // ʼn (deprecated unicode codepoint)
 | ||||
| #define CSA_NAPO                CSA_N_APOSTROPHE | ||||
| #define CSA_MU                  GR2A(KC_M)  // μ
 | ||||
| #define CSA_HORIZONTAL_BAR      GR2A(KC_COMMA)  // ―
 | ||||
| #define CSA_HZBR                CSA_HORIZONTAL_BAR | ||||
| #define CSA_DEAD_DOT_ABOVE      GR2A(KC_DOT)    // dead ˙
 | ||||
| #define CSA_DDTA                CSA_DEAD_DOT_ABOVE | ||||
| #define CSA_CENT GR2A(KC_C)               // ¢
 | ||||
| #define CSA_LEFT_DOUBLE_QUOTE GR2A(KC_V)  // “
 | ||||
| #define CSA_LDQT CSA_LEFT_DOUBLE_QUOTE | ||||
| #define CSA_RIGHT_DOUBLE_QUOTE GR2A(KC_B)  // ”
 | ||||
| #define CSA_RDQT CSA_RIGHT_DOUBLE_QUOTE | ||||
| #define CSA_N_APOSTROPHE GR2A(KC_N)  // ʼn (deprecated unicode codepoint)
 | ||||
| #define CSA_NAPO CSA_N_APOSTROPHE | ||||
| #define CSA_MU GR2A(KC_M)                  // μ
 | ||||
| #define CSA_HORIZONTAL_BAR GR2A(KC_COMMA)  // ―
 | ||||
| #define CSA_HZBR CSA_HORIZONTAL_BAR | ||||
| #define CSA_DEAD_DOT_ABOVE GR2A(KC_DOT)  // dead ˙
 | ||||
| #define CSA_DDTA CSA_DEAD_DOT_ABOVE | ||||
| 
 | ||||
| // GR2A-shifted characters (different from capitalised GR2A-ed characters)
 | ||||
| // First row
 | ||||
| #define CSA_SOFT_HYPHEN         GR2A(LSFT(CSA_SLASH))   // soft-hyphen, appears as a hyphen in wrapped word
 | ||||
| #define CSA_SHYP                CSA_SOFT_HYPHEN | ||||
| #define CSA_INVERTED_EXCLAIM    GR2A(KC_EXCLAIM)    // ¡
 | ||||
| #define CSA_IXLM                CSA_INVERTED_EXCLAIM | ||||
| #define CSA_SOFT_HYPHEN GR2A(LSFT(CSA_SLASH))  // soft-hyphen, appears as a hyphen in wrapped word
 | ||||
| #define CSA_SHYP CSA_SOFT_HYPHEN | ||||
| #define CSA_INVERTED_EXCLAIM GR2A(KC_EXCLAIM)  // ¡
 | ||||
| #define CSA_IXLM CSA_INVERTED_EXCLAIM | ||||
| // nothing on 2
 | ||||
| #define CSA_POUND               GR2A(LSFT(KC_3))    // £
 | ||||
| #define CSA_GBP                 CSA_POUND_SIGN | ||||
| #define CSA_POUND GR2A(LSFT(KC_3))  // £
 | ||||
| #define CSA_GBP CSA_POUND_SIGN | ||||
| // already on ALGR(KC_E)
 | ||||
| #define CSA_EURO_BIS            GR2A(LSFT(KC_4))    // €
 | ||||
| #define CSA_EURB                CSA_EURO_BIS | ||||
| #define CSA_THREE_EIGHTHS       GR2A(LSFT(KC_5))    // ⅜
 | ||||
| #define CSA_3ON8                CSA_THREE_EIGHTHS | ||||
| #define CSA_FIVE_EIGHTHS        GR2A(LSFT(KC_6))    // ⅝
 | ||||
| #define CSA_5ON8                CSA_FIVE_EIGHTHS | ||||
| #define CSA_SEVEN_EIGHTHS       GR2A(LSFT(KC_7))    // ⅞
 | ||||
| #define CSA_7ON8                CSA_SEVEN_EIGHTHS | ||||
| #define CSA_TRADEMARK           GR2A(LSFT(KC_8))    // ™
 | ||||
| #define CSA_TM                  CSA_TRADEMARK | ||||
| #define CSA_PLUS_MINUS          GR2A(LSFT(KC_9))    // ±
 | ||||
| #define CSA_PSMS                CSA_PLUS_MINUS | ||||
| #define CSA_EURO_BIS GR2A(LSFT(KC_4))  // €
 | ||||
| #define CSA_EURB CSA_EURO_BIS | ||||
| #define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5))  // ⅜
 | ||||
| #define CSA_3ON8 CSA_THREE_EIGHTHS | ||||
| #define CSA_FIVE_EIGHTHS GR2A(LSFT(KC_6))  // ⅝
 | ||||
| #define CSA_5ON8 CSA_FIVE_EIGHTHS | ||||
| #define CSA_SEVEN_EIGHTHS GR2A(LSFT(KC_7))  // ⅞
 | ||||
| #define CSA_7ON8 CSA_SEVEN_EIGHTHS | ||||
| #define CSA_TRADEMARK GR2A(LSFT(KC_8))  // ™
 | ||||
| #define CSA_TM CSA_TRADEMARK | ||||
| #define CSA_PLUS_MINUS GR2A(LSFT(KC_9))  // ±
 | ||||
| #define CSA_PSMS CSA_PLUS_MINUS | ||||
| // nothing on 0
 | ||||
| #define CSA_INVERTED_QUESTION   GR2A(LSFT(KC_MINUS))    // ¿
 | ||||
| #define CSA_IQST                CSA_INVERTED_QUESTION | ||||
| #define CSA_DEAD_OGONEK         GR2A(LSFT(KC_EQUAL))    // dead ˛
 | ||||
| #define CSA_DOGO                CSA_DEAD_OGONEK | ||||
| #define CSA_INVERTED_QUESTION GR2A(LSFT(KC_MINUS))  // ¿
 | ||||
| #define CSA_IQST CSA_INVERTED_QUESTION | ||||
| #define CSA_DEAD_OGONEK GR2A(LSFT(KC_EQUAL))  // dead ˛
 | ||||
| #define CSA_DOGO CSA_DEAD_OGONEK | ||||
| 
 | ||||
| // Second row
 | ||||
| #define CSA_REGISTERED_TRADEMARK    GR2A(LSFT(KC_R))        // ®
 | ||||
| #define CSA_RTM                     CSA_REGISTERED_TRADEMARK | ||||
| #define CSA_YEN                     GR2A(LSFT(KC_Y))        // ¥
 | ||||
| #define CSA_YUAN                    CSA_YEN | ||||
| #define CSA_UP_ARROW                LSFT(CSA_DOWN_ARROW)    // ↑
 | ||||
| #define CSA_DOTLESS_I               GR2A(LSFT(KC_I))        // ı
 | ||||
| #define CSA_DLSI                    CSA_DOTLESS_I | ||||
| #define CSA_DEAD_RING               GR2A(LSFT(CSA_DCRC))    // dead °
 | ||||
| #define CSA_DRNG                    CSA_DEAD_RING | ||||
| #define CSA_DEAD_MACRON             GR2A(LSFT(CSA_C_CEDILLA))   // dead ¯
 | ||||
| #define CSA_DMCR                    CSA_DEAD_MACRON | ||||
| #define CSA_REGISTERED_TRADEMARK GR2A(LSFT(KC_R))  // ®
 | ||||
| #define CSA_RTM CSA_REGISTERED_TRADEMARK | ||||
| #define CSA_YEN GR2A(LSFT(KC_Y))  // ¥
 | ||||
| #define CSA_YUAN CSA_YEN | ||||
| #define CSA_UP_ARROW LSFT(CSA_DOWN_ARROW)  // ↑
 | ||||
| #define CSA_DOTLESS_I GR2A(LSFT(KC_I))     // ı
 | ||||
| #define CSA_DLSI CSA_DOTLESS_I | ||||
| #define CSA_DEAD_RING GR2A(LSFT(CSA_DCRC))  // dead °
 | ||||
| #define CSA_DRNG CSA_DEAD_RING | ||||
| #define CSA_DEAD_MACRON GR2A(LSFT(CSA_C_CEDILLA))  // dead ¯
 | ||||
| #define CSA_DMCR CSA_DEAD_MACRON | ||||
| 
 | ||||
| // Third row
 | ||||
| #define CSA_SECTION                 GR2A(LSFT(KC_S))        // §
 | ||||
| #define CSA_SECT                    CSA_SECTION | ||||
| #define CSA_ORDINAL_INDICATOR_A     GR2A(LSFT(KC_F))        // ª
 | ||||
| #define CSA_ORDA                    CSA_ORDINAL_INDICATOR_A | ||||
| #define CSA_DEAD_DOUBLE_ACUTE       LSFT(CSA_DEAD_ACUTE)    // ˝
 | ||||
| #define CSA_DDCT                    CSA_DEAD_DOUBLE_ACUTE | ||||
| #define CSA_DEAD_CARON              GR2A(LSFT(CSA_E_GRAVE)) // dead ˇ
 | ||||
| #define CSA_DCAR                    CSA_DEAD_CARON | ||||
| #define CSA_DEAD_BREVE              GR2A(LSFT(CSA_A_GRAVE)) // dead ˘
 | ||||
| #define CSA_DBRV                    CSA_DEAD_BREVE | ||||
| #define CSA_SECTION GR2A(LSFT(KC_S))  // §
 | ||||
| #define CSA_SECT CSA_SECTION | ||||
| #define CSA_ORDINAL_INDICATOR_A GR2A(LSFT(KC_F))  // ª
 | ||||
| #define CSA_ORDA CSA_ORDINAL_INDICATOR_A | ||||
| #define CSA_DEAD_DOUBLE_ACUTE LSFT(CSA_DEAD_ACUTE)  // ˝
 | ||||
| #define CSA_DDCT CSA_DEAD_DOUBLE_ACUTE | ||||
| #define CSA_DEAD_CARON GR2A(LSFT(CSA_E_GRAVE))  // dead ˇ
 | ||||
| #define CSA_DCAR CSA_DEAD_CARON | ||||
| #define CSA_DEAD_BREVE GR2A(LSFT(CSA_A_GRAVE))  // dead ˘
 | ||||
| #define CSA_DBRV CSA_DEAD_BREVE | ||||
| 
 | ||||
| // Fourth row
 | ||||
| #define CSA_BROKEN_PIPE         GR2A(LSFT(CSA_U_GRAVE)) // ¦
 | ||||
| #define CSA_BPIP                CSA_BROKEN_PIPE | ||||
| #define CSA_COPYRIGHT           GR2A(LSFT(KC_C))        // ©
 | ||||
| #define CSA_CPRT                CSA_COPYRIGHT | ||||
| #define CSA_LEFT_QUOTE          GR2A(LSFT(KC_V))        // ‘
 | ||||
| #define CSA_LQOT                CSA_LEFT_QUOTE | ||||
| #define CSA_RIGHT_QUOTE         GR2A(LSFT(KC_B))        // ’
 | ||||
| #define CSA_RQOT                CSA_RIGHT_QUOTE | ||||
| #define CSA_EIGHTH_NOTE         GR2A(LSFT(KC_N))        // ♪
 | ||||
| #define CSA_8NOT                CSA_EIGHTH_NOTE | ||||
| #define CSA_ORDINAL_INDICATOR_O GR2A(LSFT(KC_M))        // º
 | ||||
| #define CSA_ORDO                CSA_ORDINAL_INDICATOR_O | ||||
| #define CSA_TIMES               GR2A(LSFT(KC_COMMA))    // ×
 | ||||
| #define CSA_TIMS                CSA_TIMES | ||||
| #define CSA_OBELUS              GR2A(LSFT(KC_DOT))      // ÷
 | ||||
| #define CSA_OBEL                CSA_OBELUS | ||||
| #define CSA_BROKEN_PIPE GR2A(LSFT(CSA_U_GRAVE))  // ¦
 | ||||
| #define CSA_BPIP CSA_BROKEN_PIPE | ||||
| #define CSA_COPYRIGHT GR2A(LSFT(KC_C))  // ©
 | ||||
| #define CSA_CPRT CSA_COPYRIGHT | ||||
| #define CSA_LEFT_QUOTE GR2A(LSFT(KC_V))  // ‘
 | ||||
| #define CSA_LQOT CSA_LEFT_QUOTE | ||||
| #define CSA_RIGHT_QUOTE GR2A(LSFT(KC_B))  // ’
 | ||||
| #define CSA_RQOT CSA_RIGHT_QUOTE | ||||
| #define CSA_EIGHTH_NOTE GR2A(LSFT(KC_N))  // ♪
 | ||||
| #define CSA_8NOT CSA_EIGHTH_NOTE | ||||
| #define CSA_ORDINAL_INDICATOR_O GR2A(LSFT(KC_M))  // º
 | ||||
| #define CSA_ORDO CSA_ORDINAL_INDICATOR_O | ||||
| #define CSA_TIMES GR2A(LSFT(KC_COMMA))  // ×
 | ||||
| #define CSA_TIMS CSA_TIMES | ||||
| #define CSA_OBELUS GR2A(LSFT(KC_DOT))  // ÷
 | ||||
| #define CSA_OBEL CSA_OBELUS | ||||
| // more conventional name of the symbol
 | ||||
| #define CSA_DIVISION_SIGN       CSA_OBELUS | ||||
| #define CSA_DVSN                CSA_DIVISION_SIGN | ||||
| #define CSA_DIVISION_SIGN CSA_OBELUS | ||||
| #define CSA_DVSN CSA_DIVISION_SIGN | ||||
| // TODO GR2A(LSFT(CSA_E_ACUTE))
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -18,73 +18,73 @@ | |||
| 
 | ||||
| #include "keymap.h" | ||||
| // For software implementation of colemak
 | ||||
| #define CM_Q    KC_Q | ||||
| #define CM_W    KC_W | ||||
| #define CM_F    KC_E | ||||
| #define CM_P    KC_R | ||||
| #define CM_G    KC_T | ||||
| #define CM_J    KC_Y | ||||
| #define CM_L    KC_U | ||||
| #define CM_U    KC_I | ||||
| #define CM_Y    KC_O | ||||
| #define CM_Q KC_Q | ||||
| #define CM_W KC_W | ||||
| #define CM_F KC_E | ||||
| #define CM_P KC_R | ||||
| #define CM_G KC_T | ||||
| #define CM_J KC_Y | ||||
| #define CM_L KC_U | ||||
| #define CM_U KC_I | ||||
| #define CM_Y KC_O | ||||
| #define CM_SCLN KC_P | ||||
| 
 | ||||
| #define CM_A    KC_A | ||||
| #define CM_R    KC_S | ||||
| #define CM_S    KC_D | ||||
| #define CM_T    KC_F | ||||
| #define CM_D    KC_G | ||||
| #define CM_H    KC_H | ||||
| #define CM_N    KC_J | ||||
| #define CM_E    KC_K | ||||
| #define CM_I    KC_L | ||||
| #define CM_O    KC_SCLN | ||||
| #define CM_A KC_A | ||||
| #define CM_R KC_S | ||||
| #define CM_S KC_D | ||||
| #define CM_T KC_F | ||||
| #define CM_D KC_G | ||||
| #define CM_H KC_H | ||||
| #define CM_N KC_J | ||||
| #define CM_E KC_K | ||||
| #define CM_I KC_L | ||||
| #define CM_O KC_SCLN | ||||
| #define CM_COLN LSFT(CM_SCLN) | ||||
| 
 | ||||
| #define CM_Z    KC_Z | ||||
| #define CM_X    KC_X | ||||
| #define CM_C    KC_C | ||||
| #define CM_V    KC_V | ||||
| #define CM_B    KC_B | ||||
| #define CM_K    KC_N | ||||
| #define CM_M    KC_M | ||||
| #define CM_Z KC_Z | ||||
| #define CM_X KC_X | ||||
| #define CM_C KC_C | ||||
| #define CM_V KC_V | ||||
| #define CM_B KC_B | ||||
| #define CM_K KC_N | ||||
| #define CM_M KC_M | ||||
| #define CM_COMM KC_COMM | ||||
| #define CM_DOT  KC_DOT | ||||
| #define CM_DOT KC_DOT | ||||
| #define CM_SLSH KC_SLSH | ||||
| 
 | ||||
| // Make it easy to support these in macros
 | ||||
| // TODO: change macro implementation so these aren't needed
 | ||||
| #define KC_CM_Q    CM_Q | ||||
| #define KC_CM_W    CM_W | ||||
| #define KC_CM_F    CM_F | ||||
| #define KC_CM_P    CM_P | ||||
| #define KC_CM_G    CM_G | ||||
| #define KC_CM_J    CM_J | ||||
| #define KC_CM_L    CM_L | ||||
| #define KC_CM_U    CM_U | ||||
| #define KC_CM_Y    CM_Y | ||||
| #define KC_CM_Q CM_Q | ||||
| #define KC_CM_W CM_W | ||||
| #define KC_CM_F CM_F | ||||
| #define KC_CM_P CM_P | ||||
| #define KC_CM_G CM_G | ||||
| #define KC_CM_J CM_J | ||||
| #define KC_CM_L CM_L | ||||
| #define KC_CM_U CM_U | ||||
| #define KC_CM_Y CM_Y | ||||
| #define KC_CM_SCLN CM_SCLN | ||||
| 
 | ||||
| #define KC_CM_A    CM_A | ||||
| #define KC_CM_R    CM_R | ||||
| #define KC_CM_S    CM_S | ||||
| #define KC_CM_T    CM_T | ||||
| #define KC_CM_D    CM_D | ||||
| #define KC_CM_H    CM_H | ||||
| #define KC_CM_N    CM_N | ||||
| #define KC_CM_E    CM_E | ||||
| #define KC_CM_I    CM_I | ||||
| #define KC_CM_O    CM_O | ||||
| #define KC_CM_A CM_A | ||||
| #define KC_CM_R CM_R | ||||
| #define KC_CM_S CM_S | ||||
| #define KC_CM_T CM_T | ||||
| #define KC_CM_D CM_D | ||||
| #define KC_CM_H CM_H | ||||
| #define KC_CM_N CM_N | ||||
| #define KC_CM_E CM_E | ||||
| #define KC_CM_I CM_I | ||||
| #define KC_CM_O CM_O | ||||
| 
 | ||||
| #define KC_CM_Z    CM_Z | ||||
| #define KC_CM_X    CM_X | ||||
| #define KC_CM_C    CM_C | ||||
| #define KC_CM_V    CM_V | ||||
| #define KC_CM_B    CM_B | ||||
| #define KC_CM_K    CM_K | ||||
| #define KC_CM_M    CM_M | ||||
| #define KC_CM_Z CM_Z | ||||
| #define KC_CM_X CM_X | ||||
| #define KC_CM_C CM_C | ||||
| #define KC_CM_V CM_V | ||||
| #define KC_CM_B CM_B | ||||
| #define KC_CM_K CM_K | ||||
| #define KC_CM_M CM_M | ||||
| #define KC_CM_COMM CM_COMM | ||||
| #define KC_CM_DOT  CM_DOT | ||||
| #define KC_CM_DOT CM_DOT | ||||
| #define KC_CM_SLSH CM_SLSH | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -19,82 +19,82 @@ | |||
| #include "keymap.h" | ||||
| 
 | ||||
| // Normal characters
 | ||||
| #define DV_GRV	KC_GRV | ||||
| #define DV_1	KC_1 | ||||
| #define DV_2	KC_2 | ||||
| #define DV_3	KC_3 | ||||
| #define DV_4	KC_4 | ||||
| #define DV_5	KC_5 | ||||
| #define DV_6	KC_6 | ||||
| #define DV_7	KC_7 | ||||
| #define DV_8	KC_8 | ||||
| #define DV_9	KC_9 | ||||
| #define DV_0	KC_0 | ||||
| #define DV_LBRC	KC_MINS | ||||
| #define DV_RBRC	KC_EQL | ||||
| #define DV_GRV KC_GRV | ||||
| #define DV_1 KC_1 | ||||
| #define DV_2 KC_2 | ||||
| #define DV_3 KC_3 | ||||
| #define DV_4 KC_4 | ||||
| #define DV_5 KC_5 | ||||
| #define DV_6 KC_6 | ||||
| #define DV_7 KC_7 | ||||
| #define DV_8 KC_8 | ||||
| #define DV_9 KC_9 | ||||
| #define DV_0 KC_0 | ||||
| #define DV_LBRC KC_MINS | ||||
| #define DV_RBRC KC_EQL | ||||
| 
 | ||||
| #define DV_QUOT	KC_Q | ||||
| #define DV_COMM	KC_W | ||||
| #define DV_DOT	KC_E | ||||
| #define DV_P	KC_R | ||||
| #define DV_Y	KC_T | ||||
| #define	DV_F	KC_Y | ||||
| #define DV_G	KC_U | ||||
| #define DV_C	KC_I | ||||
| #define	DV_R	KC_O | ||||
| #define DV_L	KC_P | ||||
| #define DV_SLSH	KC_LBRC | ||||
| #define DV_EQL	KC_RBRC | ||||
| #define DV_BSLS	KC_BSLS | ||||
| #define DV_QUOT KC_Q | ||||
| #define DV_COMM KC_W | ||||
| #define DV_DOT KC_E | ||||
| #define DV_P KC_R | ||||
| #define DV_Y KC_T | ||||
| #define DV_F KC_Y | ||||
| #define DV_G KC_U | ||||
| #define DV_C KC_I | ||||
| #define DV_R KC_O | ||||
| #define DV_L KC_P | ||||
| #define DV_SLSH KC_LBRC | ||||
| #define DV_EQL KC_RBRC | ||||
| #define DV_BSLS KC_BSLS | ||||
| 
 | ||||
| #define DV_A	KC_A | ||||
| #define DV_O	KC_S | ||||
| #define DV_E	KC_D | ||||
| #define DV_U	KC_F | ||||
| #define DV_I	KC_G | ||||
| #define DV_D	KC_H | ||||
| #define DV_H	KC_J | ||||
| #define DV_T	KC_K | ||||
| #define DV_N	KC_L | ||||
| #define DV_S	KC_SCLN | ||||
| #define DV_MINS	KC_QUOT | ||||
| #define DV_A KC_A | ||||
| #define DV_O KC_S | ||||
| #define DV_E KC_D | ||||
| #define DV_U KC_F | ||||
| #define DV_I KC_G | ||||
| #define DV_D KC_H | ||||
| #define DV_H KC_J | ||||
| #define DV_T KC_K | ||||
| #define DV_N KC_L | ||||
| #define DV_S KC_SCLN | ||||
| #define DV_MINS KC_QUOT | ||||
| 
 | ||||
| #define DV_SCLN	KC_Z | ||||
| #define DV_Q	KC_X | ||||
| #define DV_J	KC_C | ||||
| #define DV_K	KC_V | ||||
| #define DV_X	KC_B | ||||
| #define DV_B	KC_N | ||||
| #define DV_M	KC_M | ||||
| #define DV_W	KC_COMM | ||||
| #define DV_V	KC_DOT | ||||
| #define DV_Z	KC_SLSH | ||||
| #define DV_SCLN KC_Z | ||||
| #define DV_Q KC_X | ||||
| #define DV_J KC_C | ||||
| #define DV_K KC_V | ||||
| #define DV_X KC_B | ||||
| #define DV_B KC_N | ||||
| #define DV_M KC_M | ||||
| #define DV_W KC_COMM | ||||
| #define DV_V KC_DOT | ||||
| #define DV_Z KC_SLSH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| #define DV_TILD	LSFT(DV_GRV) | ||||
| #define DV_EXLM	LSFT(DV_1) | ||||
| #define DV_AT	LSFT(DV_2) | ||||
| #define DV_HASH	LSFT(DV_3) | ||||
| #define DV_DLR	LSFT(DV_4) | ||||
| #define DV_PERC	LSFT(DV_5) | ||||
| #define DV_CIRC	LSFT(DV_6) | ||||
| #define DV_AMPR	LSFT(DV_7) | ||||
| #define DV_ASTR	LSFT(DV_8) | ||||
| #define DV_LPRN	LSFT(DV_9) | ||||
| #define DV_RPRN	LSFT(DV_0) | ||||
| #define DV_LCBR	LSFT(DV_LBRC) | ||||
| #define DV_RCBR	LSFT(DV_RBRC) | ||||
| #define DV_TILD LSFT(DV_GRV) | ||||
| #define DV_EXLM LSFT(DV_1) | ||||
| #define DV_AT LSFT(DV_2) | ||||
| #define DV_HASH LSFT(DV_3) | ||||
| #define DV_DLR LSFT(DV_4) | ||||
| #define DV_PERC LSFT(DV_5) | ||||
| #define DV_CIRC LSFT(DV_6) | ||||
| #define DV_AMPR LSFT(DV_7) | ||||
| #define DV_ASTR LSFT(DV_8) | ||||
| #define DV_LPRN LSFT(DV_9) | ||||
| #define DV_RPRN LSFT(DV_0) | ||||
| #define DV_LCBR LSFT(DV_LBRC) | ||||
| #define DV_RCBR LSFT(DV_RBRC) | ||||
| 
 | ||||
| #define DV_DQUO	LSFT(DV_QUOT) | ||||
| #define DV_LABK	LSFT(DV_COMM) | ||||
| #define DV_RABK	LSFT(DV_DOT) | ||||
| #define DV_DQUO LSFT(DV_QUOT) | ||||
| #define DV_LABK LSFT(DV_COMM) | ||||
| #define DV_RABK LSFT(DV_DOT) | ||||
| 
 | ||||
| #define DV_QUES	LSFT(DV_SLSH) | ||||
| #define DV_PLUS	LSFT(DV_EQL) | ||||
| #define DV_PIPE	LSFT(DV_BSLS) | ||||
| #define DV_QUES LSFT(DV_SLSH) | ||||
| #define DV_PLUS LSFT(DV_EQL) | ||||
| #define DV_PIPE LSFT(DV_BSLS) | ||||
| 
 | ||||
| #define DV_UNDS	LSFT(DV_MINS) | ||||
| #define DV_UNDS LSFT(DV_MINS) | ||||
| 
 | ||||
| #define DV_COLN	LSFT(DV_SCLN) | ||||
| #define DV_COLN LSFT(DV_SCLN) | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -20,79 +20,79 @@ | |||
| #include "keymap.h" | ||||
| 
 | ||||
| // Normal characters
 | ||||
| #define DP_DLR	KC_GRV | ||||
| #define DP_AMPR	KC_1 | ||||
| #define DP_LBRC	KC_2 | ||||
| #define DP_LCBR	KC_3 | ||||
| #define DP_RCBR	KC_4 | ||||
| #define DP_LPRN	KC_5 | ||||
| #define DP_EQL	KC_6 | ||||
| #define DP_ASTR	KC_7 | ||||
| #define DP_RPRN	KC_8 | ||||
| #define DP_PLUS	KC_9 | ||||
| #define DP_RBRC	KC_0 | ||||
| #define DP_EXLM	KC_MINS | ||||
| #define DP_HASH	KC_EQL | ||||
| #define DP_DLR KC_GRV | ||||
| #define DP_AMPR KC_1 | ||||
| #define DP_LBRC KC_2 | ||||
| #define DP_LCBR KC_3 | ||||
| #define DP_RCBR KC_4 | ||||
| #define DP_LPRN KC_5 | ||||
| #define DP_EQL KC_6 | ||||
| #define DP_ASTR KC_7 | ||||
| #define DP_RPRN KC_8 | ||||
| #define DP_PLUS KC_9 | ||||
| #define DP_RBRC KC_0 | ||||
| #define DP_EXLM KC_MINS | ||||
| #define DP_HASH KC_EQL | ||||
| 
 | ||||
| #define DP_SCLN	KC_Q | ||||
| #define DP_COMM	KC_W | ||||
| #define DP_DOT	KC_E | ||||
| #define DP_P	KC_R | ||||
| #define DP_Y	KC_T | ||||
| #define DP_F	KC_Y | ||||
| #define DP_G	KC_U | ||||
| #define DP_C	KC_I | ||||
| #define DP_R	KC_O | ||||
| #define DP_L	KC_P | ||||
| #define DP_SLSH	KC_LBRC | ||||
| #define DP_AT	KC_RBRC | ||||
| #define DP_BSLS	KC_BSLS | ||||
| #define DP_SCLN KC_Q | ||||
| #define DP_COMM KC_W | ||||
| #define DP_DOT KC_E | ||||
| #define DP_P KC_R | ||||
| #define DP_Y KC_T | ||||
| #define DP_F KC_Y | ||||
| #define DP_G KC_U | ||||
| #define DP_C KC_I | ||||
| #define DP_R KC_O | ||||
| #define DP_L KC_P | ||||
| #define DP_SLSH KC_LBRC | ||||
| #define DP_AT KC_RBRC | ||||
| #define DP_BSLS KC_BSLS | ||||
| 
 | ||||
| #define DP_A	KC_A | ||||
| #define DP_O	KC_S | ||||
| #define DP_E	KC_D | ||||
| #define DP_U	KC_F | ||||
| #define DP_I	KC_G | ||||
| #define DP_D	KC_H | ||||
| #define DP_H	KC_J | ||||
| #define DP_T	KC_K | ||||
| #define DP_N	KC_L | ||||
| #define DP_S	KC_SCLN | ||||
| #define DP_MINS	KC_QUOT | ||||
| #define DP_A KC_A | ||||
| #define DP_O KC_S | ||||
| #define DP_E KC_D | ||||
| #define DP_U KC_F | ||||
| #define DP_I KC_G | ||||
| #define DP_D KC_H | ||||
| #define DP_H KC_J | ||||
| #define DP_T KC_K | ||||
| #define DP_N KC_L | ||||
| #define DP_S KC_SCLN | ||||
| #define DP_MINS KC_QUOT | ||||
| 
 | ||||
| #define DP_QUOT	KC_Z | ||||
| #define DP_Q	KC_X | ||||
| #define DP_J	KC_C | ||||
| #define DP_K	KC_V | ||||
| #define DP_X	KC_B | ||||
| #define DP_B	KC_N | ||||
| #define DP_M	KC_M | ||||
| #define DP_W	KC_COMM | ||||
| #define DP_V	KC_DOT | ||||
| #define DP_Z	KC_SLSH | ||||
| #define DP_QUOT KC_Z | ||||
| #define DP_Q KC_X | ||||
| #define DP_J KC_C | ||||
| #define DP_K KC_V | ||||
| #define DP_X KC_B | ||||
| #define DP_B KC_N | ||||
| #define DP_M KC_M | ||||
| #define DP_W KC_COMM | ||||
| #define DP_V KC_DOT | ||||
| #define DP_Z KC_SLSH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| #define DP_TILD	LSFT(DP_DLR) | ||||
| #define DP_PERC	LSFT(DP_AMPR) | ||||
| #define DP_7	LSFT(DP_LBRC) | ||||
| #define DP_5	LSFT(DP_LCBR) | ||||
| #define DP_3	LSFT(DP_RCBR) | ||||
| #define DP_1	LSFT(DP_LPRN) | ||||
| #define DP_9	LSFT(DP_EQL) | ||||
| #define DP_0	LSFT(DP_ASTR) | ||||
| #define DP_2	LSFT(DP_RPRN) | ||||
| #define DP_4	LSFT(DP_PLUS) | ||||
| #define DP_6	LSFT(DP_RBRC) | ||||
| #define DP_8	LSFT(DP_EXLM) | ||||
| #define DP_GRV	LSFT(DP_HASH) | ||||
| #define DP_TILD LSFT(DP_DLR) | ||||
| #define DP_PERC LSFT(DP_AMPR) | ||||
| #define DP_7 LSFT(DP_LBRC) | ||||
| #define DP_5 LSFT(DP_LCBR) | ||||
| #define DP_3 LSFT(DP_RCBR) | ||||
| #define DP_1 LSFT(DP_LPRN) | ||||
| #define DP_9 LSFT(DP_EQL) | ||||
| #define DP_0 LSFT(DP_ASTR) | ||||
| #define DP_2 LSFT(DP_RPRN) | ||||
| #define DP_4 LSFT(DP_PLUS) | ||||
| #define DP_6 LSFT(DP_RBRC) | ||||
| #define DP_8 LSFT(DP_EXLM) | ||||
| #define DP_GRV LSFT(DP_HASH) | ||||
| 
 | ||||
| #define DP_COLN	LSFT(DP_SCLN) | ||||
| #define DP_LABK	LSFT(DP_COMM) | ||||
| #define DP_RABK	LSFT(DP_DOT) | ||||
| #define DP_QUES	LSFT(DP_SLSH) | ||||
| #define DP_CIRC	LSFT(DP_AT) | ||||
| #define DP_PIPE	LSFT(DP_BSLS) | ||||
| #define DP_UNDS	LSFT(DP_MINS) | ||||
| #define DP_DQUO	LSFT(DP_QUOT) | ||||
| #define DP_COLN LSFT(DP_SCLN) | ||||
| #define DP_LABK LSFT(DP_COMM) | ||||
| #define DP_RABK LSFT(DP_DOT) | ||||
| #define DP_QUES LSFT(DP_SLSH) | ||||
| #define DP_CIRC LSFT(DP_AT) | ||||
| #define DP_PIPE LSFT(DP_BSLS) | ||||
| #define DP_UNDS LSFT(DP_MINS) | ||||
| #define DP_DQUO LSFT(DP_QUOT) | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -66,44 +66,44 @@ | |||
| #define FR_CH_UE KC_LBRC | ||||
| #define FR_CH_OE KC_SCLN | ||||
| 
 | ||||
| #define FR_CH_CIRC KC_EQL // accent circumflex ^ and grave ` and ~
 | ||||
| #define FR_CH_LESS KC_NUBS // < and > and backslash
 | ||||
| #define FR_CH_MINS KC_SLSH // - and _
 | ||||
| #define FR_CH_DLR KC_BSLS // $, £ and }
 | ||||
| #define FR_CH_PARA KC_GRV // § and ring °
 | ||||
| #define FR_CH_DIAE KC_RBRC // accent ¨
 | ||||
| #define FR_CH_CIRC KC_EQL   // accent circumflex ^ and grave ` and ~
 | ||||
| #define FR_CH_LESS KC_NUBS  // < and > and backslash
 | ||||
| #define FR_CH_MINS KC_SLSH  // - and _
 | ||||
| #define FR_CH_DLR KC_BSLS   // $, £ and }
 | ||||
| #define FR_CH_PARA KC_GRV   // § and ring °
 | ||||
| #define FR_CH_DIAE KC_RBRC  // accent ¨
 | ||||
| 
 | ||||
| // shifted characters
 | ||||
| #define FR_CH_RING LSFT(KC_GRV) // °
 | ||||
| #define FR_CH_EXLM LSFT(KC_RBRC) // !
 | ||||
| #define FR_CH_PLUS LSFT(KC_1) // +
 | ||||
| #define FR_CH_DQOT LSFT(KC_2) // "
 | ||||
| #define FR_CH_ASTR LSFT(KC_3) // *
 | ||||
| #define FR_CH_PERC LSFT(KC_5) // %
 | ||||
| #define FR_CH_AMPR LSFT(KC_6) // &
 | ||||
| #define FR_CH_SLSH LSFT(KC_7) // /
 | ||||
| #define FR_CH_LPRN LSFT(KC_8) // (
 | ||||
| #define FR_CH_RPRN LSFT(KC_9) // )
 | ||||
| #define FR_CH_EQL  LSFT(KC_0) // =
 | ||||
| #define FR_CH_QST  LSFT(FR_CH_QUOT) // ?
 | ||||
| #define FR_CH_MORE LSFT(FR_CH_LESS) // >
 | ||||
| #define FR_CH_COLN LSFT(KC_DOT) // :
 | ||||
| #define FR_CH_SCLN LSFT(KC_COMM) // ;
 | ||||
| #define FR_CH_UNDS LSFT(FR_CH_MINS) // _
 | ||||
| #define FR_CH_CCED LSFT(KC_4) // ç
 | ||||
| #define FR_CH_GRV  LSFT(FR_CH_CIRC) // accent grave `
 | ||||
| #define FR_CH_RING LSFT(KC_GRV)      // °
 | ||||
| #define FR_CH_EXLM LSFT(KC_RBRC)     // !
 | ||||
| #define FR_CH_PLUS LSFT(KC_1)        // +
 | ||||
| #define FR_CH_DQOT LSFT(KC_2)        // "
 | ||||
| #define FR_CH_ASTR LSFT(KC_3)        // *
 | ||||
| #define FR_CH_PERC LSFT(KC_5)        // %
 | ||||
| #define FR_CH_AMPR LSFT(KC_6)        // &
 | ||||
| #define FR_CH_SLSH LSFT(KC_7)        // /
 | ||||
| #define FR_CH_LPRN LSFT(KC_8)        // (
 | ||||
| #define FR_CH_RPRN LSFT(KC_9)        // )
 | ||||
| #define FR_CH_EQL LSFT(KC_0)         // =
 | ||||
| #define FR_CH_QST LSFT(FR_CH_QUOT)   // ?
 | ||||
| #define FR_CH_MORE LSFT(FR_CH_LESS)  // >
 | ||||
| #define FR_CH_COLN LSFT(KC_DOT)      // :
 | ||||
| #define FR_CH_SCLN LSFT(KC_COMM)     // ;
 | ||||
| #define FR_CH_UNDS LSFT(FR_CH_MINS)  // _
 | ||||
| #define FR_CH_CCED LSFT(KC_4)        // ç
 | ||||
| #define FR_CH_GRV LSFT(FR_CH_CIRC)   // accent grave `
 | ||||
| 
 | ||||
| // Alt Gr-ed characters
 | ||||
| #define FR_CH_LCBR ALGR(KC_QUOT) // {
 | ||||
| #define FR_CH_LBRC ALGR(KC_LBRC) // [
 | ||||
| #define FR_CH_RBRC ALGR(KC_9) // ]
 | ||||
| #define FR_CH_RCBR ALGR(KC_0) // }
 | ||||
| #define FR_CH_BSLS ALGR(FR_CH_LESS) // backslash
 | ||||
| #define FR_CH_AT   ALGR(KC_2) // @
 | ||||
| #define FR_CH_EURO ALGR(KC_E) // €
 | ||||
| #define FR_CH_TILD ALGR(FR_CH_CIRC) // ~
 | ||||
| #define FR_CH_PIPE ALGR(KC_1) // |
 | ||||
| #define FR_CH_HASH ALGR(KC_3) // #
 | ||||
| #define FR_CH_ACUT ALGR(FR_CH_QUOT) // accent acute ´
 | ||||
| #define FR_CH_LCBR ALGR(KC_QUOT)     // {
 | ||||
| #define FR_CH_LBRC ALGR(KC_LBRC)     // [
 | ||||
| #define FR_CH_RBRC ALGR(KC_9)        // ]
 | ||||
| #define FR_CH_RCBR ALGR(KC_0)        // }
 | ||||
| #define FR_CH_BSLS ALGR(FR_CH_LESS)  // backslash
 | ||||
| #define FR_CH_AT ALGR(KC_2)          // @
 | ||||
| #define FR_CH_EURO ALGR(KC_E)        // €
 | ||||
| #define FR_CH_TILD ALGR(FR_CH_CIRC)  // ~
 | ||||
| #define FR_CH_PIPE ALGR(KC_1)        // |
 | ||||
| #define FR_CH_HASH ALGR(KC_3)        // #
 | ||||
| #define FR_CH_ACUT ALGR(FR_CH_QUOT)  // accent acute ´
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -19,76 +19,76 @@ | |||
| #include "keymap.h" | ||||
| 
 | ||||
| // Normal characters
 | ||||
| #define FR_SUP2	KC_GRV | ||||
| #define FR_AMP	KC_1 | ||||
| #define FR_EACU	KC_2 | ||||
| #define FR_QUOT	KC_3 | ||||
| #define FR_APOS	KC_4 | ||||
| #define FR_LPRN	KC_5 | ||||
| #define FR_MINS	KC_6 | ||||
| #define FR_EGRV	KC_7 | ||||
| #define FR_UNDS	KC_8 | ||||
| #define FR_CCED	KC_9 | ||||
| #define FR_AGRV	KC_0 | ||||
| #define FR_RPRN	KC_MINS | ||||
| #define FR_EQL	KC_EQL | ||||
| #define FR_SUP2 KC_GRV | ||||
| #define FR_AMP KC_1 | ||||
| #define FR_EACU KC_2 | ||||
| #define FR_QUOT KC_3 | ||||
| #define FR_APOS KC_4 | ||||
| #define FR_LPRN KC_5 | ||||
| #define FR_MINS KC_6 | ||||
| #define FR_EGRV KC_7 | ||||
| #define FR_UNDS KC_8 | ||||
| #define FR_CCED KC_9 | ||||
| #define FR_AGRV KC_0 | ||||
| #define FR_RPRN KC_MINS | ||||
| #define FR_EQL KC_EQL | ||||
| 
 | ||||
| #define FR_A 	KC_Q | ||||
| #define FR_Z	KC_W | ||||
| #define	FR_CIRC	KC_LBRC | ||||
| #define FR_DLR	KC_RBRC | ||||
| #define FR_A KC_Q | ||||
| #define FR_Z KC_W | ||||
| #define FR_CIRC KC_LBRC | ||||
| #define FR_DLR KC_RBRC | ||||
| 
 | ||||
| #define FR_Q 	KC_A | ||||
| #define FR_M 	KC_SCLN | ||||
| #define FR_UGRV	KC_QUOT | ||||
| #define FR_ASTR	KC_NUHS | ||||
| #define FR_Q KC_A | ||||
| #define FR_M KC_SCLN | ||||
| #define FR_UGRV KC_QUOT | ||||
| #define FR_ASTR KC_NUHS | ||||
| 
 | ||||
| #define FR_LESS	KC_NUBS | ||||
| #define FR_W	KC_Z | ||||
| #define FR_COMM	KC_M | ||||
| #define FR_SCLN	KC_COMM | ||||
| #define FR_COLN	KC_DOT | ||||
| #define FR_EXLM	KC_SLSH | ||||
| #define FR_LESS KC_NUBS | ||||
| #define FR_W KC_Z | ||||
| #define FR_COMM KC_M | ||||
| #define FR_SCLN KC_COMM | ||||
| #define FR_COLN KC_DOT | ||||
| #define FR_EXLM KC_SLSH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| #define FR_1 	LSFT(KC_1) | ||||
| #define FR_2 	LSFT(KC_2) | ||||
| #define FR_3 	LSFT(KC_3) | ||||
| #define FR_4 	LSFT(KC_4) | ||||
| #define FR_5 	LSFT(KC_5) | ||||
| #define FR_6 	LSFT(KC_6) | ||||
| #define FR_7 	LSFT(KC_7) | ||||
| #define FR_8 	LSFT(KC_8) | ||||
| #define FR_9 	LSFT(KC_9) | ||||
| #define FR_0 	LSFT(KC_0) | ||||
| #define FR_OVRR	LSFT(FR_RPRN) | ||||
| #define FR_1 LSFT(KC_1) | ||||
| #define FR_2 LSFT(KC_2) | ||||
| #define FR_3 LSFT(KC_3) | ||||
| #define FR_4 LSFT(KC_4) | ||||
| #define FR_5 LSFT(KC_5) | ||||
| #define FR_6 LSFT(KC_6) | ||||
| #define FR_7 LSFT(KC_7) | ||||
| #define FR_8 LSFT(KC_8) | ||||
| #define FR_9 LSFT(KC_9) | ||||
| #define FR_0 LSFT(KC_0) | ||||
| #define FR_OVRR LSFT(FR_RPRN) | ||||
| #define FR_PLUS LSFT(FR_EQL) | ||||
| 
 | ||||
| #define FR_UMLT	LSFT(FR_CIRC) | ||||
| #define FR_PND	LSFT(FR_DLR) | ||||
| #define	FR_PERC	LSFT(FR_UGRV) | ||||
| #define FR_MU 	LSFT(FR_ASTR) | ||||
| #define FR_UMLT LSFT(FR_CIRC) | ||||
| #define FR_PND LSFT(FR_DLR) | ||||
| #define FR_PERC LSFT(FR_UGRV) | ||||
| #define FR_MU LSFT(FR_ASTR) | ||||
| 
 | ||||
| #define FR_GRTR	LSFT(FR_LESS) | ||||
| #define FR_QUES	LSFT(FR_COMM) | ||||
| #define FR_DOT	LSFT(FR_SCLN) | ||||
| #define FR_SLSH	LSFT(FR_COLN) | ||||
| #define FR_SECT	LSFT(FR_EXLM) | ||||
| #define FR_GRTR LSFT(FR_LESS) | ||||
| #define FR_QUES LSFT(FR_COMM) | ||||
| #define FR_DOT LSFT(FR_SCLN) | ||||
| #define FR_SLSH LSFT(FR_COLN) | ||||
| #define FR_SECT LSFT(FR_EXLM) | ||||
| 
 | ||||
| // Alt Gr-ed characters
 | ||||
| #define FR_TILD	ALGR(KC_2) | ||||
| #define FR_HASH	ALGR(KC_3) | ||||
| #define FR_TILD ALGR(KC_2) | ||||
| #define FR_HASH ALGR(KC_3) | ||||
| #define FR_LCBR ALGR(KC_4) | ||||
| #define FR_LBRC	ALGR(KC_5) | ||||
| #define FR_LBRC ALGR(KC_5) | ||||
| #define FR_PIPE ALGR(KC_6) | ||||
| #define FR_GRV 	ALGR(KC_7) | ||||
| #define FR_BSLS	ALGR(KC_8) | ||||
| #define FR_CCIRC	ALGR(KC_9) | ||||
| #define FR_AT 	ALGR(KC_0) | ||||
| #define FR_RBRC	ALGR(FR_RPRN) | ||||
| #define FR_GRV ALGR(KC_7) | ||||
| #define FR_BSLS ALGR(KC_8) | ||||
| #define FR_CCIRC ALGR(KC_9) | ||||
| #define FR_AT ALGR(KC_0) | ||||
| #define FR_RBRC ALGR(FR_RPRN) | ||||
| #define FR_RCBR ALGR(FR_EQL) | ||||
| 
 | ||||
| #define FR_EURO	ALGR(KC_E) | ||||
| #define FR_BULT	ALGR(FR_DLR) | ||||
| #define FR_EURO ALGR(KC_E) | ||||
| #define FR_BULT ALGR(FR_DLR) | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -19,74 +19,74 @@ | |||
| #include "keymap.h" | ||||
| 
 | ||||
| // Normal characters
 | ||||
| #define FR_AT 	KC_GRV | ||||
| #define FR_AMP	KC_1 | ||||
| #define FR_EACU	KC_2 | ||||
| #define FR_QUOT	KC_3 | ||||
| #define FR_APOS	KC_4 | ||||
| #define FR_LPRN	KC_5 | ||||
| #define FR_SECT	KC_6 | ||||
| #define FR_EGRV	KC_7 | ||||
| #define FR_EXLM	KC_8 | ||||
| #define FR_CCED	KC_9 | ||||
| #define FR_AGRV	KC_0 | ||||
| #define FR_RPRN	KC_MINS | ||||
| #define FR_MINS	KC_EQL | ||||
| #define FR_AT KC_GRV | ||||
| #define FR_AMP KC_1 | ||||
| #define FR_EACU KC_2 | ||||
| #define FR_QUOT KC_3 | ||||
| #define FR_APOS KC_4 | ||||
| #define FR_LPRN KC_5 | ||||
| #define FR_SECT KC_6 | ||||
| #define FR_EGRV KC_7 | ||||
| #define FR_EXLM KC_8 | ||||
| #define FR_CCED KC_9 | ||||
| #define FR_AGRV KC_0 | ||||
| #define FR_RPRN KC_MINS | ||||
| #define FR_MINS KC_EQL | ||||
| 
 | ||||
| #define FR_A 	KC_Q | ||||
| #define FR_Z	KC_W | ||||
| #define FR_CIRC	KC_LBRC | ||||
| #define FR_DLR	KC_RBRC | ||||
| #define FR_A KC_Q | ||||
| #define FR_Z KC_W | ||||
| #define FR_CIRC KC_LBRC | ||||
| #define FR_DLR KC_RBRC | ||||
| 
 | ||||
| #define FR_Q 	KC_A | ||||
| #define FR_M 	KC_SCLN | ||||
| #define FR_UGRV	KC_QUOT | ||||
| #define FR_GRV	KC_NUHS | ||||
| #define FR_Q KC_A | ||||
| #define FR_M KC_SCLN | ||||
| #define FR_UGRV KC_QUOT | ||||
| #define FR_GRV KC_NUHS | ||||
| 
 | ||||
| #define FR_LESS	KC_NUBS | ||||
| #define FR_W	KC_Z | ||||
| #define FR_COMM	KC_M | ||||
| #define FR_SCLN	KC_COMM | ||||
| #define FR_COLN	KC_DOT | ||||
| #define FR_EQL	KC_SLSH | ||||
| #define FR_LESS KC_NUBS | ||||
| #define FR_W KC_Z | ||||
| #define FR_COMM KC_M | ||||
| #define FR_SCLN KC_COMM | ||||
| #define FR_COLN KC_DOT | ||||
| #define FR_EQL KC_SLSH | ||||
| 
 | ||||
| // Shifted characters
 | ||||
| #define FR_HASH	LSFT(KC_GRV) | ||||
| #define FR_1 	LSFT(KC_1) | ||||
| #define FR_2 	LSFT(KC_2) | ||||
| #define FR_3 	LSFT(KC_3) | ||||
| #define FR_4 	LSFT(KC_4) | ||||
| #define FR_5 	LSFT(KC_5) | ||||
| #define FR_6 	LSFT(KC_6) | ||||
| #define FR_7 	LSFT(KC_7) | ||||
| #define FR_8 	LSFT(KC_8) | ||||
| #define FR_9 	LSFT(KC_9) | ||||
| #define FR_0 	LSFT(KC_0) | ||||
| #define FR_UNDS	LSFT(FR_MINS) | ||||
| #define FR_HASH LSFT(KC_GRV) | ||||
| #define FR_1 LSFT(KC_1) | ||||
| #define FR_2 LSFT(KC_2) | ||||
| #define FR_3 LSFT(KC_3) | ||||
| #define FR_4 LSFT(KC_4) | ||||
| #define FR_5 LSFT(KC_5) | ||||
| #define FR_6 LSFT(KC_6) | ||||
| #define FR_7 LSFT(KC_7) | ||||
| #define FR_8 LSFT(KC_8) | ||||
| #define FR_9 LSFT(KC_9) | ||||
| #define FR_0 LSFT(KC_0) | ||||
| #define FR_UNDS LSFT(FR_MINS) | ||||
| 
 | ||||
| #define FR_UMLT	LSFT(FR_CIRC) | ||||
| #define FR_ASTR	LSFT(FR_DLR) | ||||
| #define FR_UMLT LSFT(FR_CIRC) | ||||
| #define FR_ASTR LSFT(FR_DLR) | ||||
| 
 | ||||
| #define FR_PERC	LSFT(FR_UGRV) | ||||
| #define FR_PND	LSFT(FR_GRV) | ||||
| #define FR_PERC LSFT(FR_UGRV) | ||||
| #define FR_PND LSFT(FR_GRV) | ||||
| 
 | ||||
| #define FR_GRTR	LSFT(FR_LESS) | ||||
| #define FR_QUES	LSFT(FR_COMM) | ||||
| #define FR_DOT	LSFT(FR_SCLN) | ||||
| #define FR_SLSH	LSFT(FR_COLN) | ||||
| #define FR_PLUS	LSFT(FR_EQL) | ||||
| #define FR_GRTR LSFT(FR_LESS) | ||||
| #define FR_QUES LSFT(FR_COMM) | ||||
| #define FR_DOT LSFT(FR_SCLN) | ||||
| #define FR_SLSH LSFT(FR_COLN) | ||||
| #define FR_PLUS LSFT(FR_EQL) | ||||
| 
 | ||||
| // Alted characters
 | ||||
| #define FR_LCBR	LALT(KC_5) | ||||
| #define FR_RCBR	LALT(FR_RPRN) | ||||
| #define FR_EURO	LALT(KC_E) | ||||
| #define FR_BULT	LALT(FR_DLR) | ||||
| #define FR_TILD	LALT(KC_N) | ||||
| #define FR_LCBR LALT(KC_5) | ||||
| #define FR_RCBR LALT(FR_RPRN) | ||||
| #define FR_EURO LALT(KC_E) | ||||
| #define FR_BULT LALT(FR_DLR) | ||||
| #define FR_TILD LALT(KC_N) | ||||
| 
 | ||||
| // Shift+Alt-ed characters
 | ||||
| #define FR_LBRC	LSFT(LALT(KC_5)) | ||||
| #define FR_RBRC	LSFT(LALT(FR_RPRN)) | ||||
| #define FR_PIPE	LSFT(LALT(KC_L)) | ||||
| #define FR_BSLS	LSFT(LALT(FR_COLN)) | ||||
| #define FR_LBRC LSFT(LALT(KC_5)) | ||||
| #define FR_RBRC LSFT(LALT(FR_RPRN)) | ||||
| #define FR_PIPE LSFT(LALT(KC_L)) | ||||
| #define FR_BSLS LSFT(LALT(FR_COLN)) | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -67,45 +67,45 @@ | |||
| #define DE_UE KC_LBRC | ||||
| #define DE_OE KC_SCLN | ||||
| 
 | ||||
| #define DE_CIRC KC_GRAVE // accent circumflex ^ and ring °
 | ||||
| #define DE_ACUT KC_EQL // accent acute ´ and grave `
 | ||||
| #define DE_PLUS KC_RBRC // + and * and ~
 | ||||
| #define DE_HASH KC_BSLS // # and '
 | ||||
| #define DE_LESS KC_NUBS // < and > and |
 | ||||
| #define DE_MINS KC_SLSH // - and _
 | ||||
| #define DE_CIRC KC_GRAVE  // accent circumflex ^ and ring °
 | ||||
| #define DE_ACUT KC_EQL    // accent acute ´ and grave `
 | ||||
| #define DE_PLUS KC_RBRC   // + and * and ~
 | ||||
| #define DE_HASH KC_BSLS   // # and '
 | ||||
| #define DE_LESS KC_NUBS   // < and > and |
 | ||||
| #define DE_MINS KC_SLSH   // - and _
 | ||||
| 
 | ||||
| // shifted characters
 | ||||
| #define DE_RING LSFT(DE_CIRC) // °
 | ||||
| #define DE_EXLM LSFT(KC_1) // !
 | ||||
| #define DE_DQOT LSFT(KC_2) // "
 | ||||
| #define DE_PARA LSFT(KC_3) // §
 | ||||
| #define DE_DLR  LSFT(KC_4) // $
 | ||||
| #define DE_PERC LSFT(KC_5) // %
 | ||||
| #define DE_AMPR LSFT(KC_6) // &
 | ||||
| #define DE_SLSH LSFT(KC_7) // /
 | ||||
| #define DE_LPRN LSFT(KC_8) // (
 | ||||
| #define DE_RPRN LSFT(KC_9) // )
 | ||||
| #define DE_EQL  LSFT(KC_0) // =
 | ||||
| #define DE_QST  LSFT(DE_SS) // ?
 | ||||
| #define DE_GRV  LSFT(DE_ACUT) // `
 | ||||
| #define DE_ASTR LSFT(DE_PLUS) // *
 | ||||
| #define DE_QUOT LSFT(DE_HASH) // '
 | ||||
| #define DE_MORE LSFT(DE_LESS) // >
 | ||||
| #define DE_COLN LSFT(KC_DOT) // :
 | ||||
| #define DE_SCLN LSFT(KC_COMM) // ;
 | ||||
| #define DE_UNDS LSFT(DE_MINS) // _
 | ||||
| #define DE_RING LSFT(DE_CIRC)  // °
 | ||||
| #define DE_EXLM LSFT(KC_1)     // !
 | ||||
| #define DE_DQOT LSFT(KC_2)     // "
 | ||||
| #define DE_PARA LSFT(KC_3)     // §
 | ||||
| #define DE_DLR LSFT(KC_4)      // $
 | ||||
| #define DE_PERC LSFT(KC_5)     // %
 | ||||
| #define DE_AMPR LSFT(KC_6)     // &
 | ||||
| #define DE_SLSH LSFT(KC_7)     // /
 | ||||
| #define DE_LPRN LSFT(KC_8)     // (
 | ||||
| #define DE_RPRN LSFT(KC_9)     // )
 | ||||
| #define DE_EQL LSFT(KC_0)      // =
 | ||||
| #define DE_QST LSFT(DE_SS)     // ?
 | ||||
| #define DE_GRV LSFT(DE_ACUT)   // `
 | ||||
| #define DE_ASTR LSFT(DE_PLUS)  // *
 | ||||
| #define DE_QUOT LSFT(DE_HASH)  // '
 | ||||
| #define DE_MORE LSFT(DE_LESS)  // >
 | ||||
| #define DE_COLN LSFT(KC_DOT)   // :
 | ||||
| #define DE_SCLN LSFT(KC_COMM)  // ;
 | ||||
| #define DE_UNDS LSFT(DE_MINS)  // _
 | ||||
| 
 | ||||
| // Alt Gr-ed characters
 | ||||
| #define DE_SQ2 ALGR(KC_2) // ²
 | ||||
| #define DE_SQ3 ALGR(KC_3) // ³
 | ||||
| #define DE_LCBR ALGR(KC_7) // {
 | ||||
| #define DE_LBRC ALGR(KC_8) // [
 | ||||
| #define DE_RBRC ALGR(KC_9) // ]
 | ||||
| #define DE_RCBR ALGR(KC_0) // }
 | ||||
| #define DE_BSLS ALGR(DE_SS) // backslash
 | ||||
| #define DE_AT  ALGR(KC_Q) // @
 | ||||
| #define DE_EURO ALGR(KC_E) // €
 | ||||
| #define DE_TILD ALGR(DE_PLUS) // ~
 | ||||
| #define DE_PIPE ALGR(DE_LESS) // |
 | ||||
| #define DE_SQ2 ALGR(KC_2)      // ²
 | ||||
| #define DE_SQ3 ALGR(KC_3)      // ³
 | ||||
| #define DE_LCBR ALGR(KC_7)     // {
 | ||||
| #define DE_LBRC ALGR(KC_8)     // [
 | ||||
| #define DE_RBRC ALGR(KC_9)     // ]
 | ||||
| #define DE_RCBR ALGR(KC_0)     // }
 | ||||
| #define DE_BSLS ALGR(DE_SS)    // backslash
 | ||||
| #define DE_AT ALGR(KC_Q)       // @
 | ||||
| #define DE_EURO ALGR(KC_E)     // €
 | ||||
| #define DE_TILD ALGR(DE_PLUS)  // ~
 | ||||
| #define DE_PIPE ALGR(DE_LESS)  // |
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 skullY
						skullY