led.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <rtthread.h>
  10. #include "board.h"
  11. #define RT_DEVICE_CTRL_RTC_GET_COUNT 0x81 /**< get count */
  12. #define LED_NUM 4
  13. struct fm3_gpio_ctrl
  14. {
  15. uint32_t led_num;
  16. volatile uint32_t * PDOR;
  17. volatile uint32_t * PDIR;
  18. };
  19. struct fm3_led
  20. {
  21. /* inherit from rt_device */
  22. struct rt_device parent;
  23. struct fm3_gpio_ctrl fm3_gpio_ctrl[LED_NUM];
  24. };
  25. static struct fm3_led fm3_led;
  26. static rt_err_t rt_led_init (rt_device_t dev)
  27. {
  28. uint32_t i;
  29. /* led0 : P54 */
  30. FM3_GPIO->PFR5 &= ~((1<<7) | (1<<6) | (1<<5) |(1<<4)); /* set P54 fuction is GPIO. */
  31. FM3_GPIO->DDR5 |= (1<<7) | (1<<6) | (1<<5) |(1<<4); /* set P54 output. */
  32. /* LED0 */
  33. i = 0;
  34. fm3_led.fm3_gpio_ctrl[i].led_num = 4;
  35. fm3_led.fm3_gpio_ctrl[i].PDOR = &FM3_GPIO->PDOR5;
  36. fm3_led.fm3_gpio_ctrl[i].PDIR = &FM3_GPIO->PDIR5;
  37. /* LED1 */
  38. i++;
  39. fm3_led.fm3_gpio_ctrl[i].led_num = 5;
  40. fm3_led.fm3_gpio_ctrl[i].PDOR = &FM3_GPIO->PDOR5;
  41. fm3_led.fm3_gpio_ctrl[i].PDIR = &FM3_GPIO->PDIR5;
  42. /* LED2 */
  43. i++;
  44. fm3_led.fm3_gpio_ctrl[i].led_num = 6;
  45. fm3_led.fm3_gpio_ctrl[i].PDOR = &FM3_GPIO->PDOR5;
  46. fm3_led.fm3_gpio_ctrl[i].PDIR = &FM3_GPIO->PDIR5;
  47. /* LED3 */
  48. i++;
  49. fm3_led.fm3_gpio_ctrl[i].led_num = 7;
  50. fm3_led.fm3_gpio_ctrl[i].PDOR = &FM3_GPIO->PDOR5;
  51. fm3_led.fm3_gpio_ctrl[i].PDIR = &FM3_GPIO->PDIR5;
  52. return RT_EOK;
  53. }
  54. static rt_err_t rt_led_open(rt_device_t dev, rt_uint16_t oflag)
  55. {
  56. return RT_EOK;
  57. }
  58. static rt_err_t rt_led_close(rt_device_t dev)
  59. {
  60. return RT_EOK;
  61. }
  62. static rt_size_t rt_led_read (rt_device_t dev, rt_off_t pos, void* buffer,
  63. rt_size_t size)
  64. {
  65. rt_ubase_t index = 0;
  66. rt_ubase_t nr = size;
  67. rt_uint8_t * value = buffer;
  68. RT_ASSERT(dev == &fm3_led.parent);
  69. RT_ASSERT((pos+size) <= LED_NUM );
  70. for(index=0; index<nr; index++)
  71. {
  72. if(*fm3_led.fm3_gpio_ctrl[pos+index].PDIR & 1<<fm3_led.fm3_gpio_ctrl[pos+index].led_num)
  73. {
  74. *value = 0;
  75. }
  76. else
  77. {
  78. *value = 1;
  79. }
  80. value++;
  81. }
  82. return index;
  83. }
  84. static rt_size_t rt_led_write (rt_device_t dev, rt_off_t pos,
  85. const void* buffer, rt_size_t size)
  86. {
  87. rt_ubase_t index = 0;
  88. rt_ubase_t nw = size;
  89. const rt_uint8_t * value = buffer;
  90. RT_ASSERT(dev == &fm3_led.parent);
  91. RT_ASSERT((pos+size) <= LED_NUM );
  92. for(index=0; index<nw; index++)
  93. {
  94. if(*value++)
  95. {
  96. *fm3_led.fm3_gpio_ctrl[pos+index].PDOR &= ~(1<<fm3_led.fm3_gpio_ctrl[pos+index].led_num);
  97. }
  98. else
  99. {
  100. *fm3_led.fm3_gpio_ctrl[pos+index].PDOR |= (1<<fm3_led.fm3_gpio_ctrl[pos+index].led_num);
  101. }
  102. }
  103. return index;
  104. }
  105. static rt_err_t rt_led_control (rt_device_t dev, int cmd, void *args)
  106. {
  107. RT_ASSERT(dev == &fm3_led.parent);
  108. if(cmd == RT_DEVICE_CTRL_RTC_GET_COUNT)
  109. {
  110. rt_uint32_t * led_num = args;
  111. *led_num = LED_NUM;
  112. }
  113. return RT_EOK;
  114. }
  115. void rt_led_hw_init(void)
  116. {
  117. fm3_led.parent.type = RT_Device_Class_Char;
  118. fm3_led.parent.rx_indicate = RT_NULL;
  119. fm3_led.parent.tx_complete = RT_NULL;
  120. fm3_led.parent.init = rt_led_init;
  121. fm3_led.parent.open = rt_led_open;
  122. fm3_led.parent.close = rt_led_close;
  123. fm3_led.parent.read = rt_led_read;
  124. fm3_led.parent.write = rt_led_write;
  125. fm3_led.parent.control = rt_led_control;
  126. fm3_led.parent.user_data = RT_NULL;
  127. /* register a character device */
  128. rt_device_register(&fm3_led.parent, "led", RT_DEVICE_FLAG_RDWR);
  129. /* init led device */
  130. rt_led_init(&fm3_led.parent);
  131. }
  132. #ifdef RT_USING_FINSH
  133. #include <finsh.h>
  134. void led(rt_uint32_t led, rt_uint32_t value)
  135. {
  136. rt_uint8_t led_value = value;
  137. rt_led_write(&fm3_led.parent, led, &led_value, 1);
  138. }
  139. FINSH_FUNCTION_EXPORT(led, e.g:led(0,100).)
  140. #endif