static void ICACHE_FLASH_ATTR gpio_intr(void *arg) { uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); if (irparams.rcvstate == STATE_STOP) { return; } static uint32_t start = 0; uint32_t now = system_get_time(); if (irparams.rcvstate == STATE_IDLE) { irparams.rcvstate = STATE_MARK; irparams.rawbuf[irparams.rawlen++] = 20; } else if (irparams.rawlen < RAWBUF) { irparams.rawbuf[irparams.rawlen++] = (now - start) / USECPERTICK + 1; } start = now; os_timer_disarm(&timer); os_timer_arm(&timer, 15, 0); }
bool ICACHE_FLASH_ATTR pwm_add(uint8 channel){ PWM_DBG("--Function pwm_add() is called. channel:%d\n", channel); PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num); PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]); PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]); uint8 i; for(i=0;i<PWM_CHANNEL;i++){ if(pwm_out_io_num[i]==channel) // already exist return true; if(pwm_out_io_num[i] == -1){ // empty exist pwm_out_io_num[i] = channel; pwm.duty[i] = 0; pwm_gpio |= (1 << pin_num[channel]); PIN_FUNC_SELECT(pin_mux[channel], pin_func[channel]); GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[channel])), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[channel]))) & (~ GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE))); //disable open drain; pwm_channel_num++; return true; } } return false; }
void ICACHE_FLASH_ATTR vibrate_init(uint8 gpio_id) { uint32 v_gpio_name=tisan_get_gpio_name(gpio_id); uint8 v_gpio_func=tisan_get_gpio_general_func(gpio_id); PIN_FUNC_SELECT(v_gpio_name, v_gpio_func); PIN_PULLUP_EN(v_gpio_name); gpio_output_set(0, 0, 0, GPIO_ID_PIN(gpio_id)); //set as input mode gpio_register_set(GPIO_PIN_ADDR(gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(gpio_id)); //enable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_id), GPIO_PIN_INTR_NEGEDGE); peri_alarm_init(ALARM_GPIO_ID); peri_vibrate_tim_start(100); }
void ICACHE_FLASH_ATTR gpio_intr_dispatcher(gpio_intr_handler cb) { uint8 i, level; uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); for (i = 0; i < GPIO_PIN_NUM; i++) { if (pin_int_type[i] && (gpio_status & BIT(pin_num[i])) ) { //disable global interrupt ETS_GPIO_INTR_DISABLE(); //disable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[i]), GPIO_PIN_INTR_DISABLE); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(pin_num[i])); level = 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[i])); if(cb){ cb(i, level); } //enable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[i]), pin_int_type[i]); //enable global interrupt ETS_GPIO_INTR_ENABLE(); } } }
/** * Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin */ bool ICACHE_FLASH_ATTR easygpio_setupInterrupt(uint8_t gpio_pin, bool pullUp, bool pullDown, void (*interruptHandler)(void)) { uint32_t gpio_name; uint8_t gpio_func; if (gpio_pin == 6 || gpio_pin == 7 || gpio_pin == 8 || gpio_pin == 11 || gpio_pin >= 17) { os_printf("easygpio_setupInterrupt Error: There is no GPIO%d, check your code\n", gpio_pin); return false; } if (gpio_pin == 16) { os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n"); return false; } if (!easygpio_getGpioNameFunc(gpio_pin, &gpio_name, &gpio_func) ) { return false; } ETS_GPIO_INTR_ATTACH(interruptHandler, NULL); ETS_GPIO_INTR_DISABLE(); PIN_FUNC_SELECT(gpio_name, gpio_func); easygpio_setupPulls(gpio_name, pullUp, pullDown); // disable output GPIO_DIS_OUTPUT(gpio_pin); gpio_register_set(GPIO_PIN_ADDR(gpio_pin), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); //clear gpio14 status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(gpio_pin)); ETS_GPIO_INTR_ENABLE(); return true; }
/****************************************************************************** * FunctionName : key_intr_handler * Description : key interrupt handler * Parameters : key_param *keys - keys parameter, which inited by key_init_single * Returns : none *******************************************************************************/ LOCAL void key_intr_handler(struct keys_param *keys) { uint8 i; uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); for (i = 0; i < keys->key_num; i++) { if (gpio_status & BIT(keys->single_key[i]->gpio_id)) { //disable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_DISABLE); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(keys->single_key[i]->gpio_id)); if (keys->single_key[i]->key_level == 1) { // 5s long release timer os_timer_disarm(&keys->single_key[i]->key_5s); os_timer_setfn(&keys->single_key[i]->key_5s, (os_timer_func_t *)key_5s_cb, keys->single_key[i]); os_timer_arm(&keys->single_key[i]->key_5s, 5000, 0); keys->single_key[i]->key_level = 0; keys->single_key[i]->is_long = 0; gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_POSEDGE); if (keys->single_key[i]->press) { // PRESS callback os_timer_disarm(&keys->single_key[i]->key_press); os_timer_setfn(&keys->single_key[i]->key_press, (os_timer_func_t *)keys->single_key[i]->press, NULL); os_timer_arm(&keys->single_key[i]->key_press, 5, 0); } } else { // 50ms check if this is a real key up os_timer_disarm(&keys->single_key[i]->key_50ms); os_timer_setfn(&keys->single_key[i]->key_50ms, (os_timer_func_t *)key_50ms_cb, keys->single_key[i]); os_timer_arm(&keys->single_key[i]->key_50ms, 50, 0); } } } }
int platform_gpio_mode( unsigned pin, unsigned mode, unsigned pull ) { // NODE_DBG("Function platform_gpio_mode() is called. pin_mux:%d, func:%d\n",pin_mux[pin],pin_func[pin]); if (pin >= NUM_GPIO) return -1; if(pin == 0){ if(mode==PLATFORM_GPIO_INPUT) gpio16_input_conf(); else gpio16_output_conf(); return 1; } platform_pwm_close(pin); // closed from pwm module, if it is used in pwm switch(pull){ case PLATFORM_GPIO_PULLUP: PIN_PULLDWN_DIS(pin_mux[pin]); PIN_PULLUP_EN(pin_mux[pin]); break; case PLATFORM_GPIO_PULLDOWN: PIN_PULLUP_DIS(pin_mux[pin]); PIN_PULLDWN_EN(pin_mux[pin]); break; case PLATFORM_GPIO_FLOAT: PIN_PULLUP_DIS(pin_mux[pin]); PIN_PULLDWN_DIS(pin_mux[pin]); break; default: PIN_PULLUP_DIS(pin_mux[pin]); PIN_PULLDWN_DIS(pin_mux[pin]); break; } switch(mode){ case PLATFORM_GPIO_INPUT: #if defined( LUA_USE_MODULES_GPIO ) && defined( GPIO_INTERRUPT_ENABLE ) lua_gpio_unref(pin); // unref the lua ref call back. #endif GPIO_DIS_OUTPUT(pin_num[pin]); case PLATFORM_GPIO_OUTPUT: ETS_GPIO_INTR_DISABLE(); #ifdef GPIO_INTERRUPT_ENABLE pin_int_type[pin] = GPIO_PIN_INTR_DISABLE; #endif PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]); //disable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), GPIO_PIN_INTR_DISABLE); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin])); 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; ETS_GPIO_INTR_ENABLE(); break; #ifdef GPIO_INTERRUPT_ENABLE case PLATFORM_GPIO_INT: ETS_GPIO_INTR_DISABLE(); PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]); GPIO_DIS_OUTPUT(pin_num[pin]); gpio_register_set(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); ETS_GPIO_INTR_ENABLE(); break; #endif default: break; } return 1; }
static void ICACHE_FLASH_ATTR send_ws_1(uint8_t gpio) { uint8_t i; i = 8; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio); i = 6; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio); }
void __attribute__((optimize("O2"))) send_ws_1(uint8_t gpio){ uint8_t i; i = 8; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio); i = 6; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio); }
bool ICACHE_FLASH_ATTR ssd1306_init(uint8_t id) { oled_i2c_ctx *ctx = NULL; if ((id != 0) && (id != 1)) goto oled_init_fail; // free old context (if any) ssd1306_term(id); ctx = zalloc(sizeof(oled_i2c_ctx)); if (ctx == NULL) { dmsg_err_puts("Alloc OLED context failed."); goto oled_init_fail; } if (id == 0) { #if (PANEL0_TYPE != 0) #if (PANEL0_TYPE == SSD1306_128x64) ctx->type = SSD1306_128x64; ctx->buffer = zalloc(1024); // 128 * 64 / 8 ctx->width = 128; ctx->height = 64; #elif (PANEL0_TYPE == SSD1306_128x32) ctx->type = SSD1306_128x32; ctx->buffer = zalloc(512); // 128 * 32 / 8 ctx->width = 128; ctx->height = 32; #else #error "Panel 0 undefined" #endif if (ctx->buffer == NULL) { dmsg_err_puts("Alloc OLED buffer failed."); goto oled_init_fail; } ctx->address = PANEL0_ADDR; #if PANEL0_USE_RST // Panel 0 reset PIN_FUNC_SELECT(PANEL0_RST_MUX, PANEL0_RST_FUNC); GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | PANEL0_RST_BIT); GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, PANEL0_RST_BIT); os_delay_us(10000); GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, PANEL0_RST_BIT); #endif #else dmsg_err_puts("Panel 0 not defined."); goto oled_init_fail; #endif } else if (id == 1) { #if (PANEL1_PANEL_TYPE != 0) #if (PANEL1_PANEL_TYPE ==SSD1306_128x64) ctx->type = SSD1306_128x64; ctx->buffer = zalloc(1024); // 128 * 64 / 8 ctx->width = 128; ctx->height = 64; #elif (PANEL1_PANEL_TYPE == SSD1306_128x32) ctx->type = SSD1306_128x32; ctx->buffer = zalloc(512); // 128 * 32 / 8 ctx->width = 128; ctx->height = 32; #else #error "Unknown Panel 1 type" #endif if (ctx->buffer == NULL) { dmsg_err_puts("Alloc OLED buffer failed."); goto oled_init_fail; } ctx->address = PANEL1_ADDR; #if PANEL1_USE_RST // Panel 1 reset PIN_FUNC_SELECT(PANEL1_RST_MUX, PANEL1_RST_FUNC); GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | PANEL1_RST_BIT); GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, PANEL1_RST_BIT); os_delay_us(10000); GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, PANEL1_RST_BIT); #endif #else dmsg_err_puts("Panel 1 not defined."); goto oled_init_fail; #endif } // Panel initialization // Try send I2C address check if the panel is connected i2c_start(); if (!i2c_write(ctx->address)) { i2c_stop(); dmsg_err_puts("OLED I2C bus not responding."); goto oled_init_fail; } i2c_stop(); // Now we assume all sending will be successful if (ctx->type == SSD1306_128x64) { _command(ctx->address, 0xae); // SSD1306_DISPLAYOFF _command(ctx->address, 0xd5); // SSD1306_SETDISPLAYCLOCKDIV _command(ctx->address, 0x80); // Suggested value 0x80 _command(ctx->address, 0xa8); // SSD1306_SETMULTIPLEX _command(ctx->address, 0x3f); // 1/64 _command(ctx->address, 0xd3); // SSD1306_SETDISPLAYOFFSET _command(ctx->address, 0x00); // 0 no offset _command(ctx->address, 0x40); // SSD1306_SETSTARTLINE line #0 _command(ctx->address, 0x20); // SSD1306_MEMORYMODE _command(ctx->address, 0x00); // 0x0 act like ks0108 _command(ctx->address, 0xa1); // SSD1306_SEGREMAP | 1 _command(ctx->address, 0xc8); // SSD1306_COMSCANDEC _command(ctx->address, 0xda); // SSD1306_SETCOMPINS _command(ctx->address, 0x12); _command(ctx->address, 0x81); // SSD1306_SETCONTRAST _command(ctx->address, 0xcf); _command(ctx->address, 0xd9); // SSD1306_SETPRECHARGE _command(ctx->address, 0xf1); _command(ctx->address, 0xdb); // SSD1306_SETVCOMDETECT _command(ctx->address, 0x30); _command(ctx->address, 0x8d); // SSD1306_CHARGEPUMP _command(ctx->address, 0x14); // Charge pump on _command(ctx->address, 0x2e); // SSD1306_DEACTIVATE_SCROLL _command(ctx->address, 0xa4); // SSD1306_DISPLAYALLON_RESUME _command(ctx->address, 0xa6); // SSD1306_NORMALDISPLAY } else if (ctx->type == SSD1306_128x32) { _command(ctx->address, 0xae); // SSD1306_DISPLAYOFF _command(ctx->address, 0xd5); // SSD1306_SETDISPLAYCLOCKDIV _command(ctx->address, 0x80); // Suggested value 0x80 _command(ctx->address, 0xa8); // SSD1306_SETMULTIPLEX _command(ctx->address, 0x1f); // 1/32 _command(ctx->address, 0xd3); // SSD1306_SETDISPLAYOFFSET _command(ctx->address, 0x00); // 0 no offset _command(ctx->address, 0x40); // SSD1306_SETSTARTLINE line #0 _command(ctx->address, 0x8d); // SSD1306_CHARGEPUMP _command(ctx->address, 0x14); // Charge pump on _command(ctx->address, 0x20); // SSD1306_MEMORYMODE _command(ctx->address, 0x00); // 0x0 act like ks0108 _command(ctx->address, 0xa1); // SSD1306_SEGREMAP | 1 _command(ctx->address, 0xc8); // SSD1306_COMSCANDEC _command(ctx->address, 0xda); // SSD1306_SETCOMPINS _command(ctx->address, 0x02); _command(ctx->address, 0x81); // SSD1306_SETCONTRAST _command(ctx->address, 0x2f); _command(ctx->address, 0xd9); // SSD1306_SETPRECHARGE _command(ctx->address, 0xf1); _command(ctx->address, 0xdb); // SSD1306_SETVCOMDETECT _command(ctx->address, 0x40); _command(ctx->address, 0x2e); // SSD1306_DEACTIVATE_SCROLL _command(ctx->address, 0xa4); // SSD1306_DISPLAYALLON_RESUME _command(ctx->address, 0xa6); // SSD1306_NORMALDISPLAY } // Save context ctx->id = id; _ctxs[id] = ctx; ssd1306_clear(id); ssd1306_refresh(id, true); _command(ctx->address, 0xaf); // SSD1306_DISPLAYON return true; oled_init_fail: if (ctx && ctx->buffer) free(ctx->buffer); if (ctx) free(ctx); return false; }
void gpio_intr_handler(struct base_key_param **keys_param) { uint8 i; uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); uint8 gpio_id; struct base_key_param * single_key = NULL; PRINTF("Get into gpio_intr_handler, gpio_status:%u\n", gpio_status); for(i = 0; i < KEY_MAX_NUM; i++) { single_key = keys_param[i]; if(single_key == NULL) { PRINTF("\r\nintr sinle_key is NULL, i:%d\r\n",i); continue; } gpio_id = single_key->gpio_id; PRINTF("\r\ngpio_id:%d, BIT(gpio_id):%d\r\n",gpio_id, BIT(gpio_id)); if(gpio_status & BIT(gpio_id)) { PRINTF("\r\n key config start....\r\n"); //disable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_id), GPIO_PIN_INTR_DISABLE); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(gpio_id)); //if need to manage special gpio event, manage here //example: manage key config wifi connect, need call config_key_init() first if(i == 0) { if(single_key->level == 1) {// 5s, restart & enter softap mode PRINTF("\r\n sinle_key->level:%d....\r\n", single_key->level); os_timer_disarm(&single_key->k_timer1); os_timer_setfn(&single_key->k_timer1, (os_timer_func_t *)key_5s_cb, single_key); os_timer_arm(&single_key->k_timer1, LONG_PRESS_COUNT, 0); single_key->level = 0; gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_id), GPIO_PIN_INTR_POSEDGE); } else { // 50ms, check if this is a real key up PRINTF("\r\n50ms sinle_key->level:%d....\r\n", single_key->level); os_timer_disarm(&single_key->k_timer2); os_timer_setfn(&single_key->k_timer2, (os_timer_func_t *)key_50ms_cb, single_key); os_timer_arm(&single_key->k_timer2, 50, 0); } continue; } //other manage } } }
static void ICACHE_RAM_ATTR gpio_pulse_timeout(os_param_t p) { (void) p; uint32_t now = system_get_time(); int delay; if (active_pulser) { delay = active_pulser->pending_delay; if (delay > 0) { if (delay > 1200000) { delay = 1000000; } active_pulser->pending_delay -= delay; platform_hw_timer_arm_us(TIMER_OWNER, delay); return; } } do { active_pulser->active_pos = active_pulser->entry_pos; if (!active_pulser || active_pulser->entry_pos >= active_pulser->entry_count) { if (active_pulser) { active_pulser->steps++; } platform_hw_timer_close(TIMER_OWNER); task_post_low(tasknumber, (task_param_t)0); return; } active_pulser->steps++; pulse_entry_t *entry = active_pulser->entry + active_pulser->entry_pos; // Yes, this means that there is more skew on D0 than on other pins.... if (entry->gpio_set & 0x10000) { gpio16_output_set(1); } GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, entry->gpio_set); GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, entry->gpio_clr); if (entry->gpio_clr & 0x10000) { gpio16_output_set(0); } int16_t stop = active_pulser->stop_pos; if (stop == -2 || stop == active_pulser->entry_pos) { platform_hw_timer_close(TIMER_OWNER); task_post_low(tasknumber, (task_param_t)0); return; } if (entry->loop) { if (entry->count_left == 0) { entry->count_left = entry->count + 1; } if (--entry->count_left >= 1) { active_pulser->entry_pos = entry->loop - 1; // zero offset } else { active_pulser->entry_pos++; } } else { active_pulser->entry_pos++; } delay = entry->delay; int delay_offset = 0; if (entry->delay_min != -1) { int offset = active_pulser->next_adjust; active_pulser->next_adjust = 0; delay_offset = ((0x7fffffff & (now - active_pulser->desired_end_time)) << 1) >> 1; delay -= delay_offset; delay += offset; //dbg_printf("%d(et %d diff %d): Delay was %d us, offset = %d, delay_offset = %d, new delay = %d, range=%d..%d\n", // now, active_pulser->desired_end_time, now - active_pulser->desired_end_time, // entry->delay, offset, delay_offset, delay, entry->delay_min, entry->delay_max); if (delay < entry->delay_min) { // we can't delay as little as 'delay', so we need to adjust // the next period as well. active_pulser->next_adjust = (entry->delay - entry->delay_min) + offset; delay = entry->delay_min; } else if (delay > entry->delay_max) { // we can't delay as much as 'delay', so we need to adjust // the next period as well. active_pulser->next_adjust = (entry->delay - entry->delay_max) + offset; delay = entry->delay_max; } } active_pulser->desired_end_time += delay + delay_offset; active_pulser->expected_end_time = system_get_time() + delay; } while (delay < 3);
//----------------------------------------------------------------------------------------- void static dht11_protocol(uint32 gpio_status,int cause) { static int actual_bit; switch(cause) // 0 = gpio interrupt, 1=timer { case 0: // gpio edge { // disable interrupt for GPIO gpio_pin_intr_state_set(GPIO_ID_PIN(dht11_gpio), GPIO_PIN_INTR_DISABLE); // clear interrupt status for GPIO GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & GPIO_Pin(dht11_gpio)); // Reactivate interrupts for GPIO0 gpio_pin_intr_state_set(GPIO_ID_PIN(dht11_gpio), GPIO_PIN_INTR_ANYEGDE); switch(sStatus) { case dht11_connecting: if(GPIO_INPUT_GET(dht11_gpio)) { // Rising edge ?? Error. dht11_set_read_nok(); dht11_set_standby(); } else { sStatus = dht11_mark_connecting; } break; case dht11_mark_connecting: if(!GPIO_INPUT_GET(dht11_gpio)) { // Falling edge ?? Error. dht11_set_read_nok(); dht11_set_standby(); } else { sStatus = dht11_waiting_bit; } break; case dht11_waiting_bit: if(GPIO_INPUT_GET(dht11_gpio)) { // Rising edge ?? Error. dht11_set_read_nok(); dht11_set_standby(); } else { sStatus = dht11_mark_bit; actual_bit=0; } break; case dht11_mark_bit: if(! GPIO_INPUT_GET(dht11_gpio)) { // Falling edge ?? Error. dht11_set_read_nok(); dht11_set_standby(); } else { if(actual_bit >= 40) { dht11_set_standby(); // finish OK } else { last_timer = system_get_time(); sStatus = dht11_read_bit; } } break; case dht11_read_bit: if(GPIO_INPUT_GET(dht11_gpio)) { // Rising edge ?? Error. dht11_set_read_nok(); dht11_set_standby(); } else { // 26-28 uS means 0. 70 uS means 1 int bit_data = ((system_get_time()-last_timer) > 40) ? 1:0; int actual_byte = actual_bit / 8; sRead[actual_byte] <<= 1; sRead[actual_byte] |= bit_data; actual_bit++; sStatus = dht11_mark_bit; } break; case dht11_standby: case dht11_mark: default: dht11_set_standby(); break; } } break; case 1: //timer switch(sStatus) { case dht11_mark: // end of mark sStatus = dht11_connecting; // GPIO as Output to high level by default. GPIO_OUTPUT_SET(dht11_gpio,1); GPIO_AS_INPUT(dht11_gpio); ETS_GPIO_INTR_DISABLE(); gpio_register_set(GPIO_PIN_ADDR(dht11_gpio), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(dht11_gpio)); gpio_pin_intr_state_set(GPIO_ID_PIN(dht11_gpio), GPIO_PIN_INTR_ANYEGDE); ETS_GPIO_INTR_ENABLE(); os_timer_disarm(&dht11_timer); os_timer_arm(&dht11_timer,6,0); // maximun frame time 4.8 ms break; case dht11_connecting: case dht11_mark_connecting: case dht11_waiting_bit: case dht11_mark_bit: case dht11_read_bit: default: dht11_set_read_nok(); dht11_set_standby(); break; } default: break; } }
void ICACHE_FLASH_ATTR toggle_changed() { //TODO: Refactor this shit ETS_GPIO_INTR_DISABLE(); // Disable gpio interrupts uint32 gpio_status; gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); //INFO("TOGGLE: Toggle Switch %d pressed\n", index); if (gpio_status & BIT(TOGGLE01_GPIO)) { INFO("TOGGLE: Toggle Switch %d pressed\n", TOGGLE01_GPIO); if (switch01Status == 0) { set_switch(SWITCH01_GPIO, 1); } else { set_switch(SWITCH01_GPIO, 0); } } else if (gpio_status & BIT(TOGGLE02_GPIO)) { INFO("TOGGLE: Toggle Switch %d pressed\n", TOGGLE02_GPIO); if (switch02Status == 0) { set_switch(SWITCH02_GPIO, 1); } else { set_switch(SWITCH02_GPIO, 0); } } else if (gpio_status & BIT(TOGGLE03_GPIO)) { INFO("TOGGLE: Toggle Switch %d pressed\n", TOGGLE03_GPIO); if (switch03Status == 0) { set_switch(SWITCH03_GPIO,1); } else { set_switch(SWITCH03_GPIO,0); } } //Flip Status /* // Button interrupt received INFO("BUTTON: Button pressed\r\n"); // Button pressed, flip switch if (GPIO_REG_READ(BUTTON_GPIO) & BIT2) { INFO("BUTTON: Switch off\r\n"); GPIO_OUTPUT_SET(SWITCH03_GPIO, 0); } else { INFO("BUTTON: Switch on\r\n"); GPIO_OUTPUT_SET(SWITCH03_GPIO, 1); } // Send new status to the MQTT broker char *json_buf = NULL; json_buf = (char *)os_zalloc(jsonSize); json_ws_send((struct jsontree_value *)&device_tree, "device", json_buf); INFO("BUTTON: Sending current switch status\r\n"); MQTT_Publish(&mqttClient, config.mqtt_topic_s01, json_buf, strlen(json_buf), 0, 0); os_free(json_buf); json_buf = NULL; */ // Debounce os_delay_us(200000); // Clear interrupt status //uint32 gpio_status; //gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); ETS_GPIO_INTR_ENABLE(); // Enable gpio interrupts }
int ICACHE_FLASH_ATTR set_gpio_mode(unsigned pin, unsigned mode, unsigned pull) { if (pin >= GPIO_PIN_NUM) return -1; if(pin == 0) { if(mode == GPIO_INPUT) gpio16_input_conf(); else gpio16_output_conf(); return 1; } switch(pull) { case GPIO_PULLUP: // PIN_PULLDWN_DIS(pin_mux[pin]); PIN_PULLUP_EN(pin_mux[pin]); break; case GPIO_PULLDOWN: PIN_PULLUP_DIS(pin_mux[pin]); // PIN_PULLDWN_EN(pin_mux[pin]); break; case GPIO_FLOAT: PIN_PULLUP_DIS(pin_mux[pin]); // PIN_PULLDWN_DIS(pin_mux[pin]); break; default: PIN_PULLUP_DIS(pin_mux[pin]); // PIN_PULLDWN_DIS(pin_mux[pin]); break; } switch(mode) { case GPIO_INPUT: GPIO_DIS_OUTPUT(pin_num[pin]); break; case GPIO_OUTPUT: ETS_GPIO_INTR_DISABLE(); #ifdef GPIO_INTERRUPT_ENABLE pin_int_type[pin] = GPIO_PIN_INTR_DISABLE; #endif PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]); //disable interrupt gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), GPIO_PIN_INTR_DISABLE); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin])); 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; ETS_GPIO_INTR_ENABLE(); break; #ifdef GPIO_INTERRUPT_ENABLE case GPIO_INT: ETS_GPIO_INTR_DISABLE(); PIN_FUNC_SELECT(pin_mux[pin], pin_func[pin]); GPIO_DIS_OUTPUT(pin_num[pin]); gpio_register_set(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); ETS_GPIO_INTR_ENABLE(); break; #endif default: break; } return 1; }
//Main routine. Initialize stdout, the I/O and the webserver and we're done. void user_init(void) { // my stuff dBR_BOILER_SET=65; // default setting 65C boiler temperature on reboot dBR_TEMP_ROOM_SET=18; // default setting 18C room temperature on reboot dBR_HUMIDITY_SET=60; // default setting 65% humidity target on reboot dBR_MODE=2; // default BR MODE is AUTO dDEVICE_MODE=1; // This mode defines if device uses remote (MQTT) management or uses local logics - 0 for remote, 1 for local mode. DEFAULT is 0 - remote // HTTPD stdoutInit(); ioInit(); httpdInit(builtInUrls, 80); //MQTT uart_init(115200, 115200); CFG_Load(); sleepms(1000); MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, SEC_NONSSL); //MQTT_InitConnection(&mqttClient, "192.168.11.122", 1880, 0); MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive, 1); //MQTT_InitClient(&mqttClient, "client_id", "user", "pass", 120, 1); // MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); MQTT_OnConnected(&mqttClient, mqttConnectedCb); MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb); MQTT_OnPublished(&mqttClient, mqttPublishedCb); MQTT_OnData(&mqttClient, mqttDataCb); INFO("device_ID:%s\r\n",sysCfg.device_id); INFO("MQTTHOST:%s\r\n",sysCfg.mqtt_host); //DS18B20 timers os_timer_disarm(&ds18b20_timer); os_timer_setfn(&ds18b20_timer, (os_timer_func_t *)ds18b20_cb, (void *)0); os_timer_arm(&ds18b20_timer, DELAY, 1); // DHT22 initialize DHTInit(DHT22, DELAY); os_timer_disarm(&dht22_timer); os_timer_setfn(&dht22_timer, (os_timer_func_t *)dht22_cb, (void *)0); os_timer_arm(&dht22_timer, DELAY, 1); // INPUT PIN initialize ETS_GPIO_INTR_DISABLE(); // Disable gpio interrupts ETS_GPIO_INTR_ATTACH(read_input_pin, 13); // GPIO13 interrupt handler PIN_FUNC_SELECT(PIN_GPIO13_MUX, PIN_GPIO13_FUNC); gpio_output_set(0, 0, 0, BIT13); // Set GPIO13 as input PIN_PULLUP_EN(PIN_GPIO13_MUX); // Enable pullup GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(13)); // Clear GPIO12 status gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_NEGEDGE); // Interrupt on NEGATIVE GPIO13 edge ETS_GPIO_INTR_ENABLE(); // Enable gpio interrupts // INFO("Input pin INITIALIZED ! ! !"); // initialize GPIO12 PIN_FUNC_SELECT(PIN_GPIO12_MUX, PIN_GPIO12_FUNC); GPIO_OUTPUT_SET(PIN_GPIO12, 0); // INFO("GPIO12 set to OFF\r\n"); // initialize GPIO5 GPIO_OUTPUT_SET(PIN_GPIO5, 0); // INFO("GPIO5 set to OFF\r\n"); // initialize GPIO14 PIN_FUNC_SELECT(PIN_GPIO14_MUX, PIN_GPIO14_FUNC); GPIO_OUTPUT_SET(PIN_GPIO14, 0); // INFO("GPIO14 set to OFF\r\n"); WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb); os_printf("\nReady\n"); }
LOCAL char supla_esp_key_intr_handler(uint32 gpio_status) { #if defined(INPUT_PORT1) || defined(INPUT_PORT2) char start_timer = 0; #if defined(INPUT_PORT1) if ( gpio_status & BIT(INPUT_PORT1) ) { if ( gpio_status & BIT(INPUT_PORT1) ) GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(INPUT_PORT1)); start_timer = 1; } #endif #if defined(INPUT_PORT2) if ( gpio_status & BIT(INPUT_PORT2) ) { if ( gpio_status & BIT(INPUT_PORT2) ) GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(INPUT_PORT2)); start_timer = 1; } #endif if ( start_timer == 1 ) { os_timer_disarm(&supla_gpio_timer3); os_timer_setfn(&supla_gpio_timer3, supla_esp_gpio_check_inputs, NULL); os_timer_arm (&supla_gpio_timer3, 500, false); } #endif char handler_result = 0; #if defined(ZAM_INPUT1) if ( supla_esp_key_intr_zam_handler(gpio_status, ZAM_INPUT1, supla_esp_cfg.Button1Type) == 1 ) handler_result = 1; #endif #if defined(ZAM_INPUT2) if ( supla_esp_key_intr_zam_handler(gpio_status, ZAM_INPUT2, supla_esp_cfg.Button2Type) == 1 ) handler_result = 1; #endif if ( handler_result == 1 ) return 1; if ( supla_esp_cfg.CfgButtonType == BTN_TYPE_SWITCH ) { if ( gpio_status & BIT(CFG_PORT) ) { GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(CFG_PORT)); if ( switch_cfgbtn_state_check == 0 ) { switch_cfgbtn_state_check = 1; os_timer_disarm(&supla_gpio_timer4); os_timer_setfn(&supla_gpio_timer4, supla_esp_gpio_check_switch_cfgbtn, (void*)CFG_PORT); os_timer_arm (&supla_gpio_timer4, 50, false); } return 1; } }; return 0; }
void Softuart_Init(Softuart *s, uint16_t baudrate) { //disable rs485 s->is_rs485 = 0; if(! _Softuart_Instances_Count) { os_printf("SOFTUART initialize gpio\r\n"); //Initilaize gpio subsystem gpio_init(); } //set bit time s->bit_time = (1000000 / baudrate); os_printf("SOFTUART bit_time is %d\r\n",s->bit_time); //init tx pin if(!s->pin_tx.gpio_mux_name) { os_printf("SOFTUART ERROR: Set tx pin (%d)\r\n",s->pin_tx.gpio_mux_name); } else { //enable pin as gpio PIN_FUNC_SELECT(s->pin_tx.gpio_mux_name, s->pin_tx.gpio_func); //set pullup (UART idle is VDD) PIN_PULLUP_EN(s->pin_tx.gpio_mux_name); //set high for tx idle GPIO_OUTPUT_SET(GPIO_ID_PIN(s->pin_tx.gpio_id), 1); os_delay_us(100000); os_printf("SOFTUART TX INIT DONE\r\n"); } //init rx pin if(!s->pin_rx.gpio_mux_name) { os_printf("SOFTUART ERROR: Set rx pin (%d)\r\n",s->pin_rx.gpio_mux_name); } else { //enable pin as gpio PIN_FUNC_SELECT(s->pin_rx.gpio_mux_name, s->pin_rx.gpio_func); //set pullup (UART idle is VDD) PIN_PULLUP_EN(s->pin_rx.gpio_mux_name); //set to input -> disable output GPIO_DIS_OUTPUT(GPIO_ID_PIN(s->pin_rx.gpio_id)); //set interrupt related things //disable interrupts by GPIO ETS_GPIO_INTR_DISABLE(); //attach interrupt handler and a pointer that will be passed around each time ETS_GPIO_INTR_ATTACH(Softuart_Intr_Handler, s); //not sure what this does... (quote from example): // void gpio_register_set(uint32 reg_id, uint32 value); // // From include file // Set the specified GPIO register to the specified value. // This is a very general and powerful interface that is not // expected to be used during normal operation. It is intended // mainly for debug, or for unusual requirements. // // All people repeat this mantra but I don't know what it means // gpio_register_set(GPIO_PIN_ADDR(s->pin_rx.gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); //clear interrupt handler status, basically writing a low to the output GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(s->pin_rx.gpio_id)); //enable interrupt for pin on any edge (rise and fall) //@TODO: should work with ANYEDGE (=3), but complie error gpio_pin_intr_state_set(GPIO_ID_PIN(s->pin_rx.gpio_id), 3); //globally enable GPIO interrupts ETS_GPIO_INTR_ENABLE(); os_printf("SOFTUART RX INIT DONE\r\n"); } //add instance to array of instances _Softuart_GPIO_Instances[s->pin_rx.gpio_id] = s; _Softuart_Instances_Count++; os_printf("SOFTUART INIT DONE\r\n"); }
static void ICACHE_FLASH_ATTR gpio_intr(void *arg) { uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); static uint32_t start = 0; uint32_t now = system_get_time(); uint32_t delta=(now - start) / USECPERTICK + 1; switch(irparams.rcvstate){ case STATE_IDLE: //check if val =1 if(0==(gpio_status&(1<<irparams.recvpin)))goto l_Error; irparams.rcvstate = STATE_MARK; break; case STATE_MARK: //l_Error://check if new cmd come if (MATCH_MARK(delta, NEC_HDR_MARK)){ // Initial mark irparams.rcvstate = STATE_SPACE; break; } l_Error: irparams.rcvstate = STATE_IDLE; os_timer_disarm(&timer); return; case STATE_SPACE: // Initial space if (MATCH_SPACE(delta, NEC_HDR_SPACE)) { irparams.rcvstate = STATE_DATA_MARK; irparams.BitExpected=NEC_BITS; irparams.isRepeat=false; break; } if (MATCH_SPACE(delta, NEC_RPT_SPACE)) { irparams.rcvstate = STATE_REPEAT; break; } goto l_Error; case STATE_REPEAT: if (MATCH_SPACE(delta, NEC_BIT_MARK)) { //repeat previous command need check time out if((irparams.Rpt_TimeOut-now)>((NEC_RPT_TIMEOUT-1)*USECPERTICK))return; irparams.isRepeat=true; irparams.buffer=irparams.PrevValue; goto l_CMD_RETURN; } goto l_Error; case STATE_DATA_MARK: if (MATCH_SPACE(delta, NEC_BIT_MARK)) { irparams.rcvstate = STATE_DATA; break; } goto l_Error; case STATE_DATA: irparams.rcvstate = STATE_DATA_MARK; irparams.buffer<<=1; irparams.BitExpected--; if(0==irparams.BitExpected)irparams.rcvstate = STATE_END_OF_MSG; if (MATCH_SPACE(delta, NEC_ONE_SPACE)) { irparams.buffer|=1; break; } if (MATCH_SPACE(delta, NEC_ZERO_SPACE)) { break; } goto l_Error; case STATE_END_OF_MSG: if (MATCH_SPACE(delta, NEC_BIT_MARK)) { l_CMD_RETURN: if(false==irparams.isValueReady)// skip if previous was not readet irparams.Value=irparams.buffer; irparams.rcvstate = STATE_IDLE; irparams.isValueReady=true; irparams.Rpt_TimeOut=now; irparams.PrevValue=irparams.buffer; return; } goto l_Error; } start = now; os_timer_disarm(&timer); os_timer_arm(&timer, 15, 0); }