Beispiel #1
0
/**
 * @brief System main loop called by the ETS
 *
 * This function is called by ETS after all initializations has been
 * finished to start periodic processing of defined ETS tasks. We
 * overwrite this ETS function to take over the control and to start RIOT.
 */
void ets_run(void)
{
    #if ENABLE_DEBUG
    register uint32_t *sp __asm__ ("a1");
    ets_uart_printf("_stack      %p\n", sp);
    ets_uart_printf("_bss_start  %p\n", &_bss_start);
    ets_uart_printf("_bss_end    %p\n", &_bss_end);
    ets_uart_printf("_heap_start %p\n", &_sheap);
    ets_uart_printf("_heap_end   %p\n", &_eheap);
    ets_uart_printf("_heap_free  %lu\n", get_free_heap_size());
    #endif

    /* init min task priority */
    ets_task_min_prio = 0;

    #ifdef MODULE_NEWLIB_SYSCALLS_DEFAULT
    _init();
    #endif

    ets_tasks_init();

    /* enable interrupts used by ETS/SDK */
    #ifndef MODULE_ESP_SDK_INT_HANDLING
    ets_isr_unmask(BIT(ETS_FRC2_INUM));
    ets_isr_unmask(BIT(ETS_WDEV_INUM));
    ets_isr_unmask(BIT(ETS_WDT_INUM));
    #endif

    #ifdef MODULE_ESP_GDBSTUB
    gdbstub_init();
    #endif

    #if ENABLE_DEBUG==0
    /* disable SDK messages */
    system_set_os_print(0);
    #endif

    #ifdef CONTEXT_SWITCH_BY_INT
    extern void IRAM thread_yield_isr(void* arg);
    ets_isr_attach(ETS_SOFT_INUM, thread_yield_isr, NULL);
    ets_isr_unmask(BIT(ETS_SOFT_INUM));
    #endif

    /* initialize dummy lwIP library to link it even if esp_wifi is not used */
    extern void esp_lwip_init(void);
    esp_lwip_init();

    thread_create(ets_task_stack, sizeof(ets_task_stack),
            ETS_TASK_PRIORITY,
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
            ets_task_func, NULL, "ets");


    /* does not return */
    kernel_init();
}
Beispiel #2
0
void ICACHE_FLASH_ATTR init_GPIOs_intr(void)
{
	if(GPIO_TEST1 == GPIO_TEST2 || GPIO_TEST1 > 15 || GPIO_TEST1 > 15) {
		GPIO_TEST1 = 4;
		GPIO_TEST2 = 5;
	}
//	ets_isr_mask(1 << ETS_GPIO_INUM); // запрет прерываний GPIOs
	// чтение пользовательских констант (0 < idx < 4) из записей в Flash
	GPIO_INT_Counter1 = read_user_const(1);
	GPIO_INT_Counter2 = read_user_const(2);

	system_os_task(task_GPIOs_intr, GPIOs_intr_TASK_PRIO, GPIOs_intr_taskQueue, GPIOs_intr_TASK_QUEUE_LEN);

	uint32 pins_mask = (1<<GPIO_TEST1) | (1<<GPIO_TEST2);
	gpio_output_set(0,0,0, pins_mask); // настроить GPIOx на ввод
	set_gpiox_mux_func_ioport(GPIO_TEST1); // установить функцию GPIOx в режим порта i/o
	set_gpiox_mux_func_ioport(GPIO_TEST2); // установить функцию GPIOx в режим порта i/o
//	GPIO_ENABLE_W1TC = pins_mask; // GPIO OUTPUT DISABLE отключить вывод в портах
	ets_isr_attach(ETS_GPIO_INUM, GPIOs_intr_handler, NULL);
    gpio_pin_intr_state_set(GPIO_TEST1, GPIO_PIN_INTR_ANYEDGE); // GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE ?
    gpio_pin_intr_state_set(GPIO_TEST2, GPIO_PIN_INTR_ANYEDGE); // GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE ?
    // разрешить прерывания GPIOs
	GPIO_STATUS_W1TC = pins_mask;
	ets_isr_unmask(1 << ETS_GPIO_INUM);
	GPIO_INTR_INIT = 1;
	GPIO_INT_init_flg = 1;
	os_printf("GPIOs_intr init (%d,%d) ", GPIO_TEST1, GPIO_TEST2);
}
Beispiel #3
0
int do_flash_write(uint32_t addr, uint32_t len, uint32_t erase) {
  struct uart_buf ub;
  uint8_t digest[16];
  uint32_t num_written = 0, num_erased = 0;
  struct MD5Context ctx;
  MD5Init(&ctx);

  if (addr % FLASH_SECTOR_SIZE != 0) return 0x32;
  if (len % FLASH_SECTOR_SIZE != 0) return 0x33;
  if (SPIUnlock() != 0) return 0x34;

  ub.nr = 0;
  ub.pr = ub.pw = ub.data;
  ets_isr_attach(ETS_UART_INUM, uart_isr, &ub);
  SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RX_INTS);
  ets_isr_unmask(1 << ETS_UART_INUM);

  SLIP_send(&num_written, 4);

  while (num_written < len) {
    volatile uint32_t *nr = &ub.nr;
    /* Prepare the space ahead. */
    while (erase && num_erased < num_written + SPI_WRITE_SIZE) {
      const uint32_t num_left = (len - num_erased);
      if (num_left > FLASH_BLOCK_SIZE && addr % FLASH_BLOCK_SIZE == 0) {
        if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x35;
        num_erased += FLASH_BLOCK_SIZE;
      } else {
        /* len % FLASH_SECTOR_SIZE == 0 is enforced, no further checks needed */
        if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x36;
        num_erased += FLASH_SECTOR_SIZE;
      }
    }
    /* Wait for data to arrive. */
    while (*nr < SPI_WRITE_SIZE) {
    }
    MD5Update(&ctx, ub.pr, SPI_WRITE_SIZE);
    if (SPIWrite(addr, ub.pr, SPI_WRITE_SIZE) != 0) return 0x37;
    ets_intr_lock();
    *nr -= SPI_WRITE_SIZE;
    ets_intr_unlock();
    num_written += SPI_WRITE_SIZE;
    addr += SPI_WRITE_SIZE;
    ub.pr += SPI_WRITE_SIZE;
    if (ub.pr >= ub.data + UART_BUF_SIZE) ub.pr = ub.data;
    SLIP_send(&num_written, 4);
  }

  ets_isr_mask(1 << ETS_UART_INUM);

  MD5Final(digest, &ctx);
  SLIP_send(digest, 16);

  return 0;
}
Beispiel #4
0
void timer0_init(void *func, uint32 par)
#endif
{
#if DEBUGSOO > 3
	os_printf("timer0_init(%d)\n", flg);
#endif
	timer0_stop();
	timer0_cb = func;
	timer0_arg = par;
#ifdef TIMER0_USE_NMI_VECTOR
	if(nmi_flg) {
		DPORT_BASE[0] |= 0x0F;
	}
	else
#endif
	{
		DPORT_BASE[0] = 0;
		ets_isr_attach(ETS_FRC_TIMER0_INUM, _timer0_isr, NULL);
	}
	ets_isr_unmask(BIT(ETS_FRC_TIMER0_INUM));
}
Beispiel #5
0
void ICACHE_FLASH_ATTR timer0_start(uint32 us, bool repeat_flg)
{
	TIMER0_LOAD = 0xFFFFFFFF;
	if(repeat_flg) {
		TIMER0_CTRL =   TM_DIVDED_BY_16
		                  | TM_AUTO_RELOAD_CNT
		                  | TM_ENABLE_TIMER
		                  | TM_EDGE_INT;
	}
	else {
		TIMER0_CTRL =   TM_DIVDED_BY_16
		                  | TM_ENABLE_TIMER
		                  | TM_EDGE_INT;
	}
	if(us < 5) {
		TIMER0_LOAD = 40;
	}
	else if(us <= 1677721) {
		TIMER0_LOAD = us * 5;
	}
	ets_isr_unmask(BIT(ETS_FRC_TIMER0_INUM));
	INTC_EDGE_EN |= BIT(1);
}
Beispiel #6
0
//Initialize I2S subsystem for DMA circular buffer use
void ICACHE_FLASH_ATTR ws2812_init()
{
	int x, y;
	
	//Reset DMA
	SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST);
	CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST);

	//Clear DMA int flags
	SET_PERI_REG_MASK(SLC_INT_CLR,  0xffffffff);
	CLEAR_PERI_REG_MASK(SLC_INT_CLR,  0xffffffff);

	//Enable and configure DMA
	CLEAR_PERI_REG_MASK(SLC_CONF0, (SLC_MODE<<SLC_MODE_S));
	SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S));
	SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE);
	CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);

	i2sBufDescOut.owner = 1;
	i2sBufDescOut.eof = 1;
	i2sBufDescOut.sub_sof = 0;
	i2sBufDescOut.datalen = WS_BLOCKSIZE;  //Size (in bytes)
	i2sBufDescOut.blocksize = WS_BLOCKSIZE; //Size (in bytes)
	i2sBufDescOut.buf_ptr=(uint32_t)&i2sBlock[0];
	i2sBufDescOut.unused=0;
	i2sBufDescOut.next_link_ptr=(uint32_t)&i2sBufDescZeroes; //At the end, just redirect the DMA to the zero buffer.

	i2sBufDescZeroes.owner = 1;
	i2sBufDescZeroes.eof = 1;
	i2sBufDescZeroes.sub_sof = 0;
	i2sBufDescZeroes.datalen = 32;
	i2sBufDescZeroes.blocksize = 32;
	i2sBufDescZeroes.buf_ptr=(uint32_t)&i2sZeroes[0];
	i2sBufDescZeroes.unused=0;
	i2sBufDescZeroes.next_link_ptr=(uint32_t)&i2sBufDescOut;


	for( x = 0; x < 32; x++ )
	{
		i2sZeroes[x] = 0x00;
	}
	for( x = 0; x < WS_BLOCKSIZE/4; x++ )
	{
		i2sBlock[x] = 0x00000000;//(x == 0 || x == 999)?0xaa:0x00;
	
/*		uint16_t * tt = (uint16_t*)&i2sBlock[x];
		(*(tt+0)) = 0xA0F0;
		(*(tt+1)) = 0xC0E0;*/

	}


//	CLEAR_PERI_REG_MASK(SLC_TX_LINK,SLC_TXLINK_DESCADDR_MASK);
//	SET_PERI_REG_MASK(SLC_TX_LINK, ((uint32)&i2sBufDescZeroes) & SLC_TXLINK_DESCADDR_MASK); //any random desc is OK, we don't use TX but it needs something valid

	CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
	SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDescOut) & SLC_RXLINK_DESCADDR_MASK);

#ifdef USE_2812_INTERRUPTS

	//Attach the DMA interrupt
	ets_isr_attach(ETS_SLC_INUM, slc_isr);
	//Enable DMA operation intr
	WRITE_PERI_REG(SLC_INT_ENA,  SLC_RX_EOF_INT_ENA);
	//clear any interrupt flags that are set
	WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
	///enable DMA intr in cpu
	ets_isr_unmask(1<<ETS_SLC_INUM);

#endif

	//Start transmission
//	SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START);
	SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);

//----

	//Init pins to i2s functions
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA);
//	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_I2SO_WS);
//	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_I2SO_BCK);

	//Enable clock to i2s subsystem
	i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);

	//Reset I2S subsystem
	CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
	SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
	CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);

	//Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only)
	CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S));
	//Enable DMA in i2s subsystem
	SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);

	//tx/rx binaureal
//	CLEAR_PERI_REG_MASK(I2SCONF_CHAN, (I2S_TX_CHAN_MOD<<I2S_TX_CHAN_MOD_S)|(I2S_RX_CHAN_MOD<<I2S_RX_CHAN_MOD_S));

#ifdef USE_2812_INTERRUPTS

	//Clear int
	SET_PERI_REG_MASK(I2SINT_CLR,  
			I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
	CLEAR_PERI_REG_MASK(I2SINT_CLR, 
			I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);

#endif

	//trans master&rece slave,MSB shift,right_first,msb right

	CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
						(I2S_BITS_MOD<<I2S_BITS_MOD_S)|
						(I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
						(I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));
	SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
						I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
						(((WS_I2S_BCK-1)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
						(((WS_I2S_DIV-1)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S));


	//No idea if ints are needed...
	//clear int
	SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
	CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
	//enable int
	SET_PERI_REG_MASK(I2SINT_ENA,  I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA);


	//Start transmission
	SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START);
}
Beispiel #7
0
void cmd_loop() {
  while(1) {
    /* Wait for a command */
    while(ub.command == NULL) { }
    esp_command_req_t *command = ub.command;
    ub.command = NULL;
    /* provide easy access for 32-bit data words */
    uint32_t *data_words = (uint32_t *)command->data_buf;

    /* Send command response header */
    esp_command_response_t resp = {
      .resp = 1,
      .op_ret = command->op,
      .len_ret = 0, /* esptool.py ignores this value */
      .value = 0,
    };

    /* ESP_READ_REG is the only command that needs to write into the
       'resp' structure before we send it back. */
    if (command->op == ESP_READ_REG && command->data_len == 4) {
      resp.value = REG_READ(data_words[0]);
    }

    /* Send the command response. */
    SLIP_send_frame_delimiter();
    SLIP_send_frame_data_buf(&resp, sizeof(esp_command_response_t));

    if(command->data_len > MAX_WRITE_BLOCK+16) {
      SLIP_send_frame_data(ESP_BAD_DATA_LEN);
      SLIP_send_frame_data(0xEE);
      SLIP_send_frame_delimiter();
      continue;
    }

    /* ... some commands will insert in-frame response data
       between here and when we send the end of the frame */

    esp_command_error error = ESP_CMD_NOT_IMPLEMENTED;
    int status = 0;

    /* First stage of command processing - before sending error/status */
    switch (command->op) {
    case ESP_ERASE_FLASH:
      error = verify_data_len(command, 0) || SPIEraseChip();
      break;
    case ESP_ERASE_REGION:
      /* Params for ERASE_REGION are addr, len */
      error = verify_data_len(command, 8) || handle_flash_erase(data_words[0], data_words[1]);
      break;
    case ESP_SET_BAUD:
      /* ESP_SET_BAUD sends two args, we ignore the second one */
      error = verify_data_len(command, 8);
      /* actual baud setting happens after we send the reply */
      break;
    case ESP_READ_FLASH:
      error = verify_data_len(command, 16);
      /* actual data is sent after we send the reply */
      break;
    case ESP_FLASH_VERIFY_MD5:
      /* unsure why the MD5 command has 4 params but we only pass 2 of them,
         but this is in ESP32 ROM so we can't mess with it.
      */
      error = verify_data_len(command, 16) || handle_flash_get_md5sum(data_words[0], data_words[1]);
      break;
    case ESP_FLASH_BEGIN:
      /* parameters (interpreted differently to ROM flasher):
         0 - erase_size (used as total size to write)
         1 - num_blocks (ignored)
         2 - block_size (should be MAX_WRITE_BLOCK, relies on num_blocks * block_size >= erase_size)
         3 - offset (used as-is)
       */
        if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) {
            error = ESP_BAD_BLOCKSIZE;
        } else {
            error = verify_data_len(command, 16) || handle_flash_begin(data_words[0], data_words[3]);
        }
      break;
    case ESP_FLASH_DEFLATED_BEGIN:
      /* parameters:
         0 - uncompressed size
         1 - num_blocks (based on compressed size)
         2 - block_size (should be MAX_WRITE_BLOCK, total bytes over serial = num_blocks * block_size)
         3 - offset (used as-is)
      */
        if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) {
            error = ESP_BAD_BLOCKSIZE;
        } else {
            error = verify_data_len(command, 16) || handle_flash_deflated_begin(data_words[0], data_words[1] * data_words[2], data_words[3]);            }
        break;
    case ESP_FLASH_DATA:
    case ESP_FLASH_DEFLATED_DATA:
      /* ACK DATA commands immediately, then process them a few lines down,
         allowing next command to buffer */
      if(is_in_flash_mode()) {
        error = get_flash_error();
        int payload_len = command->data_len - 16;
        if (data_words[0] != payload_len) {
          /* First byte of data payload header is length (repeated) as a word */
          error = ESP_BAD_DATA_LEN;
        }
        uint8_t data_checksum = calculate_checksum(command->data_buf + 16, payload_len);
        if (data_checksum != command->checksum) {
          error = ESP_BAD_DATA_CHECKSUM;
        }
      }
      else {
        error = ESP_NOT_IN_FLASH_MODE;
      }
      break;
    case ESP_FLASH_END:
    case ESP_FLASH_DEFLATED_END:
      error = handle_flash_end();
      break;
    case ESP_SPI_SET_PARAMS:
      /* data params: fl_id, total_size, block_size, sector_Size, page_size, status_mask */
      error = verify_data_len(command, 24) || handle_spi_set_params(data_words, &status);
      break;
    case ESP_SPI_ATTACH:
      /* parameter is 'hspi mode' (0, 1 or a pin mask for ESP32. Ignored on ESP8266.) */
      error = verify_data_len(command, 4) || handle_spi_attach(data_words[0]);
      break;
    case ESP_WRITE_REG:
      /* params are addr, value, mask (ignored), delay_us (ignored) */
      error = verify_data_len(command, 16);
      if (error == ESP_OK) {
        REG_WRITE(data_words[0], data_words[1]);
      }
      break;
    case ESP_READ_REG:
      /* actual READ_REG operation happens higher up */
      error = verify_data_len(command, 4);
      break;
    case ESP_MEM_BEGIN:
        error = verify_data_len(command, 16) || handle_mem_begin(data_words[0], data_words[3]);
        break;
    case ESP_MEM_DATA:
        error = handle_mem_data(command->data_buf + 16, command->data_len - 16);
        break;
    case ESP_MEM_END:
        error = verify_data_len(command, 8) || handle_mem_finish();
        break;
    case ESP_RUN_USER_CODE:
        /* Returning from here will run user code, ie standard boot process

           This command does not send a response.
        */
        return;
    }

    SLIP_send_frame_data(error);
    SLIP_send_frame_data(status);
    SLIP_send_frame_delimiter();

    /* Some commands need to do things after after sending this response */
    if (error == ESP_OK) {
      switch(command->op) {
      case ESP_SET_BAUD:
        ets_delay_us(10000);
        uart_div_modify(0, baud_rate_to_divider(data_words[0]));
        ets_delay_us(1000);
        break;
      case ESP_READ_FLASH:
        /* args are: offset, length, block_size, max_in_flight */
        handle_flash_read(data_words[0], data_words[1], data_words[2],
                          data_words[3]);
        break;
      case ESP_FLASH_DATA:
        /* drop into flashing mode, discard 16 byte payload header */
        handle_flash_data(command->data_buf + 16, command->data_len - 16);
        break;
      case ESP_FLASH_DEFLATED_DATA:
        handle_flash_deflated_data(command->data_buf + 16, command->data_len - 16);
        break;
      case ESP_FLASH_DEFLATED_END:
      case ESP_FLASH_END:
        /* passing 0 as parameter for ESP_FLASH_END means reboot now */
        if (data_words[0] == 0) {
          /* Flush the FLASH_END response before rebooting */
#ifdef ESP32
          uart_tx_flush(0);
#endif
          ets_delay_us(10000);
          software_reset();
        }
        break;
      case ESP_MEM_END:
          if (data_words[1] != 0) {
              void (*entrypoint_fn)(void) = (void (*))data_words[1];
              /* this is a little different from the ROM loader,
                 which exits the loader routine and _then_ calls this
                 function. But for our purposes so far, having a bit of
                 extra stuff on the stack doesn't really matter.
              */
              entrypoint_fn();
          }
          break;
      }
    }
  }
}


extern uint32_t _bss_start;
extern uint32_t _bss_end;

void __attribute__((used)) stub_main();


#ifdef ESP8266
__asm__ (
  ".global stub_main_8266\n"
  ".literal_position\n"
  ".align 4\n"
  "stub_main_8266:\n"
/* ESP8266 wrapper for "stub_main()" manipulates the return address in
 * a0, so 'return' from here runs user code.
 *
 * After setting a0, we jump directly to stub_main_inner() which is a
 * normal C function
 *
 * Adapted from similar approach used by Cesanta Software for ESP8266
 * flasher stub.
 *
 */
  "movi a0, 0x400010a8;"
  "j stub_main;");
#endif

/* This function is called from stub_main, with return address
   reset to point to user code. */
void stub_main()
{
  const uint32_t greeting = 0x4941484f; /* OHAI */

  /* this points to stub_main now, clear for next boot */
  ets_set_user_start(0);

  /* zero bss */
  for(uint32_t *p = &_bss_start; p < &_bss_end; p++) {
    *p = 0;
  }

  SLIP_send(&greeting, 4);

  /* All UART reads come via uart_isr */
  ub.reading_buf = ub.buf_a;
  ets_isr_attach(ETS_UART0_INUM, uart_isr, NULL);
  SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RX_INTS);
  ets_isr_unmask(1 << ETS_UART0_INUM);

  /* Configure default SPI flash functionality.
     Can be overriden later by esptool.py. */
#ifdef ESP8266
        SelectSpiFunction();
#else
        uint32_t spiconfig = ets_efuse_get_spiconfig();
        uint32_t strapping = REG_READ(GPIO_STRAP_REG);
        /* If GPIO1 (U0TXD) is pulled low and no other boot mode is
           set in efuse, assume HSPI flash mode (same as normal boot)
        */
        if (spiconfig == 0 && (strapping & 0x1c) == 0x08) {
            spiconfig = 1; /* HSPI flash mode */
        }
        spi_flash_attach(spiconfig, 0);
#endif
        SPIParamCfg(0, 16*1024*1024, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE,
                    FLASH_PAGE_SIZE, FLASH_STATUS_MASK);

  cmd_loop();

  /* if cmd_loop returns, it's due to ESP_RUN_USER_CODE command. */

  return;
}
Beispiel #8
0
void ws2812_dma(sdio_queue_t *i2s_pixels_queue)
{
  // Reset DMA
  SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);    //|SLC_TXLINK_RST);
  CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);  //|SLC_TXLINK_RST);

  // Clear DMA int flags
  SET_PERI_REG_MASK(SLC_INT_CLR,  0xffffffff);
  CLEAR_PERI_REG_MASK(SLC_INT_CLR,  0xffffffff);

  // Enable and configure DMA
  CLEAR_PERI_REG_MASK(SLC_CONF0,(SLC_MODE<<SLC_MODE_S));
  SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S));
  SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE);
  CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);

  // configure DMA descriptor
  CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
  SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)i2s_pixels_queue) & SLC_RXLINK_DESCADDR_MASK);

#if WS2812_USE_INTERRUPT == 1
  // Attach the DMA interrupt
  ets_isr_attach(ETS_SLC_INUM, (int_handler_t)ws2812_isr , (void *)0);
  
  //Enable DMA operation intr
//  WRITE_PERI_REG(SLC_INT_ENA,  SLC_RX_EOF_INT_ENA);
  //clear any interrupt flags that are set
  WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
  ///enable DMA intr in cpu
  ets_isr_unmask(1<<ETS_SLC_INUM);
#endif

  //Start transmission
  SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);

  //Init pins to i2s functions
  PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA);

  //Enable clock to i2s subsystem
  i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);

  //Reset I2S subsystem
  CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
  SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
  CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);

  //Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only)
  CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S));
  //Enable DMA in i2s subsystem
  SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);

  //trans master&rece slave,MSB shift,right_first,msb right
  CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
            (I2S_BITS_MOD<<I2S_BITS_MOD_S)|
            (I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
            (I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));
  SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
            I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
            (((WS_I2S_BCK-1)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
            (((WS_I2S_DIV-1)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S));

#if WS2812_USE_INTERRUPT == 1
  //clear int
  SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
  CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
  //enable int
  SET_PERI_REG_MASK(I2SINT_ENA,  I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA);
#endif

  //Start transmission
  SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START);
  
}