main.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. u8x8_test
  3. */
  4. #include <stdio.h>
  5. #include "stm32l031xx.h"
  6. #include "delay.h"
  7. #include "u8g2.h"
  8. /*=======================================================================*/
  9. /* external functions */
  10. uint8_t u8x8_gpio_and_delay_stm32l0_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  11. uint8_t u8x8_gpio_and_delay_stm32l0_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  12. uint8_t u8x8_byte_stm32l0_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  13. uint8_t u8x8_byte_stm32l0_dma_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  14. /*=======================================================================*/
  15. /* global variables */
  16. u8g2_t u8g2; // u8g2 object
  17. uint8_t u8g2_x, u8g2_y; // current position on the screen
  18. volatile unsigned long SysTickCount = 0;
  19. void __attribute__ ((interrupt, used)) SysTick_Handler(void)
  20. {
  21. SysTickCount++;
  22. }
  23. void setHSIClock()
  24. {
  25. /* test if the current clock source is something else than HSI */
  26. if ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  27. {
  28. /* enable HSI */
  29. RCC->CR |= RCC_CR_HSION;
  30. /* wait until HSI becomes ready */
  31. while ( (RCC->CR & RCC_CR_HSIRDY) == 0 )
  32. ;
  33. /* enable the HSI "divide by 4" bit */
  34. RCC->CR |= (uint32_t)(RCC_CR_HSIDIVEN);
  35. /* wait until the "divide by 4" flag is enabled */
  36. while((RCC->CR & RCC_CR_HSIDIVF) == 0)
  37. ;
  38. /* then use the HSI clock */
  39. RCC->CFGR = (RCC->CFGR & (uint32_t) (~RCC_CFGR_SW)) | RCC_CFGR_SW_HSI;
  40. /* wait until HSI clock is used */
  41. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  42. ;
  43. }
  44. /* disable PLL */
  45. RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
  46. /* wait until PLL is inactive */
  47. while((RCC->CR & RCC_CR_PLLRDY) != 0)
  48. ;
  49. /* set latency to 1 wait state */
  50. FLASH->ACR |= FLASH_ACR_LATENCY;
  51. /* At this point the HSI runs with 4 MHz */
  52. /* Multiply by 16 device by 2 --> 32 MHz */
  53. RCC->CFGR = (RCC->CFGR & (~(RCC_CFGR_PLLMUL| RCC_CFGR_PLLDIV ))) | (RCC_CFGR_PLLMUL16 | RCC_CFGR_PLLDIV2);
  54. /* enable PLL */
  55. RCC->CR |= RCC_CR_PLLON;
  56. /* wait until the PLL is ready */
  57. while ((RCC->CR & RCC_CR_PLLRDY) == 0)
  58. ;
  59. /* use the PLL has clock source */
  60. RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
  61. /* wait until the PLL source is active */
  62. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
  63. ;
  64. SystemCoreClockUpdate(); /* Update SystemCoreClock global variable */
  65. }
  66. /*
  67. Enable several power regions: PWR, GPIOA
  68. This must be executed after each reset.
  69. */
  70. void startUp(void)
  71. {
  72. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  73. RCC->IOPENR |= RCC_IOPENR_IOPBEN; /* Enable clock for GPIO Port B */
  74. RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* enable power interface (PWR) */
  75. PWR->CR |= PWR_CR_DBP; /* activate write access to RCC->CSR and RTC */
  76. SysTick->LOAD = (SystemCoreClock/1000)*10 - 1; /* 10ms task */
  77. SysTick->VAL = 0;
  78. SysTick->CTRL = 7; /* enable, generate interrupt (SysTick_Handler), do not divide by 2 */
  79. }
  80. /*=======================================================================*/
  81. /* u8x8 display procedures */
  82. /*
  83. uc1609_slg19264_f SW SPI 0.3 FPS BSS 1692
  84. uc1609_slg19264_f HW SPI 4.7 FPS BSS 1692
  85. uc1609_slg19264_f DMA SPI 5.0 FPS BSS 1948
  86. uc1609_slg19264_1 SW SPI 0.3 FPS BSS 348
  87. uc1609_slg19264_1 HW SPI 2.6 FPS BSS 348
  88. uc1609_slg19264_1 DMA SPI 2.6 FPS BSS 604
  89. */
  90. void initDisplay(void)
  91. {
  92. /* setup display */
  93. //u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R2, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0_sw_i2c);
  94. //u8g2_Setup_uc1609_slg19264_f(&u8g2, U8G2_R2, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_stm32l0_spi);
  95. //u8g2_Setup_uc1609_slg19264_f(&u8g2, U8G2_R2, u8x8_byte_stm32l0_hw_spi, u8x8_gpio_and_delay_stm32l0_spi);
  96. u8g2_Setup_uc1609_slg19264_f(&u8g2, U8G2_R2, u8x8_byte_stm32l0_dma_spi, u8x8_gpio_and_delay_stm32l0_spi);
  97. u8g2_InitDisplay(&u8g2);
  98. u8g2_SetPowerSave(&u8g2, 0);
  99. }
  100. void outChar(uint8_t c)
  101. {
  102. u8g2_x+=u8g2_DrawGlyph(&u8g2, u8g2_x, u8g2_y, c);
  103. }
  104. void outStr(const char *s)
  105. {
  106. while( *s )
  107. outChar(*s++);
  108. }
  109. void outHexHalfByte(uint8_t b)
  110. {
  111. b &= 0x0f;
  112. if ( b < 10 )
  113. outChar(b+'0');
  114. else
  115. outChar(b+'a'-10);
  116. }
  117. void outHex8(uint8_t b)
  118. {
  119. outHexHalfByte(b >> 4);
  120. outHexHalfByte(b);
  121. }
  122. void outHex16(uint16_t v)
  123. {
  124. outHex8(v>>8);
  125. outHex8(v);
  126. }
  127. void outHex32(uint32_t v)
  128. {
  129. outHex16(v>>16);
  130. outHex16(v);
  131. }
  132. void setRow(uint8_t r)
  133. {
  134. u8g2_x = 0;
  135. u8g2_y = r;
  136. }
  137. /*=======================================================================*/
  138. int main()
  139. {
  140. uint8_t v = 0;
  141. uint32_t frame_cnt = 0;
  142. uint32_t start, diff, fps, fps_frac;
  143. //setHSIClock(); /* enable 32 MHz Clock */
  144. SystemCoreClockUpdate();
  145. startUp(); /* enable systick irq and several power regions */
  146. initDisplay(); /* aktivate display */
  147. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode */
  148. GPIOA->MODER |= GPIO_MODER_MODE9_0; /* Output mode */
  149. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_9; /* no open drain */
  150. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED9; /* low speed */
  151. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED9_1; /* 10 MHz */
  152. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD9; /* no pullup/pulldown */
  153. GPIOA->BSRR = GPIO_BSRR_BR_9; /* atomic clear */
  154. frame_cnt = 0;
  155. fps = 0;
  156. fps_frac = 0;
  157. start = SysTickCount;
  158. for(;;)
  159. {
  160. diff = SysTickCount - start;
  161. if ( diff > 0 )
  162. {
  163. fps = frame_cnt*1000 / diff; // diff are 10ms ticks
  164. fps_frac = fps % 10;
  165. fps /= 10;
  166. }
  167. GPIOA->BSRR = GPIO_BSRR_BR_9; /* atomic clear */
  168. //u8g2_SetContrast(&u8g2, v);
  169. //u8g2_ClearBuffer(&u8g2);
  170. u8g2_FirstPage(&u8g2);
  171. do
  172. {
  173. u8g2_SetFont(&u8g2, u8g2_font_6x12_tf);
  174. u8g2_DrawStr(&u8g2, 0,12, "STM32L031");
  175. u8g2_DrawStr(&u8g2, 0,24, u8x8_u8toa(SystemCoreClock/1000000, 2));
  176. u8g2_DrawStr(&u8g2, 20,24, "MHz");
  177. u8g2_SetFont(&u8g2, u8g2_font_9x15B_tf);
  178. u8g2_DrawStr(&u8g2, 0,40, u8x8_u8toa(v, 3));
  179. u8g2_DrawStr(&u8g2, 0,60, "FPS:");
  180. u8g2_DrawStr(&u8g2, 35,60, u8x8_u8toa( fps, 3));
  181. u8g2_DrawStr(&u8g2, 35+3*8,60, ".");
  182. u8g2_DrawStr(&u8g2, 35+3*8+6,60, u8x8_u8toa( fps_frac, 1));
  183. } while( u8g2_NextPage(&u8g2));
  184. GPIOA->BSRR = GPIO_BSRR_BS_9; /* atomic clear */
  185. //u8g2_SendBuffer(&u8g2);
  186. v++;
  187. frame_cnt++;
  188. }
  189. return 0;
  190. }