test.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-07-15 Emuzit first version
  9. * 2022-07-20 Emuzit add watchdog test
  10. * 2022-07-26 Emuzit add hwtimer test
  11. * 2022-07-30 Emuzit add spi master test
  12. * 2022-08-04 Emuzit add pwm test
  13. */
  14. #include <rtthread.h>
  15. #include <rtdebug.h>
  16. #include <drivers/pin.h>
  17. #include <drivers/watchdog.h>
  18. #include <drivers/hwtimer.h>
  19. #include <drivers/spi.h>
  20. #include <drivers/rt_drv_pwm.h>
  21. #include "board.h"
  22. #define PWM_CYCLE_MAX 255
  23. static const rt_base_t gpio_int_pins[8] = GPIO_INT_PINS;
  24. /* note : PIN_IRQ_MODE_RISING_FALLING not supported */
  25. static const uint32_t gpint_mode[] =
  26. {
  27. PIN_IRQ_MODE_RISING,
  28. PIN_IRQ_MODE_RISING,
  29. PIN_IRQ_MODE_RISING,
  30. PIN_IRQ_MODE_RISING,
  31. PIN_IRQ_MODE_FALLING,
  32. PIN_IRQ_MODE_FALLING,
  33. PIN_IRQ_MODE_FALLING,
  34. PIN_IRQ_MODE_FALLING,
  35. };
  36. static struct rt_mailbox *gpint_mb = RT_NULL;
  37. static struct rt_thread *gpint_thread = RT_NULL;
  38. static rt_device_t wdg_dev;
  39. static rt_base_t led0, led1;
  40. static void gpio_int_callback(void *pin)
  41. {
  42. led1 = (led1 == PIN_LOW) ? PIN_HIGH : PIN_LOW;
  43. rt_pin_write(LED1_PIN, led1);
  44. if (gpint_mb != RT_NULL)
  45. {
  46. /* non-block, silently ignore RT_EFULL */
  47. rt_mb_send(gpint_mb, (uint32_t)pin);
  48. }
  49. }
  50. static void gpio_int_thread(void *param)
  51. {
  52. while (1)
  53. {
  54. rt_err_t res;
  55. uint32_t pin;
  56. res = rt_mb_recv(gpint_mb, &pin, RT_WAITING_FOREVER);
  57. if (res == RT_EOK)
  58. {
  59. rt_kprintf("gpio_int #%d (%d)\n", pin, rt_pin_read(pin));
  60. }
  61. rt_thread_mdelay(100);
  62. #ifdef RT_USING_WDT
  63. rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, RT_NULL);
  64. #endif
  65. }
  66. }
  67. static void test_gpio_int(void)
  68. {
  69. rt_err_t res;
  70. int i;
  71. rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
  72. rt_pin_write(LED1_PIN, led1 = PIN_HIGH);
  73. /* Enable all gpio interrupt with various modes.
  74. * LED0 or GND touching can be used to trigger pin interrupt.
  75. */
  76. gpint_mb = rt_mb_create("pximb", 8, RT_IPC_FLAG_FIFO);
  77. if (gpint_mb == RT_NULL)
  78. {
  79. rt_kprintf("gpint mailbox create failed !\n");
  80. }
  81. else
  82. {
  83. gpint_thread = rt_thread_create("pxith", gpio_int_thread, RT_NULL,
  84. 512, RT_MAIN_THREAD_PRIORITY, 50);
  85. if (gpint_thread == RT_NULL)
  86. {
  87. rt_kprintf("gpint thread create failed !\n");
  88. }
  89. else
  90. {
  91. rt_thread_startup(gpint_thread);
  92. for (i = 0; i < 8; i++)
  93. {
  94. rt_base_t pin = gpio_int_pins[i];
  95. #ifdef RT_USING_PWM
  96. if (pin == PWM0_PIN || pin == PWM1_PIN)
  97. continue;
  98. #endif
  99. rt_pin_mode(pin, PIN_MODE_INPUT_PULLUP);
  100. res = rt_pin_attach_irq(
  101. pin, gpint_mode[i], gpio_int_callback, (void *)pin);
  102. if (res != RT_EOK)
  103. {
  104. rt_kprintf("rt_pin_attach_irq failed (%d:%d)\n", i, res);
  105. }
  106. else
  107. {
  108. rt_pin_irq_enable(pin, PIN_IRQ_ENABLE);
  109. }
  110. }
  111. }
  112. }
  113. }
  114. #ifdef RT_USING_WDT
  115. static void test_watchdog(uint32_t seconds)
  116. {
  117. /* Test watchdog with 30s timeout, keepalive with gpio interrupt.
  118. *
  119. * CAVEAT: With only 8-bit WDOG_COUNT and fixed clocking at Fsys/524288,
  120. * watchdog of ch56x may be quite limited with very short timeout.
  121. */
  122. seconds = 30;
  123. wdg_dev = rt_device_find("wdt");
  124. if (!wdg_dev)
  125. {
  126. rt_kprintf("watchdog device not found !\n");
  127. }
  128. else if (rt_device_init(wdg_dev) != RT_EOK ||
  129. rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &seconds) != RT_EOK)
  130. {
  131. rt_kprintf("watchdog setup failed !\n");
  132. }
  133. else
  134. {
  135. rt_kprintf("WDT_TIMEOUT in %d seconds, trigger gpio interrupt to keep alive.\n\n", seconds);
  136. }
  137. }
  138. #else
  139. #define test_watchdog(tov) do {} while(0)
  140. #endif
  141. #ifdef RT_USING_HWTIMER
  142. static struct rt_device *tmr_dev_0;
  143. static struct rt_device *tmr_dev_1;
  144. static rt_err_t tmr_timeout_cb(rt_device_t dev, rt_size_t size)
  145. {
  146. rt_tick_t tick = rt_tick_get();
  147. int tmr = (dev == tmr_dev_1) ? 1 : 0;
  148. rt_kprintf("hwtimer %d timeout callback fucntion @tick %d\n", tmr, tick);
  149. return RT_EOK;
  150. }
  151. static void test_hwtimer(void)
  152. {
  153. rt_hwtimerval_t timerval;
  154. rt_hwtimer_mode_t mode;
  155. rt_size_t tsize;
  156. /* setup two timers, ONESHOT & PERIOD each
  157. */
  158. tmr_dev_0 = rt_device_find("timer0");
  159. tmr_dev_1 = rt_device_find("timer1");
  160. if (tmr_dev_0 == RT_NULL || tmr_dev_1 == RT_NULL)
  161. {
  162. rt_kprintf("hwtimer device(s) not found !\n");
  163. }
  164. else if (rt_device_open(tmr_dev_0, RT_DEVICE_OFLAG_RDWR) != RT_EOK ||
  165. rt_device_open(tmr_dev_1, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
  166. {
  167. rt_kprintf("hwtimer device(s) open failed !\n");
  168. }
  169. else
  170. {
  171. rt_device_set_rx_indicate(tmr_dev_0, tmr_timeout_cb);
  172. rt_device_set_rx_indicate(tmr_dev_1, tmr_timeout_cb);
  173. timerval.sec = 3;
  174. timerval.usec = 500000;
  175. tsize = sizeof(timerval);
  176. mode = HWTIMER_MODE_ONESHOT;
  177. if (rt_device_control(tmr_dev_0, HWTIMER_CTRL_MODE_SET, &mode) != RT_EOK)
  178. {
  179. rt_kprintf("timer0 set mode failed !\n");
  180. }
  181. else if (rt_device_write(tmr_dev_0, 0, &timerval, tsize) != tsize)
  182. {
  183. rt_kprintf("timer0 start failed !\n");
  184. }
  185. else
  186. {
  187. rt_kprintf("timer0 started !\n");
  188. }
  189. timerval.sec = 5;
  190. timerval.usec = 0;
  191. tsize = sizeof(timerval);
  192. mode = HWTIMER_MODE_PERIOD;
  193. if (rt_device_control(tmr_dev_1, HWTIMER_CTRL_MODE_SET, &mode) != RT_EOK)
  194. {
  195. rt_kprintf("timer1 set mode failed !\n");
  196. }
  197. else if (rt_device_write(tmr_dev_1, 0, &timerval, tsize) != tsize)
  198. {
  199. rt_kprintf("timer1 start failed !\n");
  200. }
  201. else
  202. {
  203. rt_kprintf("timer1 started !\n\n");
  204. }
  205. }
  206. }
  207. #else
  208. #define test_hwtimer() do {} while(0)
  209. #endif
  210. #ifdef RT_USING_SPI
  211. static struct rt_spi_device spi_dev_w25q;
  212. static void test_spi_master(void)
  213. {
  214. struct rt_spi_configuration cfg;
  215. struct rt_spi_message msg1, msg2;
  216. rt_err_t res;
  217. uint8_t buf[16];
  218. int i;
  219. cfg.max_hz = 25 * 1000000;
  220. cfg.data_width = 8;
  221. cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
  222. res = rt_spi_bus_attach_device(
  223. &spi_dev_w25q, W25Q32_SPI_NAME, SPI0_BUS_NAME, (void *)W25Q32_CS_PIN);
  224. if (res == RT_EOK && rt_spi_configure(&spi_dev_w25q, &cfg) == RT_EOK)
  225. {
  226. /* cmd : Read Manufacturer / Device ID (90h) */
  227. buf[0] = 0x90;
  228. /* address : 0 */
  229. buf[1] = buf[2] = buf[3] = 0;
  230. msg1.send_buf = buf;
  231. msg1.recv_buf = RT_NULL;
  232. msg1.length = 4;
  233. msg1.cs_take = 1;
  234. msg1.cs_release = 0;
  235. msg1.next = &msg2;
  236. msg2.send_buf = RT_NULL;
  237. msg2.recv_buf = buf;
  238. msg2.length = 2;
  239. msg2.cs_take = 0;
  240. msg2.cs_release = 1;
  241. msg2.next = RT_NULL;
  242. rt_spi_transfer_message(&spi_dev_w25q, &msg1);
  243. rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", buf[0], buf[1]);
  244. /* cmd : Read Data (03h) */
  245. buf[0] = 0x03;
  246. /* address : 0 */
  247. buf[1] = buf[2] = buf[3] = 0;
  248. msg2.length = 16;
  249. if (rt_spi_transfer_message(&spi_dev_w25q, &msg1) == RT_NULL)
  250. {
  251. rt_kprintf("SPI0 16-byte DMA read :");
  252. for (i = 0; i < 16; i++)
  253. rt_kprintf(" %02x", buf[i]);
  254. rt_kprintf("\n\n");
  255. }
  256. }
  257. else
  258. {
  259. rt_kprintf("w25q32 attach/configure failed (%d) !\n", res);
  260. }
  261. }
  262. #else
  263. #define test_spi_master() do {} while(0)
  264. #endif
  265. #ifdef RT_USING_PWM
  266. static struct rt_device_pwm *pwm_dev;
  267. static uint32_t pwm_period;
  268. rt_err_t rt_pwm_get(struct rt_device_pwm *device,
  269. struct rt_pwm_configuration *cfg);
  270. static void pwm_tick_hook(void)
  271. {
  272. uint32_t pulse;
  273. if (pwm_dev)
  274. {
  275. /* PWM.CH3 duty cycle : 0%->100% for every ~2.5 seconds */
  276. pulse = (rt_tick_get() >> 1) % (PWM_CYCLE_MAX + 1);
  277. pulse = (pwm_period * pulse + PWM_CYCLE_MAX/2) / PWM_CYCLE_MAX;
  278. rt_pwm_set_pulse(pwm_dev, 3, pulse);
  279. }
  280. }
  281. static void test_pwm(void)
  282. {
  283. struct rt_pwm_configuration cfg;
  284. uint32_t pulse[4];
  285. int ch;
  286. pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEVICE_NAME);
  287. if (pwm_dev == RT_NULL)
  288. {
  289. rt_kprintf("can't find %s device !\n", PWM_DEVICE_NAME);
  290. }
  291. else
  292. {
  293. /* for HCLK@80MHz, allowed period is 3187 ~ 812812 */
  294. pwm_period = 800*1000;
  295. pulse[0] = 100*1000;
  296. pulse[1] = 400*1000;
  297. pulse[2] = 600*1000;
  298. pulse[3] = 0;
  299. for (ch = 0; ch < PWM_CHANNELS; ch++)
  300. {
  301. rt_pwm_set(pwm_dev, ch, pwm_period, pulse[ch]);
  302. rt_pwm_enable(pwm_dev, ch);
  303. cfg.channel = ch;
  304. rt_pwm_get(pwm_dev, &cfg);
  305. rt_kprintf("pwm%d period set/get : %d/%d\n", ch, pwm_period, cfg.period);
  306. rt_kprintf("pwm%d pulse set/get : %d/%d\n\n", ch, pulse[ch], cfg.pulse);
  307. }
  308. /* disable PWM.CH0 after 1 second, also start changing CH3 */
  309. rt_thread_mdelay(1000);
  310. rt_pwm_disable(pwm_dev, 0);
  311. /* connect PWM3 (PB.2) to LED2 for a visualized PWM effect */
  312. rt_pin_mode(LED2_PIN, PIN_MODE_INPUT);
  313. rt_tick_sethook(pwm_tick_hook);
  314. }
  315. }
  316. #else
  317. #define test_pwm() do {} while(0)
  318. #endif
  319. #ifdef RT_USING_USB_DEVICE
  320. #if !defined(RT_USING_EVENT) || !defined(RT_USING_MESSAGEQUEUE)
  321. #error "event flag or message queue IPC not enabled"
  322. #endif
  323. static struct rt_thread *udvcom_thread;
  324. static rt_device_t vcom;
  325. static void usbd_vcom_thread(void *param)
  326. {
  327. char ch;
  328. while (1)
  329. {
  330. while (rt_device_read(vcom, 0, &ch, 1) != 1)
  331. rt_thread_delay(1);
  332. rt_kprintf("(%2d) %02x:%c\n", rt_device_write(vcom, 0, &ch, 1), ch, ch);
  333. rt_pin_write(LED1_PIN, (ch & 1) ? PIN_LOW : PIN_HIGH);
  334. }
  335. }
  336. static void test_usbd()
  337. {
  338. char name[] = "vcom";
  339. vcom = rt_device_find(name);
  340. if (vcom && rt_device_open(vcom, RT_DEVICE_FLAG_INT_RX) == RT_EOK)
  341. {
  342. rt_kprintf("%s opened\n", name);
  343. rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
  344. rt_pin_write(LED1_PIN, PIN_LOW);
  345. udvcom_thread = rt_thread_create("udvcom", usbd_vcom_thread, vcom,
  346. 512, 20, 50);
  347. if (udvcom_thread != RT_NULL)
  348. rt_thread_startup(udvcom_thread);
  349. else
  350. rt_kprintf("usvcom thread create failed !\n");
  351. rt_device_write(vcom, 0, name, rt_strlen(name));
  352. }
  353. }
  354. #else
  355. #define test_usbd() do {} while(0)
  356. #endif
  357. void main(void)
  358. {
  359. uint32_t wdog_timeout = 32;
  360. rt_kprintf("\nCH569W-R0-1v0, HCLK: %dMHz\n\n", sys_hclk_get() / 1000000);
  361. test_gpio_int();
  362. test_watchdog(wdog_timeout);
  363. test_hwtimer();
  364. test_spi_master();
  365. test_pwm();
  366. test_usbd();
  367. rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
  368. rt_pin_write(LED0_PIN, led0 = PIN_LOW);
  369. while (1)
  370. {
  371. /* flashing LED0 every 1 second */
  372. rt_thread_mdelay(500);
  373. led0 = (led0 == PIN_LOW) ? PIN_HIGH : PIN_LOW;
  374. rt_pin_write(LED0_PIN, led0);
  375. }
  376. }