ledc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // Module for working with the ledc driver
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include "driver/ledc.h"
  6. typedef struct {
  7. int timer;
  8. int channel;
  9. int mode;
  10. } ledc_channel;
  11. static int lledc_new_channel( lua_State *L )
  12. {
  13. int t=1;
  14. luaL_checkanytable (L, t);
  15. /* Setup timer */
  16. ledc_timer_config_t ledc_timer;
  17. lua_getfield(L, t, "bits");
  18. ledc_timer.bit_num = luaL_optint (L, -1, LEDC_TIMER_13_BIT);
  19. if(ledc_timer.bit_num < LEDC_TIMER_10_BIT || ledc_timer.bit_num > LEDC_TIMER_15_BIT)
  20. return luaL_error (L, "bits field out of range");
  21. lua_getfield(L, t, "frequency");
  22. if (lua_type (L, -1) == LUA_TNUMBER) {
  23. ledc_timer.freq_hz = luaL_checkinteger(L, -1);
  24. } else {
  25. return luaL_error(L, "missing or invalid 'frequency' field");
  26. }
  27. lua_getfield(L, t, "mode");
  28. if (lua_type (L, -1) == LUA_TNUMBER) {
  29. ledc_timer.speed_mode = luaL_checkinteger(L, -1);
  30. if(ledc_timer.speed_mode != LEDC_HIGH_SPEED_MODE && ledc_timer.speed_mode != LEDC_LOW_SPEED_MODE)
  31. return luaL_error (L, "Invalid mode");
  32. } else {
  33. return luaL_error(L, "missing or invalid 'mode' field");
  34. }
  35. lua_getfield(L, t, "timer");
  36. if (lua_type (L, -1) == LUA_TNUMBER) {
  37. ledc_timer.timer_num = luaL_checkinteger(L, -1);
  38. if(ledc_timer.timer_num < LEDC_TIMER_0 || ledc_timer.timer_num > LEDC_TIMER_3)
  39. return luaL_error (L, "Invalid timer");
  40. } else {
  41. return luaL_error(L, "missing or invalid 'timer' field");
  42. }
  43. /* Setup channel */
  44. ledc_channel_config_t channel_config = {
  45. .speed_mode = ledc_timer.speed_mode,
  46. .timer_sel = ledc_timer.timer_num,
  47. .intr_type = LEDC_INTR_DISABLE
  48. };
  49. lua_getfield(L, t, "channel");
  50. if (lua_type (L, -1) == LUA_TNUMBER) {
  51. channel_config.channel = luaL_checkinteger(L, -1);
  52. if(channel_config.channel < LEDC_CHANNEL_0 || channel_config.channel > LEDC_CHANNEL_7)
  53. return luaL_error (L, "Invalid channel");
  54. } else {
  55. return luaL_error(L, "missing or invalid 'channel' field");
  56. }
  57. lua_getfield(L, t, "duty");
  58. if (lua_type (L, -1) == LUA_TNUMBER) {
  59. channel_config.duty = luaL_checkinteger(L, -1);
  60. } else {
  61. return luaL_error(L, "missing or invalid 'duty' field");
  62. }
  63. lua_getfield(L, t, "gpio");
  64. if (lua_type (L, -1) == LUA_TNUMBER) {
  65. channel_config.gpio_num = luaL_checkinteger(L, -1);
  66. if(!GPIO_IS_VALID_GPIO(channel_config.gpio_num))
  67. return luaL_error (L, "Invalid gpio");
  68. } else {
  69. return luaL_error(L, "missing or invalid 'gpio' field");
  70. }
  71. esp_err_t timerErr = ledc_timer_config(&ledc_timer);
  72. if(timerErr != ESP_OK)
  73. return luaL_error (L, "timer configuration failed code %d", timerErr);
  74. esp_err_t channelErr = ledc_channel_config(&channel_config);
  75. if(channelErr != ESP_OK)
  76. return luaL_error (L, "channel configuration failed code %d", channelErr);
  77. ledc_channel * channel = (ledc_channel*)lua_newuserdata(L, sizeof(ledc_channel));
  78. luaL_getmetatable(L, "ledc.channel");
  79. lua_setmetatable(L, -2);
  80. channel->mode = ledc_timer.speed_mode;
  81. channel->channel = channel_config.channel;
  82. channel->timer = ledc_timer.timer_num;
  83. return 1;
  84. }
  85. static int lledc_stop( lua_State *L ) {
  86. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  87. int idleLevel = luaL_checkint (L, 2);
  88. luaL_argcheck(L, idleLevel >= 0 && idleLevel <= 1, 1, "Invalid idle level");
  89. esp_err_t err = ledc_stop(channel->mode, channel->channel, idleLevel);
  90. if(err != ESP_OK)
  91. return luaL_error (L, "stop failed, code %d", err);
  92. return 1;
  93. }
  94. static int lledc_set_freq( lua_State *L ) {
  95. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  96. int frequency = luaL_checkint (L, 2);
  97. esp_err_t err = ledc_set_freq(channel->mode, channel->timer, frequency);
  98. if(err != ESP_OK)
  99. return luaL_error (L, "set freq failed, code %d", err);
  100. return 1;
  101. }
  102. static int lledc_get_freq( lua_State *L ) {
  103. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  104. int frequency = ledc_get_freq(channel->mode, channel->timer);
  105. lua_pushinteger (L, frequency);
  106. return 1;
  107. }
  108. static int lledc_set_duty( lua_State *L ) {
  109. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  110. int duty = luaL_checkint (L, 2);
  111. esp_err_t dutyErr = ledc_set_duty(channel->mode, channel->channel, duty);
  112. if(dutyErr != ESP_OK)
  113. return luaL_error (L, "set duty failed, code %d", dutyErr);
  114. esp_err_t updateErr = ledc_update_duty(channel->mode, channel->channel);
  115. if(updateErr != ESP_OK)
  116. return luaL_error (L, "update duty failed, code %d", updateErr);
  117. return 1;
  118. }
  119. static int lledc_get_duty( lua_State *L ) {
  120. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  121. int duty = ledc_get_duty(channel->mode, channel->channel);
  122. lua_pushinteger (L, duty);
  123. return 1;
  124. }
  125. static int lledc_timer_rst( lua_State *L ) {
  126. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  127. esp_err_t err = ledc_timer_rst(channel->mode, channel->timer);
  128. if(err != ESP_OK)
  129. return luaL_error (L, "reset failed, code %d", err);
  130. return 1;
  131. }
  132. static int lledc_timer_pause( lua_State *L ) {
  133. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  134. esp_err_t err = ledc_timer_pause(channel->mode, channel->timer);
  135. if(err != ESP_OK)
  136. return luaL_error (L, "pause failed, code %d", err);
  137. return 1;
  138. }
  139. static int lledc_timer_resume( lua_State *L ) {
  140. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  141. esp_err_t err = ledc_timer_resume(channel->mode, channel->timer);
  142. if(err != ESP_OK)
  143. return luaL_error (L, "resume failed, code %d", err);
  144. return 1;
  145. }
  146. static int lledc_set_fade_with_time( lua_State *L ) {
  147. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  148. int stack = 1;
  149. int targetDuty = luaL_checkint (L, ++stack);
  150. int maxFadeTime = luaL_checkint (L, ++stack);
  151. int wait = luaL_optint (L, ++stack, LEDC_FADE_NO_WAIT);
  152. luaL_argcheck(L, wait == LEDC_FADE_NO_WAIT || wait == LEDC_FADE_WAIT_DONE, stack, "Invalid wait");
  153. ledc_fade_func_install(0);
  154. esp_err_t fadeErr = ledc_set_fade_with_time(channel->mode, channel->channel, targetDuty, maxFadeTime);
  155. if(fadeErr != ESP_OK)
  156. return luaL_error (L, "set fade failed, code %d", fadeErr);
  157. esp_err_t startErr = ledc_fade_start(channel->mode, channel->channel, wait);
  158. if(startErr != ESP_OK)
  159. return luaL_error (L, "start fade failed, code %d", startErr);
  160. return 1;
  161. }
  162. static int lledc_set_fade_with_step( lua_State *L ) {
  163. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  164. int stack = 1;
  165. int targetDuty = luaL_checkint (L, ++stack);
  166. int scale = luaL_checkint (L, ++stack);
  167. int cycleNum = luaL_checkint (L, ++stack);
  168. int wait = luaL_optint (L, ++stack, LEDC_FADE_NO_WAIT);
  169. luaL_argcheck(L, wait == LEDC_FADE_NO_WAIT || wait == LEDC_FADE_WAIT_DONE, stack, "Invalid wait");
  170. ledc_fade_func_install(0);
  171. esp_err_t fadeErr = ledc_set_fade_with_step(channel->mode, channel->channel, targetDuty, scale, cycleNum);
  172. if(fadeErr != ESP_OK)
  173. return luaL_error (L, "set fade failed, code %d", fadeErr);
  174. esp_err_t startErr = ledc_fade_start(channel->mode, channel->channel, wait);
  175. if(startErr != ESP_OK)
  176. return luaL_error (L, "start fade failed, code %d", startErr);
  177. return 1;
  178. }
  179. static int lledc_set_fade( lua_State *L ) {
  180. ledc_channel * channel = (ledc_channel*)luaL_checkudata(L, 1, "ledc.channel");
  181. int stack = 1;
  182. int duty = luaL_checkint (L, ++stack);
  183. int direction = luaL_checkint (L, ++stack);
  184. luaL_argcheck(L, direction == LEDC_DUTY_DIR_DECREASE || direction == LEDC_DUTY_DIR_INCREASE, stack, "Invalid direction");
  185. int scale = luaL_checkint (L, ++stack);
  186. int cycleNum = luaL_checkint (L, ++stack);
  187. int stepNum = luaL_checkint (L, ++stack);;
  188. int wait = luaL_optint (L, ++stack, LEDC_FADE_NO_WAIT);
  189. luaL_argcheck(L, wait == LEDC_FADE_NO_WAIT || wait == LEDC_FADE_WAIT_DONE, stack, "Invalid wait");
  190. ledc_fade_func_install(0);
  191. esp_err_t fadeErr = ledc_set_fade(channel->mode, channel->channel, duty, direction, stepNum, cycleNum, scale);
  192. if(fadeErr != ESP_OK)
  193. return luaL_error (L, "set fade failed, code %d", fadeErr);
  194. esp_err_t startErr = ledc_fade_start(channel->mode, channel->channel, wait);
  195. if(startErr != ESP_OK)
  196. return luaL_error (L, "start fade failed, code %d", startErr);
  197. return 1;
  198. }
  199. // Module function map
  200. static const LUA_REG_TYPE ledc_channel_map[] =
  201. {
  202. { LSTRKEY( "getduty" ), LFUNCVAL( lledc_get_duty ) },
  203. { LSTRKEY( "setduty" ), LFUNCVAL( lledc_set_duty ) },
  204. { LSTRKEY( "getfreq" ), LFUNCVAL( lledc_get_freq ) },
  205. { LSTRKEY( "setfreq" ), LFUNCVAL( lledc_set_freq ) },
  206. { LSTRKEY( "stop" ), LFUNCVAL( lledc_stop ) },
  207. { LSTRKEY( "reset" ), LFUNCVAL( lledc_timer_rst ) },
  208. { LSTRKEY( "pause" ), LFUNCVAL( lledc_timer_pause ) },
  209. { LSTRKEY( "resume" ), LFUNCVAL( lledc_timer_resume ) },
  210. { LSTRKEY( "fadewithtime" ), LFUNCVAL( lledc_set_fade_with_time ) },
  211. { LSTRKEY( "fadewithstep" ), LFUNCVAL( lledc_set_fade_with_step ) },
  212. { LSTRKEY( "fade" ), LFUNCVAL( lledc_set_fade ) },
  213. { LSTRKEY( "__index" ), LROVAL( ledc_channel_map )},
  214. { LNILKEY, LNILVAL }
  215. };
  216. static const LUA_REG_TYPE ledc_map[] =
  217. {
  218. { LSTRKEY( "newChannel" ), LFUNCVAL( lledc_new_channel ) },
  219. { LSTRKEY( "HIGH_SPEED"), LNUMVAL( LEDC_HIGH_SPEED_MODE ) },
  220. { LSTRKEY( "LOW_SPEED"), LNUMVAL( LEDC_LOW_SPEED_MODE ) },
  221. { LSTRKEY( "TIMER_0"), LNUMVAL( LEDC_TIMER_0 ) },
  222. { LSTRKEY( "TIMER_1"), LNUMVAL( LEDC_TIMER_1 ) },
  223. { LSTRKEY( "TIMER_2"), LNUMVAL( LEDC_TIMER_2 ) },
  224. { LSTRKEY( "TIMER_10_BIT"), LNUMVAL( LEDC_TIMER_10_BIT ) },
  225. { LSTRKEY( "TIMER_11_BIT"), LNUMVAL( LEDC_TIMER_11_BIT ) },
  226. { LSTRKEY( "TIMER_12_BIT"), LNUMVAL( LEDC_TIMER_12_BIT ) },
  227. { LSTRKEY( "TIMER_13_BIT"), LNUMVAL( LEDC_TIMER_13_BIT ) },
  228. { LSTRKEY( "TIMER_14_BIT"), LNUMVAL( LEDC_TIMER_14_BIT ) },
  229. { LSTRKEY( "TIMER_15_BIT"), LNUMVAL( LEDC_TIMER_15_BIT ) },
  230. { LSTRKEY( "CHANNEL_0"), LNUMVAL( LEDC_CHANNEL_0 ) },
  231. { LSTRKEY( "CHANNEL_1"), LNUMVAL( LEDC_CHANNEL_1 ) },
  232. { LSTRKEY( "CHANNEL_2"), LNUMVAL( LEDC_CHANNEL_2 ) },
  233. { LSTRKEY( "CHANNEL_3"), LNUMVAL( LEDC_CHANNEL_3 ) },
  234. { LSTRKEY( "CHANNEL_4"), LNUMVAL( LEDC_CHANNEL_4 ) },
  235. { LSTRKEY( "CHANNEL_5"), LNUMVAL( LEDC_CHANNEL_5 ) },
  236. { LSTRKEY( "CHANNEL_6"), LNUMVAL( LEDC_CHANNEL_6 ) },
  237. { LSTRKEY( "CHANNEL_7"), LNUMVAL( LEDC_CHANNEL_7 ) },
  238. { LSTRKEY( "IDLE_LOW"), LNUMVAL( 0 ) },
  239. { LSTRKEY( "IDLE_HIGH"), LNUMVAL( 1 ) },
  240. { LSTRKEY( "FADE_NO_WAIT"), LNUMVAL( LEDC_FADE_NO_WAIT ) },
  241. { LSTRKEY( "FADE_WAIT_DONE"), LNUMVAL( LEDC_FADE_WAIT_DONE ) },
  242. { LSTRKEY( "FADE_DECREASE"), LNUMVAL( LEDC_DUTY_DIR_DECREASE ) },
  243. { LSTRKEY( "FADE_INCREASE"), LNUMVAL( LEDC_DUTY_DIR_INCREASE ) },
  244. { LNILKEY, LNILVAL }
  245. };
  246. int luaopen_ledc(lua_State *L) {
  247. luaL_rometatable(L, "ledc.channel", (void *)ledc_channel_map); // create metatable for ledc.channel
  248. return 0;
  249. }
  250. NODEMCU_MODULE(LEDC, "ledc", ledc_map, luaopen_ledc);