main.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. main.c
  3. AVR Test Project
  4. This project will use 4-Wire SW SPI
  5. Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  6. Copyright (c) 2018, olikraus@gmail.com
  7. All rights reserved.
  8. Redistribution and use in source and binary forms, with or without modification,
  9. are permitted provided that the following conditions are met:
  10. * Redistributions of source code must retain the above copyright notice, this list
  11. of conditions and the following disclaimer.
  12. * Redistributions in binary form must reproduce the above copyright notice, this
  13. list of conditions and the following disclaimer in the documentation and/or other
  14. materials provided with the distribution.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  16. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  17. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  20. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  25. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  27. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #include <avr/io.h>
  30. #include <u8g2.h>
  31. #include <util/delay.h>
  32. #define DISPLAY_CLK_DIR DDRB
  33. #define DISPLAY_CLK_PORT PORTB
  34. #define DISPLAY_CLK_PIN 5
  35. #define DISPLAY_DATA_DIR DDRB
  36. #define DISPLAY_DATA_PORT PORTB
  37. #define DISPLAY_DATA_PIN 3
  38. #define DISPLAY_CS_DIR DDRB
  39. #define DISPLAY_CS_PORT PORTB
  40. #define DISPLAY_CS_PIN 2
  41. #define DISPLAY_DC_DIR DDRB
  42. #define DISPLAY_DC_PORT PORTB
  43. #define DISPLAY_DC_PIN 1
  44. #define DISPLAY_RESET_DIR DDRB
  45. #define DISPLAY_RESET_PORT PORTB
  46. #define DISPLAY_RESET_PIN 0
  47. #define P_CPU_NS (1000000000UL / F_CPU)
  48. u8g2_t u8g2;
  49. uint8_t u8x8_avr_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  50. {
  51. uint8_t cycles;
  52. switch(msg)
  53. {
  54. case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
  55. // At 20Mhz, each cycle is 50ns, the call itself is slower.
  56. break;
  57. case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
  58. // Approximate best case values...
  59. #define CALL_CYCLES 26UL
  60. #define CALC_CYCLES 4UL
  61. #define RETURN_CYCLES 4UL
  62. #define CYCLES_PER_LOOP 4UL
  63. cycles = (100UL * arg_int) / (P_CPU_NS * CYCLES_PER_LOOP);
  64. if(cycles > CALL_CYCLES + RETURN_CYCLES + CALC_CYCLES)
  65. break;
  66. __asm__ __volatile__ (
  67. "1: sbiw %0,1" "\n\t" // 2 cycles
  68. "brne 1b" : "=w" (cycles) : "0" (cycles) // 2 cycles
  69. );
  70. break;
  71. case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
  72. for(int i=0 ; i < arg_int ; i++)
  73. _delay_us(10);
  74. break;
  75. case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
  76. for(int i=0 ; i < arg_int ; i++)
  77. _delay_ms(1);
  78. break;
  79. default:
  80. return 0;
  81. }
  82. return 1;
  83. }
  84. uint8_t u8x8_avr_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  85. {
  86. // Re-use library for delays
  87. switch(msg)
  88. {
  89. case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
  90. DISPLAY_CLK_DIR |= 1<<DISPLAY_CLK_PIN;
  91. DISPLAY_DATA_DIR |= 1<<DISPLAY_DATA_PIN;
  92. DISPLAY_CS_DIR |= 1<<DISPLAY_CS_PIN;
  93. DISPLAY_DC_DIR |= 1<<DISPLAY_DC_PIN;
  94. DISPLAY_RESET_DIR |= 1<<DISPLAY_RESET_PIN;
  95. break; // can be used to setup pins
  96. case U8X8_MSG_GPIO_SPI_CLOCK: // Clock pin: Output level in arg_int
  97. if(arg_int)
  98. DISPLAY_CLK_PORT |= (1<<DISPLAY_CLK_PIN);
  99. else
  100. DISPLAY_CLK_PORT &= ~(1<<DISPLAY_CLK_PIN);
  101. break;
  102. case U8X8_MSG_GPIO_SPI_DATA: // MOSI pin: Output level in arg_int
  103. if(arg_int)
  104. DISPLAY_DATA_PORT |= (1<<DISPLAY_DATA_PIN);
  105. else
  106. DISPLAY_DATA_PORT &= ~(1<<DISPLAY_DATA_PIN);
  107. break;
  108. case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
  109. if(arg_int)
  110. DISPLAY_CS_PORT |= (1<<DISPLAY_CS_PIN);
  111. else
  112. DISPLAY_CS_PORT &= ~(1<<DISPLAY_CS_PIN);
  113. break;
  114. case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
  115. if(arg_int)
  116. DISPLAY_DC_PORT |= (1<<DISPLAY_DC_PIN);
  117. else
  118. DISPLAY_DC_PORT &= ~(1<<DISPLAY_DC_PIN);
  119. break;
  120. case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
  121. if(arg_int)
  122. DISPLAY_RESET_PORT |= (1<<DISPLAY_RESET_PIN);
  123. else
  124. DISPLAY_RESET_PORT &= ~(1<<DISPLAY_RESET_PIN);
  125. break;
  126. default:
  127. if (u8x8_avr_delay(u8x8, msg, arg_int, arg_ptr)) // check for any delay msgs
  128. return 1;
  129. u8x8_SetGPIOResult(u8x8, 1); // default return value
  130. break;
  131. }
  132. return 1;
  133. }
  134. int main(void)
  135. {
  136. /*
  137. Select a setup procedure for your display from here: https://github.com/olikraus/u8g2/wiki/u8g2setupc
  138. 1. Arg: Address of an empty u8g2 structure
  139. 2. Arg: Usually U8G2_R0, others are listed here: https://github.com/olikraus/u8g2/wiki/u8g2reference#carduino-example
  140. 3. Arg: Protocol procedure (u8g2-byte), list is here: https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform#communication-callback-eg-u8x8_byte_hw_i2c
  141. 4. Arg: Defined in this code itself (see above)
  142. */
  143. u8g2_Setup_st7565_ea_dogm132_f( &u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8x8_avr_gpio_and_delay );
  144. u8g2_InitDisplay(&u8g2);
  145. u8g2_SetPowerSave(&u8g2, 0);
  146. /* full buffer example, setup procedure ends in _f */
  147. u8g2_ClearBuffer(&u8g2);
  148. u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
  149. u8g2_DrawStr(&u8g2, 1, 18, "U8g2 on AVR");
  150. u8g2_SendBuffer(&u8g2);
  151. while(1){
  152. }
  153. }