driver_ledc.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * @File name : driver_ledc.c
  3. * @Author : Bluetrum IOT Team K.
  4. * @Date : 2023-07-10
  5. * @Description : This file provides functions to manage the most functionalities
  6. * of the LEDC peripheral.
  7. * @WARNING : Due to IC logical error, we should make sure no other peripherals
  8. use the same DMA address as LEDC(SRAM0), or dma of ledc would be error.
  9. * Copyright (c) by Bluetrum, All Rights Reserved.
  10. */
  11. #include "driver_ledc.h"
  12. /**
  13. * @brief Initializes the LEDC peripheral according to the specified
  14. * parameters in the ledc_timing_init_struct.
  15. * @param ledc_timing_init_struct: pointer to a ledc_init_typedef structure that
  16. * contains the configuration information for the specified LEDC peripheral.
  17. * @retval None
  18. */
  19. void ledc_init(ledc_init_typedef *ledc_timing_init_struct)
  20. {
  21. u32 tmp_reg;
  22. /* Load the register value to variable */
  23. tmp_reg = LEDC->con;
  24. /* Clear value need to configure */
  25. tmp_reg &= ~(uint32_t)(LEDC_CON_OUT_INV | \
  26. LEDC_CON_BAUD | \
  27. LEDC_CON_DELAY | \
  28. LEDC_CON_IN_FORMAT | \
  29. LEDC_CON_IDLE_LEVEL | \
  30. LEDC_CON_VLD_INV);
  31. /* Config output data all invert */
  32. tmp_reg |= ledc_timing_init_struct->output_invert & LEDC_CON_OUT_INV;
  33. /* Config input format */
  34. tmp_reg |= ledc_timing_init_struct->format & LEDC_CON_IN_FORMAT;
  35. /* Config idle level */
  36. tmp_reg |= ledc_timing_init_struct->idle_level & LEDC_CON_IDLE_LEVEL;
  37. /* Config valid data direct or invert */
  38. tmp_reg |= ledc_timing_init_struct->valid_data_mode & LEDC_CON_VLD_INV;
  39. if (ledc_timing_init_struct->valid_data_mode & LEDC_CON_VLD_INV) {
  40. tmp_reg &= ~LEDC_CON_BYTE_INV;
  41. tmp_reg |= ledc_timing_init_struct->byte_inv_number & LEDC_CON_BYTE_INV;
  42. }
  43. /* Restore the value to register */
  44. LEDC->con = tmp_reg;
  45. }
  46. /**
  47. * @brief Initialize the code element timing accordingto the specified
  48. * parameters in the ledc_timing_init_struct.
  49. * @param ledc_timing_init_struct: pointer to a ledc_timing_init_typedef structure that
  50. * contains the configuration information for the specified LEDC peripheral.
  51. * @retval None
  52. */
  53. void ledc_timing_init(ledc_timing_init_typedef *ledc_timing_init_struct)
  54. {
  55. u32 tmp_reg;
  56. ledc_timing_init_typedef *p = ledc_timing_init_struct;
  57. /* Load the register value to variable */
  58. tmp_reg = LEDC->con;
  59. /* Config baud */
  60. tmp_reg |= (ledc_timing_init_struct->baud << 16) & LEDC_CON_BAUD;
  61. /* Config delay */
  62. tmp_reg |= (ledc_timing_init_struct->delay << 8) & LEDC_CON_DELAY;
  63. /* Restore the value to register */
  64. LEDC->con = tmp_reg;
  65. /* Config code element timing */
  66. tmp_reg = 0;
  67. if ((p->code_1_high <= p->baud) && (p->code_0_high <= p->baud)) {
  68. tmp_reg = (p->code_1_high << 24) | \
  69. ((p->baud - p->code_1_high) << 16) | \
  70. (p->code_0_high << 8) | \
  71. ((p->baud - p->code_0_high));
  72. }
  73. LEDC->tix = tmp_reg;
  74. /* Config reset timing */
  75. tmp_reg = (p->reset_low << 16) | p->reset_high;
  76. LEDC->rstx = tmp_reg;
  77. }
  78. /**
  79. * @brief De-initialize the specified LEDC peripheral.
  80. * @retval None
  81. */
  82. void ledc_deinit(void)
  83. {
  84. LEDC->con &= ~(LEDC_CON_DMA_INT_EN | \
  85. LEDC_CON_RST_INT_EN | \
  86. LEDC_CON_INT_EN | \
  87. LEDC_CON_EN);
  88. clk_gate2_cmd(CLK_GATE2_LEDC, CLK_DIS);
  89. }
  90. /**
  91. * @brief Enable or disable the specified LEDC peripheral.
  92. * @param state: the state of the LEDC peripheral.
  93. * This parameter can be: ENABLE or DISABLE.
  94. * @retval None
  95. */
  96. void ledc_cmd(FUNCTIONAL_STATE state)
  97. {
  98. if (state != DISABLE) {
  99. LEDC->con |= LEDC_CON_EN;
  100. } else {
  101. LEDC->con &= ~LEDC_CON_EN;
  102. }
  103. }
  104. /**
  105. * @brief Enable the LEDC DMA function.
  106. * @param addr: DMA start address.
  107. * @param len: DMA transmit len.
  108. * @retval None
  109. */
  110. AT(.com_periph.ledc.transport)
  111. void ledc_dma_kick(uint32_t addr, uint16_t len)
  112. {
  113. LEDC->addr = addr;
  114. LEDC->cnt = (0x01 << 31) | len;
  115. }
  116. /**
  117. * @brief Start ledc transmit.
  118. * @retval None
  119. */
  120. AT(.com_periph.ledc.transport)
  121. void ledc_kick(void)
  122. {
  123. LEDC->con |= LEDC_CON_LEDC_KICK;
  124. }
  125. /**
  126. * @brief Enable or disable the specified LEDC interrupt.
  127. * @param isr: Function to be executed for service interruption.
  128. * @param pr: Priority of service interruption.
  129. * @param flag_type: specifies the LEDC interrupt sources to be enable or disable.
  130. * This parameter can be one of the following values:
  131. * @arg LEDC_FLAG_DONE: One frame has tx done.
  132. * @arg LEDC_FLAG_RST: One frame has tx done and reset time has finished.
  133. * @arg LEDC_FLAG_DMA: One DMA transmit finished.
  134. * @param state: the new state need to config.
  135. * @retval None
  136. */
  137. void ledc_pic_config(isr_t isr, int pr, LEDC_FLAG_TYPEDEF flag_type, FUNCTIONAL_STATE state)
  138. {
  139. u32 flag_pending_bit = 0;
  140. if (flag_type == 0) {
  141. return;
  142. }
  143. if (flag_type & LEDC_FLAG_DONE) {
  144. flag_pending_bit |= LEDC_CON_INT_EN;
  145. }
  146. if (flag_type & LEDC_FLAG_RST) {
  147. flag_pending_bit |= LEDC_CON_RST_INT_EN;
  148. }
  149. if (flag_type & LEDC_FLAG_DMA) {
  150. flag_pending_bit |= LEDC_CON_DMA_INT_EN;
  151. }
  152. if (state != DISABLE) {
  153. LEDC->con |= flag_pending_bit;
  154. sys_irq_init(IRQn_IR_QDEC_LEDC, pr, isr);
  155. } else {
  156. LEDC->con &= ~flag_pending_bit;
  157. }
  158. }
  159. /**
  160. * @brief Check the specified LEDC flag is set or not.
  161. * @param flag_type: specifies the flag to check.
  162. * the parameter can be one of the following values:
  163. * @arg LEDC_FLAG_DONE: One frame has tx done.
  164. * @arg LEDC_FLAG_RST: One frame has tx done and reset time has finished.
  165. * @arg LEDC_FLAG_DMA: One DMA transmit finished.
  166. * @retval The state of flag_type (SET or RESET).
  167. */
  168. AT(.com_periph.ledc.flag)
  169. FLAG_STATE ledc_get_flag(LEDC_FLAG_TYPEDEF flag_type)
  170. {
  171. u32 flag_pending_bit = 0;
  172. if (flag_type & LEDC_FLAG_DONE) {
  173. flag_pending_bit |= LEDC_PEND_LEDC_PND;
  174. }
  175. if (flag_type & LEDC_FLAG_RST) {
  176. flag_pending_bit |= LEDC_PEND_RST_PND;
  177. }
  178. if (flag_type & LEDC_FLAG_DMA) {
  179. flag_pending_bit |= LEDC_PEND_DMA_PND;
  180. }
  181. if ((LEDC->pend & flag_pending_bit) != RESET) {
  182. return SET;
  183. } else {
  184. return RESET;
  185. }
  186. }
  187. /**
  188. * @brief Clear the LEDC pending.
  189. * @param flag_type: specified flag to clear.
  190. * @arg LEDC_FLAG_DONE: One frame has tx done.
  191. * @arg LEDC_FLAG_RST: One frame has tx done and reset time has finished.
  192. * @arg LEDC_FLAG_DMA: One DMA transmit finished.
  193. * @retval None
  194. */
  195. AT(.com_periph.ledc.flag)
  196. void ledc_clear_flag(LEDC_FLAG_TYPEDEF flag_type)
  197. {
  198. u32 flag_pending_bit = 0;
  199. if (flag_type & LEDC_FLAG_DONE) {
  200. flag_pending_bit |= LEDC_PEND_LEDC_PND;
  201. }
  202. if (flag_type & LEDC_FLAG_RST) {
  203. flag_pending_bit |= LEDC_PEND_RST_PND;
  204. }
  205. if (flag_type & LEDC_FLAG_DMA) {
  206. flag_pending_bit |= LEDC_PEND_DMA_PND;
  207. }
  208. LEDC->pend = flag_pending_bit;
  209. }
  210. /**
  211. * @brief Set the length of frame length.
  212. * @param frame_length: the length param of frame that need to config.
  213. * @retval None
  214. */
  215. void ledc_set_frame_length(uint16_t frame_length)
  216. {
  217. LEDC->fd = frame_length & 0xfff;
  218. }
  219. /**
  220. * @brief Set the number of loop.
  221. * @param loop_n: the number param of loop that need to config.
  222. * @retval None
  223. */
  224. void ledc_set_loop_number(uint16_t loop_n)
  225. {
  226. LEDC->lp = loop_n & 0x7ff;
  227. }
  228. /**
  229. * @brief Get the length of frame length.
  230. * @retval None
  231. */
  232. uint16_t ledc_get_frame_length(void)
  233. {
  234. return (LEDC->fd & 0xfff);
  235. }
  236. /**
  237. * @brief Get the number of loop.
  238. * @retval None
  239. */
  240. uint16_t ledc_get_loop_number(void)
  241. {
  242. return (LEDC->lp & 0x7ff);
  243. }