forked from olikraus/u8g2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
149 additions
and
161 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include <u8g2.h> | ||
#include <util/delay.h> | ||
#include <u8x8_avr.h> | ||
|
||
#define P_CPU_NS (1000000000UL / F_CPU) | ||
|
||
u8g2_t u8g2; | ||
|
||
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||
{ | ||
// Re-use library for delays | ||
if(u8x8_avr_delay(u8x8, msg, arg_int, arg_ptr)) | ||
return 1; | ||
|
||
switch(msg){ | ||
case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8 | ||
DDRB |= (1<<0); // CS | ||
DDRB |= (1<<4); // DC | ||
DDRA |= (1<<7); // RESET | ||
break; // can be used to setup pins | ||
case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int | ||
if(arg_int) | ||
PORTB |= (1<<0); | ||
else | ||
PORTB &= ~(1<<0); | ||
break; | ||
case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int | ||
if(arg_int) | ||
PORTB |= (1<<4); | ||
else | ||
PORTB &= ~(1<<4); | ||
break; | ||
case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int | ||
if(arg_int) | ||
PORTA |= (1<<7); | ||
else | ||
PORTA &= ~(1<<7); | ||
break; | ||
default: | ||
u8x8_SetGPIOResult(u8x8, 1); // default return value | ||
break; | ||
} | ||
return 1; | ||
} | ||
|
||
int main(void) | ||
{ | ||
u8g2_Setup_sh1106_128x64_vcomh0_f( | ||
&u8g2, U8G2_R0, | ||
u8x8_byte_avr_hw_spi, | ||
u8x8_gpio_and_delay | ||
); | ||
u8g2_InitDisplay(&u8g2); | ||
u8g2_SetPowerSave(&u8g2, 0); | ||
while(1){ | ||
u8g2_ClearBuffer(&u8g2); | ||
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr); | ||
u8g2_DrawStr(&u8g2, 0, 15, "Hello!"); | ||
u8g2_SendBuffer(&u8g2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#include "u8x8_avr.h" | ||
#include <util/delay.h> | ||
|
||
#define P_CPU_NS (1000000000UL / F_CPU) | ||
|
||
uint8_t u8x8_byte_avr_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { | ||
uint8_t *data; | ||
|
||
switch(msg) { | ||
case U8X8_MSG_BYTE_INIT: | ||
DDRB |= (1 << 1); // CLOCK (SCLK) | ||
DDRB |= (1 << 2); // DATA (MOSI) | ||
SPSR |= (1 << SPI2X); // SPI2X: Double SPI Speed bit | ||
SPCR = ((1 << SPE) | (1 << MSTR)); // Enable / Master | ||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||
break; | ||
case U8X8_MSG_BYTE_SET_DC: | ||
u8x8_gpio_SetDC(u8x8, arg_int); | ||
break; | ||
case U8X8_MSG_BYTE_START_TRANSFER: | ||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level); | ||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); | ||
break; | ||
case U8X8_MSG_BYTE_SEND: | ||
data = (uint8_t *)arg_ptr; | ||
while( arg_int > 0 ) { | ||
SPDR = (uint8_t)*data; | ||
while (!(SPSR & _BV(SPIF))); | ||
data++; | ||
arg_int--; | ||
} | ||
break; | ||
case U8X8_MSG_BYTE_END_TRANSFER: | ||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); | ||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); | ||
break; | ||
default: | ||
return 0; | ||
} | ||
return 1; | ||
} | ||
|
||
uint8_t u8x8_avr_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) | ||
{ | ||
uint8_t cycles; | ||
|
||
switch(msg){ | ||
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second | ||
// At 20Mhz, each cycle is 50ns, the call itself is slower. | ||
break; | ||
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds | ||
// Approximate best case values... | ||
#define CALL_CYCLES 26UL | ||
#define CALC_CYCLES 4UL | ||
#define RETURN_CYCLES 4UL | ||
#define CYCLES_PER_LOOP 4UL | ||
|
||
cycles = (100UL * arg_int) / (P_CPU_NS * CYCLES_PER_LOOP); | ||
|
||
if(cycles > CALL_CYCLES + RETURN_CYCLES + CALC_CYCLES) break; | ||
|
||
__asm__ __volatile__ ( | ||
"1: sbiw %0,1" "\n\t" // 2 cycles | ||
"brne 1b" : "=w" (cycles) : "0" (cycles) // 2 cycles | ||
); | ||
break; | ||
case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds | ||
for(int i=0 ; i < arg_int ; i++) | ||
_delay_us(10); | ||
break; | ||
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second | ||
for(int i=0 ; i < arg_int ; i++) | ||
_delay_ms(1); | ||
break; | ||
default: | ||
return 0; | ||
} | ||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#include <u8g2.h> | ||
#include <stdint.h> | ||
|
||
uint8_t u8x8_byte_avr_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); | ||
uint8_t u8x8_avr_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); |