platform.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. // Platform-dependent functions
  2. #include "platform.h"
  3. #include "c_stdio.h"
  4. #include "c_string.h"
  5. #include "c_stdlib.h"
  6. #include "gpio.h"
  7. #include "user_interface.h"
  8. #include "driver/uart.h"
  9. // Platform specific includes
  10. static void pwms_init();
  11. int platform_init()
  12. {
  13. // Setup PWMs
  14. pwms_init();
  15. cmn_platform_init();
  16. // All done
  17. return PLATFORM_OK;
  18. }
  19. // ****************************************************************************
  20. // KEY_LED functions
  21. uint8_t platform_key_led( uint8_t level){
  22. uint8_t temp;
  23. gpio16_output_set(1); // set to high first, for reading key low level
  24. gpio16_input_conf();
  25. temp = gpio16_input_get();
  26. gpio16_output_conf();
  27. gpio16_output_set(level);
  28. return temp;
  29. }
  30. // ****************************************************************************
  31. // GPIO functions
  32. #ifdef GPIO_INTERRUPT_ENABLE
  33. extern void lua_gpio_unref(unsigned pin);
  34. #endif
  35. int platform_gpio_mode( unsigned pin, unsigned mode, unsigned pull )
  36. {
  37. // NODE_DBG("Function platform_gpio_mode() is called. pin_mux:%d, func:%d\n",pin_mux[pin],pin_func[pin]);
  38. if (pin >= NUM_GPIO)
  39. return -1;
  40. if(pin == 0){
  41. if(mode==PLATFORM_GPIO_INPUT)
  42. gpio16_input_conf();
  43. else
  44. gpio16_output_conf();
  45. return 1;
  46. }
  47. platform_pwm_close(pin); // closed from pwm module, if it is used in pwm
  48. switch(pull){
  49. case PLATFORM_GPIO_PULLUP:
  50. PIN_PULLDWN_DIS(pin_mux[pin]);
  51. PIN_PULLUP_EN(pin_mux[pin]);
  52. break;
  53. case PLATFORM_GPIO_PULLDOWN:
  54. PIN_PULLUP_DIS(pin_mux[pin]);
  55. PIN_PULLDWN_EN(pin_mux[pin]);
  56. break;
  57. case PLATFORM_GPIO_FLOAT:
  58. PIN_PULLUP_DIS(pin_mux[pin]);
  59. PIN_PULLDWN_DIS(pin_mux[pin]);
  60. break;
  61. default:
  62. PIN_PULLUP_DIS(pin_mux[pin]);
  63. PIN_PULLDWN_DIS(pin_mux[pin]);
  64. break;
  65. }
  66. switch(mode){
  67. case PLATFORM_GPIO_INPUT:
  68. #ifdef GPIO_INTERRUPT_ENABLE
  69. lua_gpio_unref(pin); // unref the lua ref call back.
  70. #endif
  71. GPIO_DIS_OUTPUT(pin_num[pin]);
  72. case PLATFORM_GPIO_OUTPUT:
  73. ETS_GPIO_INTR_DISABLE();
  74. #ifdef GPIO_INTERRUPT_ENABLE
  75. pin_int_type[pin] = GPIO_PIN_INTR_DISABLE;
  76. #endif
  77. PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]);
  78. //disable interrupt
  79. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), GPIO_PIN_INTR_DISABLE);
  80. //clear interrupt status
  81. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin]));
  82. GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin]))) & (~ GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE))); //disable open drain;
  83. ETS_GPIO_INTR_ENABLE();
  84. break;
  85. #ifdef GPIO_INTERRUPT_ENABLE
  86. case PLATFORM_GPIO_INT:
  87. ETS_GPIO_INTR_DISABLE();
  88. PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]);
  89. GPIO_DIS_OUTPUT(pin_num[pin]);
  90. gpio_register_set(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
  91. | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
  92. | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
  93. ETS_GPIO_INTR_ENABLE();
  94. break;
  95. #endif
  96. default:
  97. break;
  98. }
  99. return 1;
  100. }
  101. int platform_gpio_write( unsigned pin, unsigned level )
  102. {
  103. // NODE_DBG("Function platform_gpio_write() is called. pin:%d, level:%d\n",GPIO_ID_PIN(pin_num[pin]),level);
  104. if (pin >= NUM_GPIO)
  105. return -1;
  106. if(pin == 0){
  107. gpio16_output_conf();
  108. gpio16_output_set(level);
  109. return 1;
  110. }
  111. GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), level);
  112. }
  113. int platform_gpio_read( unsigned pin )
  114. {
  115. // NODE_DBG("Function platform_gpio_read() is called. pin:%d\n",GPIO_ID_PIN(pin_num[pin]));
  116. if (pin >= NUM_GPIO)
  117. return -1;
  118. if(pin == 0){
  119. // gpio16_input_conf();
  120. return 0x1 & gpio16_input_get();
  121. }
  122. // GPIO_DIS_OUTPUT(pin_num[pin]);
  123. return 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[pin]));
  124. }
  125. #ifdef GPIO_INTERRUPT_ENABLE
  126. static void platform_gpio_intr_dispatcher( platform_gpio_intr_handler_fn_t cb){
  127. uint8 i, level;
  128. uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
  129. for (i = 0; i < GPIO_PIN_NUM; i++) {
  130. if (pin_int_type[i] && (gpio_status & BIT(pin_num[i])) ) {
  131. //disable interrupt
  132. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[i]), GPIO_PIN_INTR_DISABLE);
  133. //clear interrupt status
  134. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(pin_num[i]));
  135. level = 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[i]));
  136. if(cb){
  137. cb(i, level);
  138. }
  139. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[i]), pin_int_type[i]);
  140. }
  141. }
  142. }
  143. void platform_gpio_init( platform_gpio_intr_handler_fn_t cb )
  144. {
  145. ETS_GPIO_INTR_ATTACH(platform_gpio_intr_dispatcher, cb);
  146. }
  147. int platform_gpio_intr_init( unsigned pin, GPIO_INT_TYPE type )
  148. {
  149. if (pin >= NUM_GPIO)
  150. return -1;
  151. ETS_GPIO_INTR_DISABLE();
  152. //clear interrupt status
  153. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin]));
  154. pin_int_type[pin] = type;
  155. //enable interrupt
  156. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), type);
  157. ETS_GPIO_INTR_ENABLE();
  158. }
  159. #endif
  160. // ****************************************************************************
  161. // UART
  162. // TODO: Support timeouts.
  163. // UartDev is defined and initialized in rom code.
  164. extern UartDevice UartDev;
  165. uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int parity, int stopbits )
  166. {
  167. switch( baud )
  168. {
  169. case BIT_RATE_9600:
  170. case BIT_RATE_19200:
  171. case BIT_RATE_38400:
  172. case BIT_RATE_57600:
  173. case BIT_RATE_74880:
  174. case BIT_RATE_115200:
  175. case BIT_RATE_230400:
  176. case BIT_RATE_460800:
  177. case BIT_RATE_921600:
  178. UartDev.baut_rate = baud;
  179. break;
  180. default:
  181. UartDev.baut_rate = BIT_RATE_9600;
  182. break;
  183. }
  184. switch( databits )
  185. {
  186. case 5:
  187. UartDev.data_bits = FIVE_BITS;
  188. break;
  189. case 6:
  190. UartDev.data_bits = SIX_BITS;
  191. break;
  192. case 7:
  193. UartDev.data_bits = SEVEN_BITS;
  194. break;
  195. case 8:
  196. UartDev.data_bits = EIGHT_BITS;
  197. break;
  198. default:
  199. UartDev.data_bits = EIGHT_BITS;
  200. break;
  201. }
  202. switch (stopbits)
  203. {
  204. case PLATFORM_UART_STOPBITS_1:
  205. UartDev.stop_bits = ONE_STOP_BIT;
  206. break;
  207. case PLATFORM_UART_STOPBITS_2:
  208. UartDev.stop_bits = TWO_STOP_BIT;
  209. break;
  210. default:
  211. UartDev.stop_bits = ONE_STOP_BIT;
  212. break;
  213. }
  214. switch (parity)
  215. {
  216. case PLATFORM_UART_PARITY_EVEN:
  217. UartDev.parity = EVEN_BITS;
  218. break;
  219. case PLATFORM_UART_PARITY_ODD:
  220. UartDev.parity = ODD_BITS;
  221. break;
  222. default:
  223. UartDev.parity = NONE_BITS;
  224. break;
  225. }
  226. uart_setup(id);
  227. return baud;
  228. }
  229. // Send: version with and without mux
  230. void platform_uart_send( unsigned id, u8 data )
  231. {
  232. uart_tx_one_char(id, data);
  233. }
  234. // ****************************************************************************
  235. // PWMs
  236. static uint16_t pwms_duty[NUM_PWM] = {0};
  237. static void pwms_init()
  238. {
  239. int i;
  240. for(i=0;i<NUM_PWM;i++){
  241. pwms_duty[i] = DUTY(0);
  242. }
  243. pwm_init(500, NULL);
  244. // NODE_DBG("Function pwms_init() is called.\n");
  245. }
  246. // Return the PWM clock
  247. // NOTE: Can't find a function to query for the period set for the timer,
  248. // therefore using the struct.
  249. // This may require adjustment if driver libraries are updated.
  250. uint32_t platform_pwm_get_clock( unsigned pin )
  251. {
  252. // NODE_DBG("Function platform_pwm_get_clock() is called.\n");
  253. if( pin >= NUM_PWM)
  254. return 0;
  255. if(!pwm_exist(pin))
  256. return 0;
  257. return (uint32_t)pwm_get_freq(pin);
  258. }
  259. // Set the PWM clock
  260. uint32_t platform_pwm_set_clock( unsigned pin, uint32_t clock )
  261. {
  262. // NODE_DBG("Function platform_pwm_set_clock() is called.\n");
  263. if( pin >= NUM_PWM)
  264. return 0;
  265. if(!pwm_exist(pin))
  266. return 0;
  267. pwm_set_freq((uint16_t)clock, pin);
  268. pwm_start();
  269. return (uint32_t)pwm_get_freq( pin );
  270. }
  271. uint32_t platform_pwm_get_duty( unsigned pin )
  272. {
  273. // NODE_DBG("Function platform_pwm_get_duty() is called.\n");
  274. if( pin < NUM_PWM){
  275. if(!pwm_exist(pin))
  276. return 0;
  277. // return NORMAL_DUTY(pwm_get_duty(pin));
  278. return pwms_duty[pin];
  279. }
  280. return 0;
  281. }
  282. // Set the PWM duty
  283. uint32_t platform_pwm_set_duty( unsigned pin, uint32_t duty )
  284. {
  285. // NODE_DBG("Function platform_pwm_set_duty() is called.\n");
  286. if ( pin < NUM_PWM)
  287. {
  288. if(!pwm_exist(pin))
  289. return 0;
  290. pwm_set_duty(DUTY(duty), pin);
  291. } else {
  292. return 0;
  293. }
  294. pwm_start();
  295. pwms_duty[pin] = NORMAL_DUTY(pwm_get_duty(pin));
  296. return pwms_duty[pin];
  297. }
  298. uint32_t platform_pwm_setup( unsigned pin, uint32_t frequency, unsigned duty )
  299. {
  300. uint32_t clock;
  301. if ( pin < NUM_PWM)
  302. {
  303. platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT); // disable gpio interrupt first
  304. if(!pwm_add(pin))
  305. return 0;
  306. // pwm_set_duty(DUTY(duty), pin);
  307. pwm_set_duty(0, pin);
  308. pwms_duty[pin] = duty;
  309. pwm_set_freq((uint16_t)frequency, pin);
  310. } else {
  311. return 0;
  312. }
  313. clock = platform_pwm_get_clock( pin );
  314. pwm_start();
  315. return clock;
  316. }
  317. void platform_pwm_close( unsigned pin )
  318. {
  319. // NODE_DBG("Function platform_pwm_stop() is called.\n");
  320. if ( pin < NUM_PWM)
  321. {
  322. pwm_delete(pin);
  323. pwm_start();
  324. }
  325. }
  326. void platform_pwm_start( unsigned pin )
  327. {
  328. // NODE_DBG("Function platform_pwm_start() is called.\n");
  329. if ( pin < NUM_PWM)
  330. {
  331. if(!pwm_exist(pin))
  332. return;
  333. pwm_set_duty(DUTY(pwms_duty[pin]), pin);
  334. pwm_start();
  335. }
  336. }
  337. void platform_pwm_stop( unsigned pin )
  338. {
  339. // NODE_DBG("Function platform_pwm_stop() is called.\n");
  340. if ( pin < NUM_PWM)
  341. {
  342. if(!pwm_exist(pin))
  343. return;
  344. pwm_set_duty(0, pin);
  345. pwm_start();
  346. }
  347. }
  348. // *****************************************************************************
  349. // I2C platform interface
  350. uint32_t platform_i2c_setup( unsigned id, uint8_t sda, uint8_t scl, uint32_t speed ){
  351. if (sda >= NUM_GPIO || scl >= NUM_GPIO)
  352. return 0;
  353. // platform_pwm_close(sda);
  354. // platform_pwm_close(scl);
  355. // disable gpio interrupt first
  356. platform_gpio_mode(sda, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP); // inside this func call platform_pwm_close
  357. platform_gpio_mode(scl, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP); // disable gpio interrupt first
  358. i2c_master_gpio_init(sda, scl);
  359. return PLATFORM_I2C_SPEED_SLOW;
  360. }
  361. void platform_i2c_send_start( unsigned id ){
  362. i2c_master_start();
  363. }
  364. void platform_i2c_send_stop( unsigned id ){
  365. i2c_master_stop();
  366. }
  367. int platform_i2c_send_address( unsigned id, uint16_t address, int direction ){
  368. // Convert enum codes to R/w bit value.
  369. // If TX == 0 and RX == 1, this test will be removed by the compiler
  370. if ( ! ( PLATFORM_I2C_DIRECTION_TRANSMITTER == 0 &&
  371. PLATFORM_I2C_DIRECTION_RECEIVER == 1 ) ) {
  372. direction = ( direction == PLATFORM_I2C_DIRECTION_TRANSMITTER ) ? 0 : 1;
  373. }
  374. i2c_master_writeByte( (uint8_t) ((address << 1) | direction ));
  375. // Low-level returns nack (0=acked); we return ack (1=acked).
  376. return ! i2c_master_getAck();
  377. }
  378. int platform_i2c_send_byte( unsigned id, uint8_t data ){
  379. i2c_master_writeByte(data);
  380. // Low-level returns nack (0=acked); we return ack (1=acked).
  381. return ! i2c_master_getAck();
  382. }
  383. int platform_i2c_recv_byte( unsigned id, int ack ){
  384. uint8_t r = i2c_master_readByte();
  385. i2c_master_setAck( !ack );
  386. return r;
  387. }
  388. // *****************************************************************************
  389. // SPI platform interface
  390. uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock)
  391. {
  392. spi_master_init(id, cpol, cpha, databits, clock);
  393. return 1;
  394. }
  395. spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
  396. {
  397. spi_mast_byte_write(id, &data);
  398. return data;
  399. }
  400. // ****************************************************************************
  401. // Flash access functions
  402. uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t size )
  403. {
  404. toaddr -= INTERNAL_FLASH_START_ADDRESS;
  405. SpiFlashOpResult r;
  406. const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
  407. uint32_t *apbuf = NULL;
  408. if( ((uint32_t)from) & blkmask ){
  409. apbuf = (uint32_t *)c_malloc(size);
  410. if(!apbuf)
  411. return 0;
  412. c_memcpy(apbuf, from, size);
  413. }
  414. WRITE_PERI_REG(0x60000914, 0x73);
  415. r = flash_write(toaddr, apbuf?(uint32 *)apbuf:(uint32 *)from, size);
  416. if(apbuf)
  417. c_free(apbuf);
  418. if(SPI_FLASH_RESULT_OK == r)
  419. return size;
  420. else{
  421. NODE_ERR( "ERROR in flash_write: r=%d at %08X\n", ( int )r, ( unsigned )toaddr+INTERNAL_FLASH_START_ADDRESS );
  422. return 0;
  423. }
  424. }
  425. uint32_t platform_s_flash_read( void *to, uint32_t fromaddr, uint32_t size )
  426. {
  427. fromaddr -= INTERNAL_FLASH_START_ADDRESS;
  428. SpiFlashOpResult r;
  429. WRITE_PERI_REG(0x60000914, 0x73);
  430. r = flash_read(fromaddr, (uint32 *)to, size);
  431. if(SPI_FLASH_RESULT_OK == r)
  432. return size;
  433. else{
  434. NODE_ERR( "ERROR in flash_read: r=%d at %08X\n", ( int )r, ( unsigned )fromaddr+INTERNAL_FLASH_START_ADDRESS );
  435. return 0;
  436. }
  437. }
  438. int platform_flash_erase_sector( uint32_t sector_id )
  439. {
  440. WRITE_PERI_REG(0x60000914, 0x73);
  441. return flash_erase( sector_id ) == SPI_FLASH_RESULT_OK ? PLATFORM_OK : PLATFORM_ERR;
  442. }