Пример #1
0
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);
}
Пример #2
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;
}
Пример #3
0
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);
}
Пример #4
0
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();
		}
	}
}
Пример #5
0
/**
 * 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;
}
Пример #6
0
Файл: key.c Проект: lvjh/ESP8266
/******************************************************************************
 * 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);
            }
        }
    }
}
Пример #7
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;
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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;
}
Пример #11
0
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

		}
	}


}
Пример #12
0
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);
Пример #13
0
//-----------------------------------------------------------------------------------------
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
}
Пример #15
0
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;
}
Пример #16
0
//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");
}
Пример #17
0
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;
}
Пример #18
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");
}
Пример #19
0
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);
}