chargestore.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "generic/typedef.h"
  2. #include "generic/gpio.h"
  3. #include "asm/power/p33.h"
  4. #include "asm/hwi.h"
  5. #include "asm/gpio.h"
  6. #include "asm/clock.h"
  7. #include "asm/charge.h"
  8. #include "asm/chargestore.h"
  9. #include "asm/power_interface.h"
  10. #include "update.h"
  11. #include "app_config.h"
  12. #if (TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE || TCFG_ANC_BOX_ENABLE)
  13. struct chargestore_handle {
  14. const struct chargestore_platform_data *data;
  15. JL_UART_TypeDef *UART;
  16. u32 baudrate;
  17. };
  18. #define DMA_ISR_LEN 64
  19. #define DMA_BUF_LEN 64
  20. #define __this (&hdl)
  21. static struct chargestore_handle hdl;
  22. u8 uart_dma_buf[DMA_BUF_LEN] __attribute__((aligned(4)));
  23. volatile u8 send_busy;
  24. //串口时钟和串口超时时钟是分开的
  25. #define UART_SRC_CLK clk_get("uart")
  26. #define UART_OT_CLK clk_get("lsb")
  27. enum {
  28. UPGRADE_NULL = 0,
  29. UPGRADE_USB_HARD_KEY,
  30. UPGRADE_USB_SOFTKEY,
  31. UPGRADE_UART_SOFT_KEY,
  32. UPGRADE_UART_ONE_WIRE_HARD_KEY,
  33. };
  34. extern void nvram_set_boot_state(u32 state);
  35. void chargestore_set_update_ram(void)
  36. {
  37. //需要补充设置ram
  38. int tmp;
  39. __asm__ volatile("%0 =icfg" : "=r"(tmp));
  40. tmp &= ~(3 << 8);
  41. __asm__ volatile("icfg = %0" :: "r"(tmp));//GIE1
  42. local_irq_disable();
  43. nvram_set_boot_state(UPGRADE_UART_SOFT_KEY);
  44. }
  45. void __attribute__((weak)) chargestore_data_deal(u8 cmd, u8 *data, u8 len)
  46. {
  47. }
  48. void __attribute__((weak)) chargestore_uart_data_deal(u8 *data, u8 len)
  49. {
  50. }
  51. static u8 chargestore_get_f95_det_res(u32 equ_res)
  52. {
  53. u8 det_res = (equ_res + 50) / 100;
  54. if (det_res > 0) {
  55. det_res -= 1;
  56. }
  57. if (det_res > 0x0f) {
  58. det_res = 0x0f;
  59. }
  60. return det_res;
  61. }
  62. u8 chargestore_get_det_level(u8 chip_type)
  63. {
  64. u32 res = 1000;
  65. switch (chip_type) {
  66. case TYPE_F95:
  67. if (IS_L5V_LOAD_EN()) {
  68. res = (GET_L5V_RES_DET_S_SEL() + 1) * 50;
  69. }
  70. return chargestore_get_f95_det_res(res);
  71. case TYPE_NORMAL:
  72. default:
  73. return 0x0f;
  74. }
  75. }
  76. ___interrupt
  77. static void uart_isr(void)
  78. {
  79. u16 i;
  80. u32 rx_len = 0;
  81. if ((__this->UART->CON0 & BIT(2)) && (__this->UART->CON0 & BIT(15))) {
  82. __this->UART->CON0 |= BIT(13);
  83. send_busy = 0;
  84. chargestore_data_deal(CMD_COMPLETE, NULL, 0);
  85. }
  86. if ((__this->UART->CON0 & BIT(3)) && (__this->UART->CON0 & BIT(14))) {
  87. __this->UART->CON0 |= BIT(12);//清RX PND
  88. chargestore_data_deal(CMD_RECVDATA, uart_dma_buf, DMA_ISR_LEN);
  89. memset((void *)uart_dma_buf, 0, sizeof(uart_dma_buf));
  90. __this->UART->RXSADR = (u32)uart_dma_buf;
  91. __this->UART->RXEADR = (u32)(uart_dma_buf + DMA_BUF_LEN);
  92. __this->UART->RXCNT = DMA_ISR_LEN;
  93. }
  94. if ((__this->UART->CON0 & BIT(5)) && (__this->UART->CON0 & BIT(11))) {
  95. //OTCNT PND
  96. __this->UART->CON0 |= BIT(7);//DMA模式
  97. __this->UART->CON0 |= BIT(10);//清OTCNT PND
  98. asm volatile("nop");
  99. rx_len = __this->UART->HRXCNT;//读当前串口接收数据的个数
  100. __this->UART->CON0 |= BIT(12);//清RX PND(这里的顺序不能改变,这里要清一次)
  101. chargestore_data_deal(CMD_RECVDATA, uart_dma_buf, rx_len);
  102. chargestore_uart_data_deal(uart_dma_buf, rx_len);
  103. memset((void *)uart_dma_buf, 0, sizeof(uart_dma_buf));
  104. __this->UART->RXSADR = (u32)uart_dma_buf;
  105. __this->UART->RXEADR = (u32)(uart_dma_buf + DMA_BUF_LEN);
  106. __this->UART->RXCNT = DMA_ISR_LEN;
  107. }
  108. }
  109. void chargestore_write(u8 *data, u8 len)
  110. {
  111. u32 data_addr = (u32)data;
  112. if (data_addr % 4) {//4byte对齐
  113. ASSERT(0, "%s: unaligned accesses!", __func__);
  114. }
  115. send_busy = 1;
  116. __this->UART->TXADR = data_addr;
  117. __this->UART->TXCNT = len;
  118. }
  119. void chargestore_open(u8 mode)
  120. {
  121. __this->UART->CON0 = BIT(13) | BIT(12) | BIT(10);
  122. power_wakeup_disable_with_port(__this->data->io_port);
  123. if (mode == MODE_RECVDATA) {
  124. charge_set_ldo5v_detect_stop(0);
  125. gpio_direction_input(__this->data->io_port);
  126. gpio_set_die(__this->data->io_port, 1);
  127. __this->UART->CON1 &= ~BIT(4);
  128. if (__this->UART == JL_UART0) {
  129. gpio_set_fun_input_port(__this->data->io_port, PFI_UART0_RX);
  130. } else if (__this->UART == JL_UART1) {
  131. gpio_set_fun_input_port(__this->data->io_port, PFI_UART1_RX);
  132. } else {
  133. gpio_set_fun_input_port(__this->data->io_port, PFI_UART2_RX);
  134. }
  135. memset((void *)uart_dma_buf, 0, sizeof(uart_dma_buf));
  136. __this->UART->RXSADR = (u32)uart_dma_buf;
  137. __this->UART->RXEADR = (u32)(uart_dma_buf + DMA_BUF_LEN);
  138. __this->UART->RXCNT = DMA_ISR_LEN;
  139. __this->UART->CON0 |= BIT(6) | BIT(5) | BIT(3);
  140. } else {
  141. charge_set_ldo5v_detect_stop(1);
  142. gpio_direction_output(__this->data->io_port, 1);
  143. gpio_set_hd(__this->data->io_port, 1);
  144. __this->UART->CON1 |= BIT(4);
  145. if (__this->UART == JL_UART0) {
  146. gpio_set_fun_output_port(__this->data->io_port, FO_UART0_TX, 1, 1);
  147. } else if (__this->UART == JL_UART1) {
  148. gpio_set_fun_output_port(__this->data->io_port, FO_UART1_TX, 1, 1);
  149. } else {
  150. gpio_set_fun_output_port(__this->data->io_port, FO_UART2_TX, 1, 1);
  151. }
  152. __this->UART->CON0 |= BIT(2);
  153. }
  154. __this->UART->CON0 |= BIT(13) | BIT(12) | BIT(10) | BIT(1) | BIT(0);
  155. }
  156. void chargestore_close(void)
  157. {
  158. __this->UART->CON0 = BIT(13) | BIT(12) | BIT(10) | BIT(0);
  159. gpio_set_pull_down(__this->data->io_port, 0);
  160. gpio_set_pull_up(__this->data->io_port, 0);
  161. gpio_set_die(__this->data->io_port, 1);
  162. gpio_set_hd(__this->data->io_port, 0);
  163. gpio_direction_input(__this->data->io_port);
  164. memset((void *)uart_dma_buf, 0, sizeof(uart_dma_buf));
  165. power_wakeup_enable_with_port(__this->data->io_port);
  166. charge_set_ldo5v_detect_stop(0);
  167. }
  168. void chargestore_set_baudrate(u32 baudrate)
  169. {
  170. u32 uart_timeout;
  171. __this->baudrate = baudrate;
  172. uart_timeout = 20 * 1000000 / __this->baudrate;
  173. __this->UART->OTCNT = uart_timeout * (UART_OT_CLK / 1000000);
  174. __this->UART->BAUD = (UART_SRC_CLK / __this->baudrate) / 4 - 1;
  175. }
  176. void chargestore_init(const struct chargestore_platform_data *data)
  177. {
  178. u32 uart_timeout;
  179. __this->data = (struct chargestore_platform_data *)data;
  180. ASSERT(data);
  181. if (!(JL_UART0->CON0 & BIT(0))) {
  182. JL_UART0->CON0 = BIT(13) | BIT(12) | BIT(10);
  183. request_irq(IRQ_UART0_IDX, 2, uart_isr, 0);
  184. __this->UART = JL_UART0;
  185. } else if (!(JL_UART1->CON0 & BIT(0))) {
  186. JL_UART1->CON0 = BIT(13) | BIT(12) | BIT(10);
  187. request_irq(IRQ_UART1_IDX, 2, uart_isr, 0);
  188. __this->UART = JL_UART1;
  189. } else if (!(JL_UART2->CON0 & BIT(0))) {
  190. JL_UART2->CON0 = BIT(13) | BIT(12) | BIT(10);
  191. request_irq(IRQ_UART2_IDX, 2, uart_isr, 0);
  192. __this->UART = JL_UART2;
  193. } else {
  194. ASSERT(0, "uart all used!\n");
  195. }
  196. send_busy = 0;
  197. uart_timeout = 20 * 1000000 / __this->data->baudrate;
  198. __this->UART->CON0 = BIT(13) | BIT(12) | BIT(10) | BIT(1) | BIT(0);//占用该串口,不被其他模块使用
  199. __this->UART->OTCNT = uart_timeout * (UART_OT_CLK / 1000000);
  200. __this->UART->BAUD = (UART_SRC_CLK / __this->data->baudrate) / 4 - 1;
  201. __this->baudrate = __this->data->baudrate;
  202. gpio_set_pull_down(__this->data->io_port, 0);
  203. gpio_set_pull_up(__this->data->io_port, 0);
  204. gpio_set_die(__this->data->io_port, 1);
  205. gpio_direction_input(__this->data->io_port);
  206. }
  207. static void clock_critical_enter(void)
  208. {
  209. if (__this->UART == NULL) {
  210. return;
  211. }
  212. u8 cmp_buf[2] = {0x55, 0xAA};
  213. //等待数据收完
  214. extern void *memmem(void *srcmem, int src_len, void *desmem, int des_len);
  215. while (memmem(uart_dma_buf, sizeof(uart_dma_buf), cmp_buf, sizeof(cmp_buf)));
  216. //等待数据发完
  217. while (send_busy);
  218. }
  219. static void clock_critical_exit(void)
  220. {
  221. u32 uart_timeout;
  222. if (__this->UART == NULL) {
  223. return;
  224. }
  225. uart_timeout = 20 * 1000000 / __this->baudrate;
  226. __this->UART->OTCNT = uart_timeout * (UART_OT_CLK / 1000000);
  227. __this->UART->BAUD = (UART_SRC_CLK / __this->baudrate) / 4 - 1;
  228. }
  229. CLOCK_CRITICAL_HANDLE_REG(chargestore, clock_critical_enter, clock_critical_exit)
  230. #endif