drv_can.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319
  1. /*
  2. * Copyright (c) 2006-2026, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2026-04-20 rcitach first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "interrupt.h"
  13. #include "board.h"
  14. #include "drv_can.h"
  15. #include "drv_gpio.h"
  16. #define DBG_TAG "drv.can"
  17. #define DBG_LVL DBG_LOG
  18. #include <rtdbg.h>
  19. #define CAN_RET(_err, _msg) \
  20. do { LOG_E("%s ret=%d", (_msg), (int)(_err)); return (_err); } while (0)
  21. #define CAN_RET_FMT(_err, _fmt, ...) \
  22. do { LOG_E(_fmt " ret=%d", ##__VA_ARGS__, (int)(_err)); return (_err); } while (0)
  23. #define S100_CAN_CLK_WORKAROUND_BASE (0x2370007CU)
  24. #define S100_CAN_CLK_WORKAROUND_COUNT (10U)
  25. #define S100_CAN_CLK_WORKAROUND_ENABLE (0x8000U)
  26. #define S100_MCU2CAN_STB_N_PIN (6U)
  27. #define S100_CAN_DEFAULT_CLK_HZ (40000000UL)
  28. #define S100_CAN5_BASE (0x23720000UL)
  29. #define S100_CAN6_BASE (0x23730000UL)
  30. #define S100_CAN7_BASE (0x23740000UL)
  31. #define S100_CAN8_BASE (0x23750000UL)
  32. #define S100_CAN9_BASE (0x23760000UL)
  33. #define S100_CAN5_IRQ (136U)
  34. #define S100_CAN6_IRQ (140U)
  35. #define S100_CAN7_IRQ (144U)
  36. #define S100_CAN8_IRQ (148U)
  37. #define S100_CAN9_IRQ (152U)
  38. #define S100_CAN_MAX_MB_NUM (128U)
  39. #define S100_CAN_MAX_MB_INDEX (55U)
  40. #define S100_CAN_BASIC_TX_MB_START (16U)
  41. #define S100_CAN_DEFAULT_PRESDIV (1U)
  42. #define S100_CAN_DEFAULT_PROPSEG (7U)
  43. #define S100_CAN_DEFAULT_PSEG1 (8U)
  44. #define S100_CAN_DEFAULT_PSEG2 (4U)
  45. #define S100_CAN_DEFAULT_RJW (2U)
  46. #define S100_CAN_BASIC_TIMEOUT_LOOP (1000000U)
  47. #define S100_CAN_STD_ID_SHIFT (18U)
  48. #define S100_CAN_STD_ID_MASK (0x7FFU)
  49. #define S100_CAN_MB_CODE_TX_INACTIVE (0x8U)
  50. #define S100_CAN_MB_CODE_TX_DATA (0xCU)
  51. #define S100_CAN_ENHANCED_FILTER_STD_SHIFT1 (0U)
  52. #define S100_CAN_ENHANCED_FILTER_STD_SHIFT2 (16U)
  53. #define S100_CAN_ENHANCED_FILTER_FSCH_SHIFT (30U)
  54. #define S100_CAN_ENHANCED_FILTER_STD_MASK (0x7FFU)
  55. #define S100_CAN_MB_CODE_SHIFT 24U
  56. struct s100_can_basic_frame
  57. {
  58. rt_uint32_t cs;
  59. rt_uint32_t id;
  60. rt_uint32_t data0;
  61. rt_uint32_t data1;
  62. };
  63. typedef struct s100_can_basic_frame s100_can_mb_t;
  64. struct s100_can_basic_baudrate_cfg
  65. {
  66. rt_uint32_t presdiv;
  67. rt_uint32_t propseg;
  68. rt_uint32_t pseg1;
  69. rt_uint32_t pseg2;
  70. rt_uint32_t rjw;
  71. rt_bool_t loopback;
  72. };
  73. struct s100_can_basic_state
  74. {
  75. struct rt_ringbuffer rx_rb;
  76. rt_uint8_t rx_rb_pool[S100_CAN_BASIC_TX_MB_START * sizeof(struct s100_can_basic_frame)];
  77. rt_uint8_t tx_done;
  78. rt_uint8_t ehfifo_enabled;
  79. rt_uint16_t rx_overrun;
  80. };
  81. struct s100_can_basic
  82. {
  83. const char *name;
  84. s100_can_regs_t *regs;
  85. rt_int32_t irqno;
  86. rt_uint8_t ctrl_id;
  87. rt_uint8_t irq_inited;
  88. rt_uint32_t irq_mask_flags;
  89. struct s100_can_basic_state state;
  90. #ifdef RT_CAN_USING_HDR
  91. rt_uint8_t filter_valid;
  92. struct rt_can_filter_item filter;
  93. #endif
  94. struct rt_can_device can_dev;
  95. };
  96. static struct s100_can_basic s100_can_basics[] =
  97. {
  98. #ifdef BSP_USING_CAN5
  99. {
  100. .name = "can5",
  101. .regs = (s100_can_regs_t *)S100_CAN5_BASE,
  102. .irqno = S100_CAN5_IRQ,
  103. .ctrl_id = 5U,
  104. },
  105. #endif
  106. #ifdef BSP_USING_CAN6
  107. {
  108. .name = "can6",
  109. .regs = (s100_can_regs_t *)S100_CAN6_BASE,
  110. .irqno = S100_CAN6_IRQ,
  111. .ctrl_id = 6U,
  112. },
  113. #endif
  114. #ifdef BSP_USING_CAN7
  115. {
  116. .name = "can7",
  117. .regs = (s100_can_regs_t *)S100_CAN7_BASE,
  118. .irqno = S100_CAN7_IRQ,
  119. .ctrl_id = 7U,
  120. },
  121. #endif
  122. #ifdef BSP_USING_CAN8
  123. {
  124. .name = "can8",
  125. .regs = (s100_can_regs_t *)S100_CAN8_BASE,
  126. .irqno = S100_CAN8_IRQ,
  127. .ctrl_id = 8U,
  128. },
  129. #endif
  130. #ifdef BSP_USING_CAN9
  131. {
  132. .name = "can9",
  133. .regs = (s100_can_regs_t *)S100_CAN9_BASE,
  134. .irqno = S100_CAN9_IRQ,
  135. .ctrl_id = 9U,
  136. },
  137. #endif
  138. };
  139. static inline s100_can_mb_t *s100_can_basic_mb(s100_can_regs_t *base, rt_uint32_t mb_index)
  140. {
  141. return (s100_can_mb_t *)((rt_uintptr_t)base +
  142. FLEXCAN_IP_FEATURE_RAM_OFFSET +
  143. (mb_index * sizeof(s100_can_mb_t)));
  144. }
  145. static inline rt_uint32_t s100_can_basic_tx_box_to_mb(rt_uint32_t boxno)
  146. {
  147. return S100_CAN_BASIC_TX_MB_START + boxno;
  148. }
  149. static void s100_can_clear_ram_words(volatile rt_uint32_t *ram, rt_uint32_t count)
  150. {
  151. rt_uint32_t i;
  152. for (i = 0U; i < count; i++)
  153. {
  154. ram[i] = 0U;
  155. }
  156. }
  157. static rt_bool_t s100_can_basic_wait_set(volatile rt_uint32_t *reg, rt_uint32_t mask, rt_bool_t set)
  158. {
  159. rt_uint32_t timeout = S100_CAN_BASIC_TIMEOUT_LOOP;
  160. while (timeout > 0U)
  161. {
  162. if (set != RT_FALSE)
  163. {
  164. if ((*reg & mask) == mask)
  165. {
  166. return RT_TRUE;
  167. }
  168. }
  169. else
  170. {
  171. if ((*reg & mask) == 0U)
  172. {
  173. return RT_TRUE;
  174. }
  175. }
  176. timeout--;
  177. }
  178. return RT_FALSE;
  179. }
  180. static rt_err_t s100_can_basic_enter_freeze(s100_can_regs_t *base)
  181. {
  182. base->MCR = (base->MCR & ~FLEXCAN_MCR_FRZ_MASK) | FLEXCAN_MCR_FRZ(1U);
  183. base->MCR = (base->MCR & ~FLEXCAN_MCR_HALT_MASK) | FLEXCAN_MCR_HALT(1U);
  184. if (((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT) != 0U)
  185. {
  186. base->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
  187. }
  188. if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_FRZACK_MASK, RT_TRUE) == RT_FALSE)
  189. {
  190. CAN_RET(-RT_ETIMEOUT, "enter freeze timeout");
  191. }
  192. return RT_EOK;
  193. }
  194. static rt_err_t s100_can_basic_exit_freeze(s100_can_regs_t *base)
  195. {
  196. base->MCR = (base->MCR & ~FLEXCAN_MCR_HALT_MASK) | FLEXCAN_MCR_HALT(0U);
  197. if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_FRZACK_MASK, RT_FALSE) == RT_FALSE)
  198. {
  199. CAN_RET(-RT_ETIMEOUT, "exit freeze timeout");
  200. }
  201. return RT_EOK;
  202. }
  203. static rt_err_t s100_can_basic_stop(s100_can_regs_t *base)
  204. {
  205. if (0U == ((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT))
  206. {
  207. base->MCR = (base->MCR & ~FLEXCAN_MCR_MDIS_MASK) | FLEXCAN_MCR_MDIS(1U);
  208. if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_MDIS_MASK, RT_TRUE) == RT_FALSE)
  209. {
  210. CAN_RET(-RT_ETIMEOUT, "stop controller timeout");
  211. }
  212. }
  213. return RT_EOK;
  214. }
  215. static rt_err_t s100_can_basic_soft_reset(s100_can_regs_t *base)
  216. {
  217. base->MCR = (base->MCR & ~FLEXCAN_MCR_SOFTRST_MASK) | FLEXCAN_MCR_SOFTRST(1U);
  218. if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_SOFTRST_MASK, RT_FALSE) == RT_FALSE)
  219. {
  220. CAN_RET(-RT_ETIMEOUT, "soft reset timeout");
  221. }
  222. return RT_EOK;
  223. }
  224. static void s100_can_basic_init_ecc_req_ram(s100_can_regs_t *base)
  225. {
  226. volatile rt_uint32_t *ram;
  227. ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_OFFSET);
  228. s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_COUNT);
  229. ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_FILTER_RAM_OFFSET);
  230. s100_can_clear_ram_words(ram, FLEXCAN_ERFFEL_COUNT);
  231. ram = (volatile rt_uint32_t *)base->RESERVED_4;
  232. s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_SMB_1_RAM_COUNT);
  233. ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_SMB_2_RAM_OFFSET);
  234. s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_SMB_2_RAM_COUNT);
  235. ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_OFFSET);
  236. s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_COUNT);
  237. s100_can_clear_ram_words(base->HR_TIME_STAMP, FLEXCAN_HR_TIME_STAMP_COUNT);
  238. }
  239. static void s100_can_basic_init_flexcan_ram(s100_can_regs_t *base)
  240. {
  241. volatile rt_uint32_t *ram;
  242. ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_RAM_OFFSET);
  243. s100_can_clear_ram_words(ram, S100_CAN_MAX_MB_NUM * 4U);
  244. s100_can_clear_ram_words(base->RXIMR, S100_CAN_MAX_MB_NUM);
  245. base->CTRL2 = (base->CTRL2 & ~FLEXCAN_CTRL2_WRMFRZ_MASK) | FLEXCAN_CTRL2_WRMFRZ(1U);
  246. base->RXMGMASK = 0U;
  247. base->RXFGMASK = 0U;
  248. base->RX14MASK = 0U;
  249. base->RX15MASK = 0U;
  250. s100_can_basic_init_ecc_req_ram(base);
  251. base->CTRL2 = (base->CTRL2 & ~FLEXCAN_CTRL2_WRMFRZ_MASK) | FLEXCAN_CTRL2_WRMFRZ(0U);
  252. }
  253. static void s100_can_basic_set_mem_error_detection(s100_can_regs_t *base, rt_uint32_t eccdis)
  254. {
  255. base->CTRL2 |= FLEXCAN_CTRL2_ECRWRE_MASK;
  256. base->MECR = 0U;
  257. base->MECR |= FLEXCAN_MECR_ECCDIS(eccdis);
  258. base->CTRL2 &= ~FLEXCAN_CTRL2_ECRWRE_MASK;
  259. }
  260. static rt_uint32_t s100_can_basic_build_mb_cs(rt_uint32_t code, rt_uint32_t dlc, rt_bool_t ide, rt_bool_t rtr)
  261. {
  262. rt_uint32_t cs = 0U;
  263. cs |= ((code & 0x0FU) << 24U);
  264. cs |= ((dlc & 0x0FU) << 16U);
  265. if (ide != RT_FALSE)
  266. {
  267. cs |= (1UL << 21) | (1UL << 22);
  268. }
  269. if (rtr != RT_FALSE)
  270. {
  271. cs |= (1UL << 20);
  272. }
  273. return cs;
  274. }
  275. static void s100_can_basic_config_ehrxfifo_filters_all_std(struct s100_can_basic *ctrl)
  276. {
  277. ctrl->regs->ERFFEL[0] =
  278. ((0U & S100_CAN_ENHANCED_FILTER_STD_MASK) << S100_CAN_ENHANCED_FILTER_STD_SHIFT1) |
  279. ((S100_CAN_STD_ID_MASK & S100_CAN_ENHANCED_FILTER_STD_MASK) << S100_CAN_ENHANCED_FILTER_STD_SHIFT2) |
  280. (1U << S100_CAN_ENHANCED_FILTER_FSCH_SHIFT);
  281. }
  282. static void s100_can_basic_read_ehrxfifo(struct s100_can_basic *ctrl, struct s100_can_basic_frame *frame)
  283. {
  284. volatile const rt_uint32_t *fifo_ram;
  285. fifo_ram = (volatile const rt_uint32_t *)((rt_uintptr_t)ctrl->regs + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_OFFSET);
  286. frame->cs = fifo_ram[0];
  287. frame->id = fifo_ram[1];
  288. frame->data0 = fifo_ram[2];
  289. frame->data1 = fifo_ram[3];
  290. }
  291. static rt_err_t s100_can_basic_init_ehrxfifo(struct s100_can_basic *ctrl,
  292. rt_uint32_t numOfStdIDFilters,
  293. rt_uint32_t numOfExtIDFilters,
  294. rt_uint32_t numOfWatermark)
  295. {
  296. rt_uint32_t NumOfEnhancedFilters = 0U;
  297. s100_can_regs_t *base = ctrl->regs;
  298. /* NumOfEnhancedFilters equals (numOfStdIDFilters/2) + numOfExtIDFilters - 1u */
  299. NumOfEnhancedFilters = (numOfStdIDFilters >> 1u) + numOfExtIDFilters - 1u;
  300. if ((0U == numOfStdIDFilters) && (0U == numOfExtIDFilters))
  301. {
  302. CAN_RET(-RT_ERROR, "ehrxfifo invalid filter count");
  303. }
  304. /* If the no of Std Filters is odd */
  305. if (1U == (numOfStdIDFilters & 1U))
  306. {
  307. CAN_RET(-RT_ERROR, "ehrxfifo std filter count must be even");
  308. }
  309. /*Enhanced RX FIFO and Legacy RX FIFO cannot be enabled at the same time.*/
  310. if (FLEXCAN_MCR_RFEN_MASK == (base->MCR & FLEXCAN_MCR_RFEN_MASK))
  311. {
  312. CAN_RET(-RT_ERROR, "ehrxfifo conflicts with legacy rxfifo");
  313. }
  314. base->ERFIER = 0U;
  315. /* Enable Enhanced Rx FIFO */
  316. base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_ERFEN_MASK) | FLEXCAN_ERFCR_ERFEN(1U);
  317. /* Reset Enhanced Rx FIFO engine */
  318. base->ERFSR = (base->ERFSR & ~FLEXCAN_ERFSR_ERFCLR_MASK) | FLEXCAN_ERFSR_ERFCLR(1U);
  319. /* Clear the status bits of the Enhanced RX FIFO */
  320. base->ERFSR = FLEXCAN_ERFSR_ERFUFW_MASK |
  321. FLEXCAN_ERFSR_ERFOVF_MASK |
  322. FLEXCAN_ERFSR_ERFWMI_MASK |
  323. FLEXCAN_ERFSR_ERFDA_MASK;
  324. /* Set the total number of enhanced Rx FIFO filter elements */
  325. base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_NFE_MASK) | ((NumOfEnhancedFilters << FLEXCAN_ERFCR_NFE_SHIFT) & FLEXCAN_ERFCR_NFE_MASK);
  326. /* Set the number of extended ID filter elements */
  327. base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_NEXIF_MASK) | ((numOfExtIDFilters << FLEXCAN_ERFCR_NEXIF_SHIFT) & FLEXCAN_ERFCR_NEXIF_MASK);
  328. /* Set the Enhanced Rx FIFO watermark */
  329. base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_ERFWM_MASK) | ((numOfWatermark << FLEXCAN_ERFCR_ERFWM_SHIFT) & FLEXCAN_ERFCR_ERFWM_MASK);
  330. s100_can_basic_config_ehrxfifo_filters_all_std(ctrl);
  331. return RT_EOK;
  332. }
  333. static void s100_can_basic_init_tx_mb(struct s100_can_basic *ctrl)
  334. {
  335. rt_uint32_t i;
  336. for (i = S100_CAN_BASIC_TX_MB_START; i < S100_CAN_MAX_MB_INDEX; i++)
  337. {
  338. s100_can_mb_t *mb = s100_can_basic_mb(ctrl->regs, i);
  339. mb->cs = 0U;
  340. mb->id = 0U;
  341. mb->data0 = 0U;
  342. mb->data1 = 0U;
  343. mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_INACTIVE, 0U, RT_FALSE, RT_FALSE);
  344. }
  345. }
  346. static rt_err_t s100_can_basic_wait_ready(s100_can_regs_t *base)
  347. {
  348. rt_uint32_t timeout = S100_CAN_BASIC_TIMEOUT_LOOP;
  349. while (timeout > 0U)
  350. {
  351. if (((base->MCR & FLEXCAN_MCR_NOTRDY_MASK) == 0U) &&
  352. ((base->ESR1 & FLEXCAN_ESR1_SYNCH_MASK) != 0U))
  353. {
  354. return RT_EOK;
  355. }
  356. timeout--;
  357. }
  358. CAN_RET(-RT_ETIMEOUT, "wait ready timeout");
  359. }
  360. static void s100_can_basic_update_irq_mask(struct s100_can_basic *ctrl, rt_uint32_t flags, rt_bool_t enable)
  361. {
  362. rt_uint32_t imask1_tx = 0U;
  363. rt_uint32_t imask2_tx = 0U;
  364. rt_uint32_t i;
  365. if ((flags & RT_DEVICE_FLAG_INT_TX) != 0U)
  366. {
  367. for (i = S100_CAN_BASIC_TX_MB_START; i < 32U; i++)
  368. {
  369. imask1_tx |= (1UL << i);
  370. }
  371. for (i = 0U; i < (S100_CAN_MAX_MB_INDEX - 32U); i++)
  372. {
  373. imask2_tx |= (1UL << i);
  374. }
  375. if (enable != RT_FALSE)
  376. {
  377. ctrl->regs->IMASK1 |= imask1_tx;
  378. ctrl->regs->IMASK2 |= imask2_tx;
  379. }
  380. else
  381. {
  382. ctrl->regs->IMASK1 &= ~imask1_tx;
  383. ctrl->regs->IMASK2 &= ~imask2_tx;
  384. }
  385. }
  386. if ((flags & RT_DEVICE_FLAG_INT_RX) != 0U)
  387. {
  388. if (enable != RT_FALSE)
  389. {
  390. ctrl->regs->ERFIER |= FLEXCAN_ERFIER_ERFDAIE_MASK |
  391. FLEXCAN_ERFIER_ERFOVFIE_MASK |
  392. FLEXCAN_ERFIER_ERFUFWIE_MASK;
  393. }
  394. else
  395. {
  396. ctrl->regs->ERFIER &= ~(FLEXCAN_ERFIER_ERFDAIE_MASK |
  397. FLEXCAN_ERFIER_ERFOVFIE_MASK |
  398. FLEXCAN_ERFIER_ERFUFWIE_MASK);
  399. }
  400. }
  401. if ((flags & RT_DEVICE_CAN_INT_ERR) != 0U)
  402. {
  403. if (enable != RT_FALSE)
  404. {
  405. ctrl->regs->CTRL1 |= FLEXCAN_CTRL1_ERRMSK_MASK | FLEXCAN_CTRL1_BOFFMSK_MASK;
  406. }
  407. else
  408. {
  409. ctrl->regs->CTRL1 &= ~(FLEXCAN_CTRL1_ERRMSK_MASK | FLEXCAN_CTRL1_BOFFMSK_MASK);
  410. }
  411. }
  412. }
  413. static rt_err_t s100_can_basic_calc_baudrate_params(struct s100_can_basic *ctrl,
  414. const struct can_configure *cfg,
  415. struct s100_can_basic_baudrate_cfg *baud_cfg)
  416. {
  417. rt_uint32_t clk_hz;
  418. rt_uint32_t baud;
  419. rt_uint32_t tq_num;
  420. rt_uint32_t presdiv;
  421. if ((cfg == RT_NULL) || (baud_cfg == RT_NULL))
  422. {
  423. CAN_RET(-RT_EINVAL, "calc baudrate params invalid argument");
  424. }
  425. baud = cfg->baud_rate;
  426. clk_hz = S100_CAN_DEFAULT_CLK_HZ;
  427. switch (baud)
  428. {
  429. case CAN1MBaud:
  430. case CAN500kBaud:
  431. case CAN250kBaud:
  432. case CAN125kBaud:
  433. case CAN100kBaud:
  434. case CAN50kBaud:
  435. case CAN20kBaud:
  436. case CAN10kBaud:
  437. tq_num = 20U;
  438. baud_cfg->propseg = 7U;
  439. baud_cfg->pseg1 = 8U;
  440. baud_cfg->pseg2 = 4U;
  441. baud_cfg->rjw = 2U;
  442. break;
  443. case CAN800kBaud:
  444. tq_num = 10U;
  445. baud_cfg->propseg = 2U;
  446. baud_cfg->pseg1 = 5U;
  447. baud_cfg->pseg2 = 2U;
  448. baud_cfg->rjw = 2U;
  449. break;
  450. default:
  451. CAN_RET_FMT(-RT_EINVAL, "unsupported nominal baud=%lu", (unsigned long)baud);
  452. }
  453. if ((baud_cfg->propseg + baud_cfg->pseg1) <= baud_cfg->pseg2)
  454. {
  455. CAN_RET_FMT(-RT_EINVAL, "invalid timing split prop=%lu pseg1=%lu pseg2=%lu",
  456. (unsigned long)baud_cfg->propseg,
  457. (unsigned long)baud_cfg->pseg1,
  458. (unsigned long)baud_cfg->pseg2);
  459. }
  460. if (baud_cfg->rjw > ((baud_cfg->pseg1 < baud_cfg->pseg2) ? baud_cfg->pseg1 : baud_cfg->pseg2))
  461. {
  462. CAN_RET_FMT(-RT_EINVAL, "invalid sjw=%lu pseg1=%lu pseg2=%lu",
  463. (unsigned long)baud_cfg->rjw,
  464. (unsigned long)baud_cfg->pseg1,
  465. (unsigned long)baud_cfg->pseg2);
  466. }
  467. if ((clk_hz % (baud * tq_num)) != 0U)
  468. {
  469. CAN_RET_FMT(-RT_EINVAL, "clock not divisible clk=%lu baud=%lu tq=%lu",
  470. (unsigned long)clk_hz, (unsigned long)baud, (unsigned long)tq_num);
  471. }
  472. presdiv = clk_hz / (baud * tq_num);
  473. if ((presdiv == 0U) || (presdiv > 1024U))
  474. {
  475. CAN_RET_FMT(-RT_EINVAL, "invalid presdiv=%lu baud=%lu tq=%lu",
  476. (unsigned long)presdiv, (unsigned long)baud, (unsigned long)tq_num);
  477. }
  478. baud_cfg->presdiv = presdiv;
  479. return RT_EOK;
  480. }
  481. static void s100_can_basic_program_baudrate(struct s100_can_basic *ctrl,
  482. const struct s100_can_basic_baudrate_cfg *baud_cfg)
  483. {
  484. rt_uint32_t ctrl1 = 0U;
  485. rt_uint32_t cbt = 0U;
  486. ctrl1 |= FLEXCAN_CTRL1_ERRMSK(1U);
  487. ctrl1 |= FLEXCAN_CTRL1_BOFFMSK(1U);
  488. if (baud_cfg->loopback != RT_FALSE)
  489. {
  490. ctrl1 |= FLEXCAN_CTRL1_LPB(1U);
  491. }
  492. ctrl->regs->CTRL1 = ctrl1;
  493. cbt |= FLEXCAN_CBT_BTF(1U);
  494. cbt |= FLEXCAN_CBT_EPRESDIV(baud_cfg->presdiv - 1U);
  495. cbt |= FLEXCAN_CBT_ERJW(baud_cfg->rjw - 1U);
  496. cbt |= FLEXCAN_CBT_EPROPSEG(baud_cfg->propseg - 1U);
  497. cbt |= FLEXCAN_CBT_EPSEG1(baud_cfg->pseg1 - 1U);
  498. cbt |= FLEXCAN_CBT_EPSEG2(baud_cfg->pseg2 - 1U);
  499. ctrl->regs->CBT = cbt;
  500. }
  501. static void s100_can_basic_apply_baudrate(struct s100_can_basic *ctrl, const struct can_configure *cfg)
  502. {
  503. struct s100_can_basic_baudrate_cfg baud_cfg;
  504. baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV;
  505. baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG;
  506. baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1;
  507. baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2;
  508. baud_cfg.rjw = S100_CAN_DEFAULT_RJW;
  509. baud_cfg.loopback = ((cfg->mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE;
  510. if (s100_can_basic_calc_baudrate_params(ctrl, cfg, &baud_cfg) != RT_EOK)
  511. {
  512. baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV;
  513. baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG;
  514. baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1;
  515. baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2;
  516. baud_cfg.rjw = S100_CAN_DEFAULT_RJW;
  517. }
  518. s100_can_basic_program_baudrate(ctrl, &baud_cfg);
  519. }
  520. static rt_err_t s100_can_basic_apply_baudrate_runtime(struct s100_can_basic *ctrl, rt_uint32_t baud)
  521. {
  522. struct can_configure cfg;
  523. struct s100_can_basic_baudrate_cfg baud_cfg;
  524. rt_err_t ret;
  525. cfg = ctrl->can_dev.config;
  526. cfg.baud_rate = baud;
  527. baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV;
  528. baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG;
  529. baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1;
  530. baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2;
  531. baud_cfg.rjw = S100_CAN_DEFAULT_RJW;
  532. baud_cfg.loopback = ((cfg.mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE;
  533. ret = s100_can_basic_calc_baudrate_params(ctrl, &cfg, &baud_cfg);
  534. if (ret != RT_EOK)
  535. {
  536. CAN_RET_FMT(ret, "apply baudrate runtime calc params failed baud=%lu", (unsigned long)baud);
  537. }
  538. ret = s100_can_basic_enter_freeze(ctrl->regs);
  539. if (ret != RT_EOK)
  540. {
  541. CAN_RET(ret, "apply baudrate runtime enter freeze failed");
  542. }
  543. s100_can_basic_program_baudrate(ctrl, &baud_cfg);
  544. ret = s100_can_basic_exit_freeze(ctrl->regs);
  545. if (ret != RT_EOK)
  546. {
  547. CAN_RET(ret, "apply baudrate runtime exit freeze failed");
  548. }
  549. return RT_EOK;
  550. }
  551. static rt_err_t s100_can_basic_apply_mode(struct s100_can_basic *ctrl, rt_uint32_t mode)
  552. {
  553. s100_can_regs_t *base = ctrl->regs;
  554. rt_uint32_t mcr;
  555. rt_uint32_t ctrl1;
  556. rt_bool_t loopback;
  557. rt_err_t ret;
  558. loopback = ((mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE;
  559. ret = s100_can_basic_enter_freeze(base);
  560. if (ret != RT_EOK)
  561. {
  562. CAN_RET(ret, "apply mode enter freeze failed");
  563. }
  564. mcr = base->MCR;
  565. mcr &= ~FLEXCAN_MCR_SRXDIS_MASK;
  566. if (loopback == RT_FALSE)
  567. {
  568. mcr |= FLEXCAN_MCR_SRXDIS(1U);
  569. }
  570. base->MCR = mcr;
  571. ctrl1 = base->CTRL1;
  572. ctrl1 &= ~FLEXCAN_CTRL1_LPB_MASK;
  573. if (loopback != RT_FALSE)
  574. {
  575. ctrl1 |= FLEXCAN_CTRL1_LPB(1U);
  576. }
  577. base->CTRL1 = ctrl1;
  578. ret = s100_can_basic_exit_freeze(base);
  579. if (ret != RT_EOK)
  580. {
  581. CAN_RET(ret, "apply mode exit freeze failed");
  582. }
  583. return RT_EOK;
  584. }
  585. static inline void s100_can_setclksrc(s100_can_regs_t *base, rt_bool_t enable)
  586. {
  587. base->CTRL1 = (base->CTRL1 & ~FLEXCAN_CTRL1_CLKSRC_MASK) | FLEXCAN_CTRL1_CLKSRC(enable ? 1UL : 0UL);
  588. }
  589. static rt_bool_t s100_can_basic_is_enabled(s100_can_regs_t *base)
  590. {
  591. return (((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT) != 0U) ? RT_FALSE : RT_TRUE;
  592. }
  593. static rt_err_t s100_can_basic_init(struct s100_can_basic *ctrl, struct can_configure *cfg)
  594. {
  595. rt_uint32_t mcr;
  596. rt_err_t ret;
  597. s100_can_regs_t *base = ctrl->regs;
  598. rt_bool_t loopback;
  599. if (s100_can_basic_is_enabled(base) != RT_FALSE)
  600. {
  601. ret = s100_can_basic_enter_freeze(base);
  602. if (ret != RT_EOK)
  603. {
  604. CAN_RET(ret, "init enter freeze before stop failed");
  605. }
  606. ret = s100_can_basic_stop(base);
  607. if (ret != RT_EOK)
  608. {
  609. CAN_RET(ret, "init stop failed");
  610. }
  611. }
  612. s100_can_setclksrc(base, RT_FALSE);
  613. base->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
  614. ret = s100_can_basic_soft_reset(base);
  615. if (ret != RT_EOK)
  616. {
  617. CAN_RET(ret, "init soft reset failed");
  618. }
  619. ret = s100_can_basic_enter_freeze(base);
  620. if (ret != RT_EOK)
  621. {
  622. CAN_RET(ret, "init enter freeze failed");
  623. }
  624. mcr = base->MCR;
  625. mcr &= ~(FLEXCAN_MCR_MAXMB_MASK | FLEXCAN_MCR_SRXDIS_MASK);
  626. mcr |= FLEXCAN_MCR_AEN(1U);
  627. mcr |= FLEXCAN_MCR_IRMQ(1U);
  628. mcr |= FLEXCAN_MCR_WRNEN(1U);
  629. mcr |= FLEXCAN_MCR_MAXMB(S100_CAN_MAX_MB_INDEX);
  630. loopback = ((cfg->mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE;
  631. if (loopback == RT_FALSE)
  632. {
  633. mcr |= FLEXCAN_MCR_SRXDIS(1U);
  634. }
  635. base->MCR = mcr;
  636. s100_can_basic_set_mem_error_detection(base, 0U);
  637. s100_can_basic_init_flexcan_ram(base);
  638. s100_can_basic_apply_baudrate(ctrl, cfg);
  639. base->IMASK1 = 0U;
  640. base->IMASK2 = 0U;
  641. base->IFLAG1 = 0xFFFFFFFFU;
  642. base->IFLAG2 = 0xFFFFFFFFU;
  643. base->ESR1 = FLEXCAN_IP_ALL_INT;
  644. s100_can_basic_init_tx_mb(ctrl);
  645. ctrl->state.ehfifo_enabled = 0U;
  646. ret = s100_can_basic_init_ehrxfifo(ctrl, 2U, 0U, 1U);
  647. if (ret != RT_EOK)
  648. {
  649. CAN_RET(ret, "init ehrxfifo failed");
  650. }
  651. ctrl->state.ehfifo_enabled = 1U;
  652. ctrl->state.tx_done = 0U;
  653. ret = s100_can_basic_exit_freeze(base);
  654. if (ret != RT_EOK)
  655. {
  656. CAN_RET(ret, "init exit freeze failed");
  657. }
  658. ret = s100_can_basic_wait_ready(base);
  659. if (ret != RT_EOK)
  660. {
  661. CAN_RET(ret, "init wait ready failed");
  662. }
  663. return RT_EOK;
  664. }
  665. static rt_err_t s100_can_basic_send_std(struct s100_can_basic *ctrl, rt_uint32_t std_id,
  666. const rt_uint8_t *data, rt_uint8_t len, rt_uint32_t boxno)
  667. {
  668. s100_can_mb_t *mb;
  669. rt_uint32_t tx_bit;
  670. rt_uint32_t data0 = 0U;
  671. rt_uint32_t data1 = 0U;
  672. rt_uint32_t code;
  673. rt_uint32_t i;
  674. if ((data == RT_NULL) || (len > 8U) || (std_id > S100_CAN_STD_ID_MASK))
  675. {
  676. CAN_RET_FMT(-RT_EINVAL, "send std invalid args id=0x%lx len=%lu",
  677. (unsigned long)std_id, (unsigned long)len);
  678. }
  679. if (boxno >= ctrl->can_dev.config.sndboxnumber)
  680. {
  681. CAN_RET_FMT(-RT_EINVAL, "send std invalid boxno=%lu sndboxnumber=%lu",
  682. (unsigned long)boxno, (unsigned long)ctrl->can_dev.config.sndboxnumber);
  683. }
  684. mb = s100_can_basic_mb(ctrl->regs, s100_can_basic_tx_box_to_mb(boxno));
  685. code = (mb->cs >> S100_CAN_MB_CODE_SHIFT) & 0x0FU;
  686. if (code != S100_CAN_MB_CODE_TX_INACTIVE)
  687. {
  688. CAN_RET_FMT(-RT_EBUSY, "send std mailbox busy boxno=%lu code=0x%lx",
  689. (unsigned long)boxno, (unsigned long)code);
  690. }
  691. for (i = 0U; i < 4U; i++)
  692. {
  693. data0 <<= 8;
  694. if (i < len)
  695. {
  696. data0 |= data[i];
  697. }
  698. }
  699. for (i = 4U; i < 8U; i++)
  700. {
  701. data1 <<= 8;
  702. if (i < len)
  703. {
  704. data1 |= data[i];
  705. }
  706. }
  707. ctrl->state.tx_done = 0U;
  708. mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_INACTIVE, 0U, RT_FALSE, RT_FALSE);
  709. mb->id = 0U;
  710. mb->data0 = data0;
  711. mb->data1 = data1;
  712. mb->id = (std_id & S100_CAN_STD_ID_MASK) << S100_CAN_STD_ID_SHIFT;
  713. mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_DATA, len, RT_FALSE, RT_FALSE);
  714. return RT_EOK;
  715. }
  716. static void s100_can_basic_handle_tx_irq_bank(struct s100_can_basic *ctrl,
  717. volatile rt_uint32_t *iflag_reg,
  718. rt_uint32_t imask,
  719. rt_uint32_t mb_base)
  720. {
  721. rt_uint32_t pending;
  722. rt_uint32_t bit;
  723. rt_uint32_t mb_id;
  724. pending = (*iflag_reg) & imask;
  725. while (pending != 0U)
  726. {
  727. bit = pending & (~pending + 1U);
  728. mb_id = mb_base + (rt_uint32_t)__builtin_ctz(bit);
  729. (void)ctrl->regs->TIMER;
  730. *iflag_reg = bit;
  731. if ((mb_id >= S100_CAN_BASIC_TX_MB_START) &&
  732. (mb_id < S100_CAN_MAX_MB_INDEX))
  733. {
  734. ctrl->state.tx_done = 1U;
  735. if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_TX) != 0U)
  736. {
  737. rt_hw_can_isr(&ctrl->can_dev,
  738. RT_CAN_EVENT_TX_DONE | ((mb_id - S100_CAN_BASIC_TX_MB_START) << 8));
  739. }
  740. }
  741. pending &= ~bit;
  742. }
  743. }
  744. static void s100_can_basic_handle_ehrxfifo_irq(struct s100_can_basic *ctrl)
  745. {
  746. rt_uint32_t erf_pending;
  747. struct s100_can_basic_frame frame;
  748. rt_size_t wr_len;
  749. if ((ctrl == RT_NULL) || (ctrl->state.ehfifo_enabled == 0U))
  750. {
  751. return;
  752. }
  753. erf_pending = ctrl->regs->ERFSR & ctrl->regs->ERFIER;
  754. while ((erf_pending & FLEXCAN_ERFSR_ERFDA_MASK) != 0U)
  755. {
  756. s100_can_basic_read_ehrxfifo(ctrl, &frame);
  757. wr_len = rt_ringbuffer_put(&ctrl->state.rx_rb,
  758. (const rt_uint8_t *)&frame,
  759. sizeof(frame));
  760. if (wr_len != sizeof(frame))
  761. {
  762. ctrl->state.rx_overrun++;
  763. if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U)
  764. {
  765. rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RXOF_IND | (1U << 8));
  766. }
  767. }
  768. else
  769. {
  770. if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U)
  771. {
  772. rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RX_IND | (1U << 8));
  773. }
  774. }
  775. ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFDA_MASK;
  776. erf_pending = ctrl->regs->ERFSR & ctrl->regs->ERFIER;
  777. }
  778. if ((erf_pending & FLEXCAN_ERFSR_ERFOVF_MASK) != 0U)
  779. {
  780. ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFOVF_MASK;
  781. if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U)
  782. {
  783. rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RXOF_IND | (1U << 8));
  784. }
  785. }
  786. if ((erf_pending & FLEXCAN_ERFSR_ERFUFW_MASK) != 0U)
  787. {
  788. ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFUFW_MASK;
  789. }
  790. }
  791. static void s100_can_basic_irq_handler(int vector, void *param)
  792. {
  793. struct s100_can_basic *ctrl;
  794. RT_UNUSED(vector);
  795. ctrl = (struct s100_can_basic *)param;
  796. if (ctrl == RT_NULL)
  797. {
  798. return;
  799. }
  800. s100_can_basic_handle_tx_irq_bank(ctrl, &ctrl->regs->IFLAG1, ctrl->regs->IMASK1, 0U);
  801. s100_can_basic_handle_tx_irq_bank(ctrl, &ctrl->regs->IFLAG2, ctrl->regs->IMASK2, 32U);
  802. if (ctrl->state.ehfifo_enabled != 0U)
  803. {
  804. s100_can_basic_handle_ehrxfifo_irq(ctrl);
  805. }
  806. if ((ctrl->regs->ESR1 & (FLEXCAN_ESR1_ERRINT_MASK |
  807. FLEXCAN_ESR1_BOFFINT_MASK |
  808. FLEXCAN_ESR1_ACKERR_MASK)) != 0U)
  809. {
  810. ctrl->regs->ESR1 = FLEXCAN_IP_ALL_INT;
  811. if ((ctrl->irq_mask_flags & RT_DEVICE_CAN_INT_ERR) != 0U)
  812. {
  813. rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_TX_FAIL | (0U << 8));
  814. }
  815. }
  816. }
  817. static rt_err_t s100_can_basic_configure(struct rt_can_device *can, struct can_configure *cfg)
  818. {
  819. struct s100_can_basic *ctrl;
  820. rt_err_t ret;
  821. RT_ASSERT(can != RT_NULL);
  822. RT_ASSERT(cfg != RT_NULL);
  823. if (cfg->sndboxnumber == 0U)
  824. {
  825. CAN_RET(-RT_EINVAL, "configure invalid sndboxnumber=0");
  826. }
  827. /* TODO legacy RXFIFO 0-S100_CAN_MAX_MB_INDEX */
  828. if (cfg->sndboxnumber > S100_CAN_MAX_MB_INDEX - S100_CAN_BASIC_TX_MB_START)
  829. {
  830. CAN_RET_FMT(-RT_EINVAL, "configure sndboxnumber too large=%lu",
  831. (unsigned long)cfg->sndboxnumber);
  832. }
  833. if (cfg->msgboxsz == 0U)
  834. {
  835. CAN_RET(-RT_EINVAL, "configure invalid msgboxsz=0");
  836. }
  837. ctrl = (struct s100_can_basic *)can->parent.user_data;
  838. if (ctrl == RT_NULL)
  839. {
  840. CAN_RET(-RT_EINVAL, "configure null ctrl");
  841. }
  842. rt_ringbuffer_init(&ctrl->state.rx_rb,
  843. ctrl->state.rx_rb_pool,
  844. sizeof(ctrl->state.rx_rb_pool));
  845. ctrl->state.rx_overrun = 0U;
  846. ret = s100_can_basic_init(ctrl,cfg);
  847. if (ret != RT_EOK)
  848. {
  849. CAN_RET_FMT(ret, "configure init failed ctrl=%s", ctrl->name);
  850. }
  851. return RT_EOK;
  852. }
  853. static rt_err_t s100_can_basic_control(struct rt_can_device *can, int cmd, void *arg)
  854. {
  855. struct s100_can_basic *ctrl;
  856. RT_ASSERT(can != RT_NULL);
  857. ctrl = (struct s100_can_basic *)can->parent.user_data;
  858. if (ctrl == RT_NULL)
  859. {
  860. CAN_RET(-RT_EINVAL, "control null ctrl");
  861. }
  862. switch (cmd)
  863. {
  864. case RT_DEVICE_CTRL_SET_INT:
  865. {
  866. rt_uint32_t flags = (rt_uint32_t)(rt_uintptr_t)arg;
  867. ctrl->irq_mask_flags |= flags;
  868. s100_can_basic_update_irq_mask(ctrl, flags, RT_TRUE);
  869. return RT_EOK;
  870. }
  871. case RT_DEVICE_CTRL_CLR_INT:
  872. {
  873. rt_uint32_t flags = (rt_uint32_t)(rt_uintptr_t)arg;
  874. ctrl->irq_mask_flags &= ~flags;
  875. s100_can_basic_update_irq_mask(ctrl, flags, RT_FALSE);
  876. return RT_EOK;
  877. }
  878. case RT_CAN_CMD_SET_BAUD:
  879. {
  880. rt_uint32_t new_baud = (rt_uint32_t)(rt_uintptr_t)arg;
  881. rt_err_t ret;
  882. ret = s100_can_basic_apply_baudrate_runtime(ctrl, new_baud);
  883. if (ret == RT_EOK)
  884. {
  885. can->config.baud_rate = new_baud;
  886. }
  887. if (ret != RT_EOK)
  888. {
  889. CAN_RET_FMT(ret, "control set baud failed ctrl=%s baud=%lu",
  890. ctrl->name, (unsigned long)new_baud);
  891. }
  892. return RT_EOK;
  893. }
  894. case RT_CAN_CMD_SET_MODE:
  895. {
  896. rt_uint32_t new_mode = (rt_uint32_t)(rt_uintptr_t)arg;
  897. rt_err_t ret;
  898. ret = s100_can_basic_apply_mode(ctrl, new_mode);
  899. if (ret == RT_EOK)
  900. {
  901. can->config.mode = new_mode;
  902. }
  903. if (ret != RT_EOK)
  904. {
  905. CAN_RET_FMT(ret, "control set mode failed ctrl=%s mode=%lu",
  906. ctrl->name, (unsigned long)new_mode);
  907. }
  908. return RT_EOK;
  909. }
  910. case RT_CAN_CMD_SET_PRIV:
  911. can->config.privmode = (rt_uint32_t)(rt_uintptr_t)arg;
  912. return RT_EOK;
  913. case RT_CAN_CMD_GET_STATUS:
  914. if (arg == RT_NULL)
  915. {
  916. CAN_RET(-RT_EINVAL, "control get status null arg");
  917. }
  918. can->status.snderrcnt = ctrl->regs->ECR & 0xFFU;
  919. can->status.rcverrcnt = (ctrl->regs->ECR >> 8U) & 0xFFU;
  920. can->status.errcode = ((ctrl->regs->ESR1 & FLEXCAN_ESR1_BOFFINT_MASK) != 0U) ? BUSOFF : NORMAL;
  921. rt_memcpy(arg, &can->status, sizeof(can->status));
  922. return RT_EOK;
  923. case RT_CAN_CMD_START:
  924. {
  925. rt_uint32_t next_status = (rt_uint32_t)(rt_uintptr_t)arg;
  926. if(next_status == RT_FALSE)
  927. {
  928. if(s100_can_basic_is_enabled(ctrl->regs))
  929. {
  930. return s100_can_basic_stop(ctrl->regs);
  931. }
  932. }
  933. return RT_EOK;
  934. }
  935. default:
  936. CAN_RET_FMT(-RT_EINVAL, "control unsupported cmd=%d ctrl=%s", cmd, ctrl->name);
  937. }
  938. return RT_EOK;
  939. }
  940. static rt_ssize_t s100_can_basic_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  941. {
  942. struct s100_can_basic *ctrl;
  943. const struct rt_can_msg *msg;
  944. rt_uint32_t retry;
  945. RT_ASSERT(can != RT_NULL);
  946. ctrl = (struct s100_can_basic *)can->parent.user_data;
  947. msg = (const struct rt_can_msg *)buf;
  948. if ((ctrl == RT_NULL) || (msg == RT_NULL))
  949. {
  950. CAN_RET(-RT_EINVAL, "sendmsg null ctrl or msg");
  951. }
  952. if (boxno >= ctrl->can_dev.config.sndboxnumber)
  953. {
  954. CAN_RET_FMT(-RT_EINVAL, "sendmsg invalid boxno=%lu sndboxnumber=%lu",
  955. (unsigned long)boxno, (unsigned long)ctrl->can_dev.config.sndboxnumber);
  956. }
  957. if ((msg->ide != RT_CAN_STDID) || (msg->rtr != RT_CAN_DTR))
  958. {
  959. CAN_RET_FMT(-RT_ENOSYS, "sendmsg unsupported frame ide=%lu rtr=%lu",
  960. (unsigned long)msg->ide, (unsigned long)msg->rtr);
  961. }
  962. return s100_can_basic_send_std(ctrl, msg->id, msg->data, (rt_uint8_t)msg->len, boxno);
  963. }
  964. static rt_ssize_t s100_can_basic_sendmsg_nonblocking(struct rt_can_device *can, const void *buf)
  965. {
  966. rt_uint32_t boxno;
  967. rt_ssize_t ret;
  968. for (boxno = 0U; boxno < can->config.sndboxnumber; boxno++)
  969. {
  970. ret = s100_can_basic_sendmsg(can, buf, boxno);
  971. if (ret == RT_EOK)
  972. {
  973. return RT_EOK;
  974. }
  975. if (ret != -RT_EBUSY)
  976. {
  977. CAN_RET_FMT(ret, "sendmsg nonblocking failed boxno=%lu", (unsigned long)boxno);
  978. }
  979. }
  980. CAN_RET(-RT_EBUSY, "sendmsg nonblocking all mailboxes busy");
  981. }
  982. static rt_ssize_t s100_can_basic_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
  983. {
  984. struct s100_can_basic *ctrl;
  985. struct rt_can_msg *msg;
  986. struct s100_can_basic_frame frame;
  987. rt_uint32_t data_word;
  988. rt_uint32_t i;
  989. rt_size_t rd_len;
  990. rt_base_t level;
  991. RT_ASSERT(can != RT_NULL);
  992. ctrl = (struct s100_can_basic *)can->parent.user_data;
  993. msg = (struct rt_can_msg *)buf;
  994. if ((ctrl == RT_NULL) || (msg == RT_NULL) || (fifo == 0U))
  995. {
  996. CAN_RET_FMT(-RT_EINVAL, "recvmsg invalid args ctrl=%p msg=%p fifo=%lu",
  997. ctrl, msg, (unsigned long)fifo);
  998. }
  999. level = rt_hw_interrupt_disable();
  1000. rd_len = rt_ringbuffer_get(&ctrl->state.rx_rb,
  1001. (rt_uint8_t *)&frame,
  1002. sizeof(frame));
  1003. rt_hw_interrupt_enable(level);
  1004. if (rd_len != sizeof(frame))
  1005. {
  1006. CAN_RET(-RT_EEMPTY, "recvmsg ringbuffer empty");
  1007. }
  1008. if ((frame.cs & (1UL << 21)) != 0U)
  1009. {
  1010. CAN_RET(-RT_ENOSYS, "recvmsg ext frame unsupported");
  1011. }
  1012. msg->ide = RT_CAN_STDID;
  1013. msg->rtr = ((frame.cs & (1UL << 20)) != 0U) ? RT_CAN_RTR : RT_CAN_DTR;
  1014. msg->id = (frame.id >> S100_CAN_STD_ID_SHIFT) & S100_CAN_STD_ID_MASK;
  1015. msg->len = (frame.cs >> 16U) & 0x0FU;
  1016. if (msg->len > 8U)
  1017. {
  1018. msg->len = 8U;
  1019. }
  1020. #ifdef RT_CAN_USING_HDR
  1021. msg->hdr_index = -1;
  1022. #else
  1023. msg->hdr_index = -1;
  1024. #endif
  1025. msg->rxfifo = 0;
  1026. msg->priv = 0U;
  1027. data_word = frame.data0;
  1028. for (i = 0U; i < 4U; i++)
  1029. {
  1030. msg->data[i] = (rt_uint8_t)((data_word >> (24U - (i * 8U))) & 0xFFU);
  1031. }
  1032. data_word = frame.data1;
  1033. for (i = 0U; i < 4U; i++)
  1034. {
  1035. msg->data[i + 4U] = (rt_uint8_t)((data_word >> (24U - (i * 8U))) & 0xFFU);
  1036. }
  1037. return RT_EOK;
  1038. }
  1039. static const struct rt_can_ops s100_can_basic_ops =
  1040. {
  1041. .configure = s100_can_basic_configure,
  1042. .control = s100_can_basic_control,
  1043. .sendmsg = s100_can_basic_sendmsg,
  1044. .recvmsg = s100_can_basic_recvmsg,
  1045. .sendmsg_nonblocking = s100_can_basic_sendmsg_nonblocking,
  1046. };
  1047. static void s100_can_enable_all_clocks_once(void)
  1048. {
  1049. volatile rt_uint32_t *reg = (volatile rt_uint32_t *)S100_CAN_CLK_WORKAROUND_BASE;
  1050. rt_uint32_t i;
  1051. for (i = 0U; i < S100_CAN_CLK_WORKAROUND_COUNT; i++)
  1052. {
  1053. reg[i] = S100_CAN_CLK_WORKAROUND_ENABLE;
  1054. }
  1055. __DSB();
  1056. }
  1057. void s100_can_board_enable_transceiver(void)
  1058. {
  1059. /* Equivalent to Dio_WriteChannel(MCU2CAN_STB_N, STD_LOW). */
  1060. s100_gpio_write(S100_MCU2CAN_STB_N_PIN, 0U);
  1061. }
  1062. #define CAN_DEV_SND_BOX_MAX 32U
  1063. int rt_hw_can_init(void)
  1064. {
  1065. rt_size_t i;
  1066. rt_err_t ret;
  1067. struct can_configure cfg = CANDEFAULTCONFIG;
  1068. cfg.privmode = RT_CAN_MODE_NOPRIV;
  1069. cfg.ticks = 50U;
  1070. if (cfg.sndboxnumber > CAN_DEV_SND_BOX_MAX)
  1071. {
  1072. rt_uint32_t requested = cfg.sndboxnumber;
  1073. cfg.sndboxnumber = CAN_DEV_SND_BOX_MAX;
  1074. LOG_W("sndboxnumber=%lu exceeds max, capped to %lu",
  1075. (unsigned long)requested,
  1076. (unsigned long)cfg.sndboxnumber);
  1077. }
  1078. #ifdef RT_CAN_USING_HDR
  1079. cfg.maxhdr = 1U;
  1080. #endif
  1081. s100_can_enable_all_clocks_once();
  1082. s100_can_board_enable_transceiver();
  1083. for (i = 0U; i < (sizeof(s100_can_basics) / sizeof(s100_can_basics[0])); i++)
  1084. {
  1085. s100_can_basics[i].can_dev.config = cfg;
  1086. s100_can_basics[i].can_dev.parent.user_data = &s100_can_basics[i];
  1087. ret = rt_hw_can_register(&s100_can_basics[i].can_dev,
  1088. s100_can_basics[i].name,
  1089. &s100_can_basic_ops,
  1090. &s100_can_basics[i]);
  1091. if (ret != RT_EOK)
  1092. {
  1093. CAN_RET_FMT(ret, "rt_hw_can_register failed ctrl=%s", s100_can_basics[i].name);
  1094. }
  1095. if (s100_can_basics[i].irq_inited == 0U)
  1096. {
  1097. rt_hw_interrupt_install(s100_can_basics[i].irqno,
  1098. s100_can_basic_irq_handler,
  1099. &s100_can_basics[i],
  1100. s100_can_basics[i].name);
  1101. rt_hw_interrupt_set_target_cpus(s100_can_basics[i].irqno, 0U);
  1102. rt_hw_interrupt_umask(s100_can_basics[i].irqno);
  1103. s100_can_basics[i].irq_inited = 1U;
  1104. }
  1105. }
  1106. return RT_EOK;
  1107. }
  1108. INIT_DEVICE_EXPORT(rt_hw_can_init);