u8x8cb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. u8x8cb.c
  3. STM32L031
  4. */
  5. #include "stm32l031xx.h"
  6. #include "delay.h"
  7. #include "u8x8.h"
  8. /*
  9. I2C:
  10. PA9: Clock
  11. PA10: Data
  12. */
  13. uint8_t u8x8_gpio_and_delay_stm32l0_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  14. {
  15. switch(msg)
  16. {
  17. case U8X8_MSG_GPIO_AND_DELAY_INIT:
  18. /* only support for software I2C*/
  19. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  20. __NOP();
  21. __NOP();
  22. GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10 */
  23. //GPIOA->MODER |= GPIO_MODER_MODE10_0; /* Output mode for PA10 */
  24. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_10; /* no open drain for PA10 */
  25. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED10; /* low speed for PA10 */
  26. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD10; /* no pullup/pulldown for PA10 */
  27. //GPIOA->BSRR = GPIO_BSRR_BS_10; /* atomic set PA10 */
  28. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA9 */
  29. //GPIOA->MODER |= GPIO_MODER_MODE9_0; /* Output mode for PA9 */
  30. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_9; /* no open drain for PA9 */
  31. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED9; /* low speed for PA9 */
  32. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD9; /* no pullup/pulldown for PA9 */
  33. //GPIOA->BSRR = GPIO_BSRR_BS_9; /* atomic set PA9 */
  34. break;
  35. case U8X8_MSG_DELAY_NANO:
  36. /* not required for SW I2C */
  37. break;
  38. case U8X8_MSG_DELAY_10MICRO:
  39. /* not used at the moment */
  40. break;
  41. case U8X8_MSG_DELAY_100NANO:
  42. /* not used at the moment */
  43. break;
  44. case U8X8_MSG_DELAY_MILLI:
  45. delay_micro_seconds(arg_int*1000UL);
  46. break;
  47. case U8X8_MSG_DELAY_I2C:
  48. /* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
  49. delay_micro_seconds(arg_int<=2?5:1);
  50. break;
  51. case U8X8_MSG_GPIO_I2C_CLOCK:
  52. if ( arg_int == 0 )
  53. {
  54. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA10 */
  55. GPIOA->MODER |= GPIO_MODER_MODE9_0; /* Output mode for PA10 */
  56. GPIOA->BSRR = GPIO_BSRR_BR_9; /* atomic clr PA9 */
  57. }
  58. else
  59. {
  60. //GPIOA->BSRR = GPIO_BSRR_BS_9; /* atomic set PA9 */
  61. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA9: input mode */
  62. }
  63. break;
  64. case U8X8_MSG_GPIO_I2C_DATA:
  65. if ( arg_int == 0 )
  66. {
  67. GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10 */
  68. GPIOA->MODER |= GPIO_MODER_MODE10_0; /* Output mode for PA10 */
  69. GPIOA->BSRR = GPIO_BSRR_BR_10; /* atomic clr PA10 */
  70. }
  71. else
  72. {
  73. //GPIOA->BSRR = GPIO_BSRR_BS_10; /* atomic set PA10 */
  74. // input mode
  75. GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10: input mode */
  76. }
  77. break;
  78. /*
  79. case U8X8_MSG_GPIO_MENU_SELECT:
  80. u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
  81. break;
  82. case U8X8_MSG_GPIO_MENU_NEXT:
  83. u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
  84. break;
  85. case U8X8_MSG_GPIO_MENU_PREV:
  86. u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
  87. break;
  88. case U8X8_MSG_GPIO_MENU_HOME:
  89. u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));
  90. break;
  91. */
  92. default:
  93. u8x8_SetGPIOResult(u8x8, 1);
  94. break;
  95. }
  96. return 1;
  97. }
  98. /*
  99. SPI:
  100. PA14: CD
  101. PA13: CS
  102. PA7: MOSI
  103. PA6: Reset
  104. PA5: SCK
  105. */
  106. uint8_t u8x8_gpio_and_delay_stm32l0_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  107. {
  108. switch(msg)
  109. {
  110. case U8X8_MSG_GPIO_AND_DELAY_INIT:
  111. /* only support for software I2C*/
  112. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  113. __NOP();
  114. __NOP();
  115. /* setup PA14, PA13, PA7, PA6, PA5 */
  116. GPIOA->MODER &= ~GPIO_MODER_MODE14; /* clear mode */
  117. GPIOA->MODER |= GPIO_MODER_MODE14_0; /* Output mode */
  118. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_14; /* no open drain */
  119. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED14; /* low speed */
  120. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED14_1; /* 10 MHz */
  121. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD14; /* no pullup/pulldown */
  122. GPIOA->BSRR = GPIO_BSRR_BR_14; /* atomic clear */
  123. GPIOA->MODER &= ~GPIO_MODER_MODE13; /* clear mode */
  124. GPIOA->MODER |= GPIO_MODER_MODE13_0; /* Output mode */
  125. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_13; /* no open drain */
  126. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED13; /* low speed */
  127. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED13_1; /* 10 MHz */
  128. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD13; /* no pullup/pulldown */
  129. GPIOA->BSRR = GPIO_BSRR_BR_13; /* atomic clear */
  130. GPIOA->MODER &= ~GPIO_MODER_MODE7; /* clear mode */
  131. GPIOA->MODER |= GPIO_MODER_MODE7_0; /* Output mode */
  132. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_7; /* no open drain */
  133. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED7; /* low speed */
  134. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED7_1; /* 10 MHz */
  135. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD7; /* no pullup/pulldown */
  136. GPIOA->BSRR = GPIO_BSRR_BR_7; /* atomic clear */
  137. GPIOA->MODER &= ~GPIO_MODER_MODE6; /* clear mode */
  138. GPIOA->MODER |= GPIO_MODER_MODE6_0; /* Output mode */
  139. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_6; /* no open drain */
  140. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED6; /* low speed */
  141. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED6_1; /* 10 MHz */
  142. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD6; /* no pullup/pulldown */
  143. GPIOA->BSRR = GPIO_BSRR_BR_6; /* atomic clear */
  144. GPIOA->MODER &= ~GPIO_MODER_MODE5; /* clear mode */
  145. GPIOA->MODER |= GPIO_MODER_MODE5_0; /* Output mode */
  146. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5; /* no open drain */
  147. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED5; /* low speed */
  148. GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEED5_1; /* 10 MHz */
  149. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD5; /* no pullup/pulldown */
  150. GPIOA->BSRR = GPIO_BSRR_BR_5; /* atomic clear */
  151. break;
  152. case U8X8_MSG_DELAY_NANO:
  153. /* required for SPI, but seems to work without any delay (at least with 2MHz system clock) */
  154. //delay_micro_seconds(1);
  155. break;
  156. case U8X8_MSG_DELAY_10MICRO:
  157. delay_micro_seconds(arg_int*10UL);
  158. break;
  159. case U8X8_MSG_DELAY_100NANO:
  160. /* not used at the moment */
  161. delay_micro_seconds((arg_int+9)/10);
  162. break;
  163. case U8X8_MSG_DELAY_MILLI:
  164. delay_micro_seconds(arg_int*1000UL);
  165. break;
  166. case U8X8_MSG_DELAY_I2C:
  167. /* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
  168. delay_micro_seconds(arg_int<=2?5:1);
  169. break;
  170. case U8X8_MSG_GPIO_SPI_CLOCK:
  171. if ( arg_int == 0 )
  172. GPIOA->BSRR = GPIO_BSRR_BR_5; /* atomic clr */
  173. else
  174. GPIOA->BSRR = GPIO_BSRR_BS_5; /* atomic set */
  175. break;
  176. case U8X8_MSG_GPIO_SPI_DATA:
  177. if ( arg_int == 0 )
  178. GPIOA->BSRR = GPIO_BSRR_BR_7; /* atomic clr */
  179. else
  180. GPIOA->BSRR = GPIO_BSRR_BS_7; /* atomic set */
  181. break;
  182. case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
  183. if ( arg_int == 0 )
  184. GPIOA->BSRR = GPIO_BSRR_BR_13; /* atomic clr */
  185. else
  186. GPIOA->BSRR = GPIO_BSRR_BS_13; /* atomic set */
  187. break;
  188. case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
  189. if ( arg_int == 0 )
  190. GPIOA->BSRR = GPIO_BSRR_BR_14; /* atomic clr */
  191. else
  192. GPIOA->BSRR = GPIO_BSRR_BS_14; /* atomic set */
  193. break;
  194. case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int/*
  195. if ( arg_int == 0 )
  196. GPIOA->BSRR = GPIO_BSRR_BR_6; /* atomic clr */
  197. else
  198. GPIOA->BSRR = GPIO_BSRR_BS_6; /* atomic set */
  199. break;
  200. default:
  201. u8x8_SetGPIOResult(u8x8, 1);
  202. break;
  203. }
  204. return 1;
  205. }
  206. uint8_t u8x8_byte_stm32l0_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  207. {
  208. uint8_t *data;
  209. switch(msg) {
  210. case U8X8_MSG_BYTE_SEND:
  211. data = (uint8_t *)arg_ptr;
  212. while( arg_int > 0 )
  213. {
  214. while ( (SPI1->SR & SPI_SR_BSY) || (DMA1_Channel3->CNDTR != 0) ) // wait for transfer completion
  215. ;
  216. *(uint8_t *)&(SPI1->DR) = *data;
  217. data++;
  218. arg_int--;
  219. }
  220. break;
  221. case U8X8_MSG_BYTE_INIT:
  222. /* enable clock for SPI */
  223. RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; /* enable SPI1 */
  224. /* set a predivision if the system clock is too high, not required for 2MHz */
  225. RCC->CFGR &= ~RCC_CFGR_PPRE2_Msk;
  226. //RCC->CFGR |= RCC_CFGR_PPRE2_DIV4;
  227. /* output setup is already done, just enable the alternate mode here */
  228. GPIOA->MODER &= ~GPIO_MODER_MODE7; /* clear mode */
  229. GPIOA->MODER |= GPIO_MODER_MODE7_1; /* Alternate function mode */
  230. GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL7_Msk; /* clear af mode */
  231. GPIOA->AFR[0] |= 0 << GPIO_AFRL_AFRL7_Pos; /* assign af mode (which is 0 for SPI) */
  232. GPIOA->MODER &= ~GPIO_MODER_MODE5; /* clear mode */
  233. GPIOA->MODER |= GPIO_MODER_MODE5_1; /* Alternate function mode */
  234. GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL5_Msk; /* clear af mode */
  235. GPIOA->AFR[0] |= 0 << GPIO_AFRL_AFRL5_Pos; /* assign af mode (which is 0 for SPI) */
  236. /* setup and enable SPI subsystem */
  237. /* Note: We assume SPI mode 0 for the displays (true for the most modern displays), so CPHA and CPOL are forced to 0 here. SPI mode is here: u8x8->display_info->spi_mode */
  238. /* Note: The below assignment will setup also the clock speed, which in turn depends on the uC master clock */
  239. SPI1->CR1 = SPI_CR1_MSTR // master
  240. //| SPI_CR1_BIDIMODE
  241. //| SPI_CR1_BIDIOE
  242. | SPI_CR1_SSM
  243. | SPI_CR1_SSI
  244. //| SPI_CR1_BR_0
  245. //| SPI_CR1_BR_1
  246. //| SPI_CR1_BR_2 // speed
  247. //| SPI_CR1_CPHA
  248. //| SPI_CR1_CPOL
  249. ;
  250. SPI1->CR2 = 0; // SPI_CR2_TXDMAEN = transmit DMA enable
  251. SPI1->CR1 |= SPI_CR1_SPE; // SPI enable
  252. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  253. break;
  254. case U8X8_MSG_BYTE_SET_DC:
  255. while ( SPI1->SR & SPI_SR_BSY ) // wait for transfer completion
  256. ;
  257. u8x8_gpio_SetDC(u8x8, arg_int);
  258. break;
  259. case U8X8_MSG_BYTE_START_TRANSFER:
  260. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  261. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  262. break;
  263. case U8X8_MSG_BYTE_END_TRANSFER:
  264. while ( SPI1->SR & SPI_SR_BSY ) // wait for transfer completion
  265. ;
  266. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  267. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  268. break;
  269. default:
  270. return 0;
  271. }
  272. return 1;
  273. }
  274. uint8_t dma_buffer[256]; // required for DMA transfer
  275. uint8_t u8x8_byte_stm32l0_dma_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  276. {
  277. uint16_t i;
  278. switch(msg) {
  279. case U8X8_MSG_BYTE_SEND:
  280. /* data in arg_ptr will be overwritten, once we leave this function, so create a copy of it (note: memcpy seems to be slower) */
  281. for( i = 0; i < arg_int; i++ )
  282. dma_buffer[i] = ((uint8_t *)arg_ptr)[i];
  283. /* wait for completion of any previous transfer */
  284. while ( (SPI1->SR & SPI_SR_BSY) || (DMA1_Channel3->CNDTR != 0) ) // wait for transfer completion
  285. ;
  286. /* setup and start DMA SPI transfer */
  287. DMA1_Channel3->CCR = 0; // disable + reset channel 3
  288. /* defaults:
  289. - 8 Bit access --> ok
  290. - read from peripheral --> changed
  291. - none-circular mode --> ok
  292. - no increment mode --> will be changed below
  293. */
  294. DMA1_Channel3->CNDTR = arg_int; /* buffer size */
  295. DMA1_Channel3->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_EN; /* increment memory, copy from M to P, enable DMA */
  296. break;
  297. case U8X8_MSG_BYTE_INIT:
  298. /* enable clock for SPI and DMA*/
  299. RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; /* enable SPI1 */
  300. RCC->AHBENR |= RCC_AHBENR_DMA1EN;
  301. /* set a predivision if the system clock is too high, not required for 2MHz */
  302. RCC->CFGR &= ~RCC_CFGR_PPRE2_Msk;
  303. //RCC->CFGR |= RCC_CFGR_PPRE2_DIV4;
  304. /* output setup is already done, just enable the alternate mode here */
  305. GPIOA->MODER &= ~GPIO_MODER_MODE7; /* clear mode */
  306. GPIOA->MODER |= GPIO_MODER_MODE7_1; /* Alternate function mode */
  307. GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL7_Msk; /* clear af mode */
  308. GPIOA->AFR[0] |= 0 << GPIO_AFRL_AFRL7_Pos; /* assign af mode (which is 0 for SPI) */
  309. GPIOA->MODER &= ~GPIO_MODER_MODE5; /* clear mode */
  310. GPIOA->MODER |= GPIO_MODER_MODE5_1; /* Alternate function mode */
  311. GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL5_Msk; /* clear af mode */
  312. GPIOA->AFR[0] |= 0 << GPIO_AFRL_AFRL5_Pos; /* assign af mode (which is 0 for SPI) */
  313. DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S_Msk; /* clear selection on Channel 3 */
  314. DMA1_CSELR->CSELR |= 1 << DMA_CSELR_C3S_Pos; /* aktivate SPI_TX on Channel 3 */
  315. DMA1_Channel3->CCR = 0; // disable + reset channel 3
  316. DMA1_Channel3->CNDTR = 0; /* clear buffer size */
  317. DMA1_Channel3->CMAR = (uint32_t)dma_buffer;
  318. DMA1_Channel3->CPAR = (uint32_t)&(SPI1->DR);
  319. /* setup and enable SPI subsystem */
  320. /* Note: We assume SPI mode 0 for the displays (true for the most modern displays), so CPHA and CPOL are forced to 0 here. SPI mode is here: u8x8->display_info->spi_mode */
  321. /* Note: The below assignment will setup also the clock speed, which in turn depends on the uC master clock */
  322. SPI1->CR1 = SPI_CR1_MSTR // master
  323. //| SPI_CR1_BIDIMODE
  324. //| SPI_CR1_BIDIOE
  325. | SPI_CR1_SSM
  326. | SPI_CR1_SSI
  327. //| SPI_CR1_BR_0
  328. //| SPI_CR1_BR_1
  329. //| SPI_CR1_BR_2 // speed
  330. //| SPI_CR1_CPHA
  331. //| SPI_CR1_CPOL
  332. ;
  333. SPI1->CR2 = SPI_CR2_TXDMAEN; // SPI_CR2_TXDMAEN = transmit DMA enable
  334. SPI1->CR1 |= SPI_CR1_SPE; // SPI enable
  335. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  336. break;
  337. case U8X8_MSG_BYTE_SET_DC:
  338. while ( (SPI1->SR & SPI_SR_BSY) || (DMA1_Channel3->CNDTR != 0) ) // wait for transfer completion
  339. ;
  340. u8x8_gpio_SetDC(u8x8, arg_int);
  341. break;
  342. case U8X8_MSG_BYTE_START_TRANSFER:
  343. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  344. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  345. break;
  346. case U8X8_MSG_BYTE_END_TRANSFER:
  347. while ( (SPI1->SR & SPI_SR_BSY) || (DMA1_Channel3->CNDTR != 0) ) // wait for transfer completion
  348. ;
  349. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  350. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  351. break;
  352. default:
  353. return 0;
  354. }
  355. return 1;
  356. }