Esempio n. 1
0
static void vr41xx_restart(char *command)
{
    local_irq_disable();
    software_reset();
    printk(KERN_NOTICE "\nYou can reset your system\n");
    while (1) ;
}
Esempio n. 2
0
void Initialize() {
  short int i = 0;
  // variable initialization
  LQI = 0;
  RSSI2 = 0;
  SEQ_NUMBER = 0x23;
  lost_data = 0;
  address_RX_FIFO = 0x300;
  address_TX_normal_FIFO = 0;

  for (i = 0; i < 2; i++) {
    ADDRESS_short_1[i] = 1;
    ADDRESS_short_2[i] = 2;
    PAN_ID_1[i] = 3;
    PAN_ID_2[i] = 3;
  }

  for (i = 0; i < 8; i++) {
    ADDRESS_long_1[i] = 1;
    ADDRESS_long_2[i] = 2;
  }

  // Set Chip Select pin as Output
  GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_13);
  GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_10);
  GPIO_Digital_Output(&GPIOC_BASE, _GPIO_PINMASK_2);

  // Set PD0 and PD1 as digital input
  GPIO_Digital_Input(&GPIOD_BASE, _GPIO_PINMASK_0);


  Delay_ms(5);

  // SPI config
  SPI3_Init_Advanced(_SPI_FPCLK_DIV4, _SPI_MASTER  | _SPI_8_BIT |
                     _SPI_CLK_IDLE_LOW | _SPI_FIRST_CLK_EDGE_TRANSITION |
                     _SPI_MSB_FIRST | _SPI_SS_DISABLE | _SPI_SSM_ENABLE | _SPI_SSI_1,
                     &_GPIO_MODULE_SPI3_PC10_11_12);
  TFT_BLED = 1;                             // Turn on TFT Backlight

  TFT_Init(320, 240);                       // Initialize TFT display
  TFT_Fill_Screen(CL_WHITE);                // Clear Screen

  pin_reset();                              // Activate reset from pin
  software_reset();                         // Activate software reset
  RF_reset();                               // RF reset
  set_WAKE_from_pin();                      // Set wake from pin

  set_long_address(ADDRESS_long_2);         // Set long address
  set_short_address(ADDRESS_short_2);       // Set short address
  set_PAN_ID(PAN_ID_2);                     // Set PAN_ID

  init_ZIGBEE_nonbeacon();                  // Initialize ZigBee module
  nonbeacon_PAN_coordinator_device();
  set_TX_power(31);                         // Set max TX power
  set_frame_format_filter(1);               // 1 all frames, 3 data frame only
  set_reception_mode(1);                    // 1 normal mode

  pin_wake();                               // Wake from pin
}
Esempio n. 3
0
void pageShift()
{
	if(_hw->btn_rec == mgHW::hw_t::BUTTON_RELEASED) {
		software_reset();
	}
		else if(_hw->btn_shift == mgHW::hw_t::BUTTON_RELEASED) {
			PREVSTATE();
		}
}
Esempio n. 4
0
void RF23B_init_parameter(void)
{
	//unsigned char j;

	software_reset();
	read_status();
	//to_ready_mode();
	init_all_from_excel();
	
}
Esempio n. 5
0
File: pm.c Progetto: A-Paul/RIOT
void pm_reboot(void)
{
    DEBUG ("%s\n", __func__);

    /* suspend and flush UARTs */
    for (int i = 0; i < 3; ++i) {
        REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF);
        uart_tx_wait_idle(i);
    }

    software_reset();
}
Esempio n. 6
0
static int8_t on_post_door_response(int8_t cid, uint16_t status_code, GSwifi::GSREQUESTSTATE state) {
    HTTPLOG_PRINT(P("< P /d ")); HTTPLOG_PRINTLN(status_code);

    gs.bufferClear();

    if (state != GSwifi::GSREQUESTSTATE_RECEIVED) {
        return 0;
    }

    switch (status_code) {
    case 200:
        keys.setKeyValid(true);
        // save only independent area, since sharedbuffer might be populated by IR or so.
        keys.save2();
        IR_state( IR_IDLE );

        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
#ifdef USE_INTERNET
        ring_put( &commands, COMMAND_START_POLLING );
#endif

        on_irkit_ready();

        break;
#ifdef USE_INTERNET
    case 401:
    case HTTP_STATUSCODE_CLIENT_TIMEOUT:
        // keys have expired, we have to start listening for POST /wifi again
        keys.clear();
        keys.save();
        software_reset();

        break;
    case 400: // must be program bug, happens when there's no hostname parameter
    case 408:
    case 503: // heroku responds with 503 if longer than 30sec
    default:
        // retry again on next loop
        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
        ring_put( &commands, COMMAND_POST_DOOR );
        break;
#endif
    }

    return 0;
}
Esempio n. 7
0
static void vr41xx_restart(char *command)
{
	local_irq_disable();
	software_reset();
	while (1) ;
}
Esempio n. 8
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;
}
Esempio n. 9
0
static int
cmd_bfin_run (urj_chain_t *chain, char *params[])
{
    int num_params;

    num_params = urj_cmd_params (params);

    if (num_params < 2)
    {
        urj_error_set (URJ_ERROR_SYNTAX,
                       "#parameters should be >= 2, not %d",
                       num_params);
        return URJ_STATUS_FAIL;
    }

    /* The remaining commands require cable or parts.  */

    if (urj_cmd_test_cable (chain) != URJ_STATUS_OK)
        return URJ_STATUS_FAIL;

    if (!chain->parts)
    {
        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "no parts, Run '%s' first",
                       "detect");
        return URJ_STATUS_FAIL;
    }

    if (chain->active_part >= chain->parts->len)
    {
        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "no active part");
        return URJ_STATUS_FAIL;
    }

    if (!part_is_bfin (chain, chain->active_part))
    {
        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "not a Blackfin part");
        return URJ_STATUS_FAIL;
    }

    assert (chain->active_part >= 0 && chain->active_part < chain->parts->len);

    if (strcmp (params[1], "emulation") == 0)
    {
        if (num_params != 3)
        {
            urj_error_set (URJ_ERROR_BFIN,
                           "'bfin emulation' requires 1 parameter, not %d",
                           num_params - 2);
            return URJ_STATUS_FAIL;
        }

        if (strcmp (params[2], "enable") == 0)
        {
            part_emulation_enable (chain, chain->active_part);
        }
        else if (strcmp (params[2], "trigger") == 0)
        {
            part_emulation_trigger (chain, chain->active_part);
        }
        else if (strcmp (params[2], "enter") == 0)
        {
            part_emulation_enable (chain, chain->active_part);
            part_emulation_trigger (chain, chain->active_part);
        }
        else if (strcmp (params[2], "return") == 0)
        {
            part_emulation_return (chain, chain->active_part);
        }
        else if (strcmp (params[2], "disable") == 0)
        {
            part_emulation_disable (chain, chain->active_part);
        }
        else if (strcmp (params[2], "exit") == 0)
        {
            part_emulation_return (chain, chain->active_part);
            part_emulation_disable (chain, chain->active_part);
        }
        else if (strcmp (params[2], "status") == 0)
        {
            uint16_t dbgstat, excause;
            const char *str_excause;
            urj_part_t *part;

            part_dbgstat_get (chain, chain->active_part);
            part = chain->parts->parts[chain->active_part];
            dbgstat = BFIN_PART_DBGSTAT (part);
            excause = part_dbgstat_emucause (chain, chain->active_part);

            switch (excause)
            {
                case 0x0: str_excause = "EMUEXCPT was executed"; break;
                case 0x1: str_excause = "EMUIN pin was asserted"; break;
                case 0x2: str_excause = "Watchpoint event occurred"; break;
                case 0x4: str_excause = "Performance Monitor 0 overflowed"; break;
                case 0x5: str_excause = "Performance Monitor 1 overflowed"; break;
                case 0x8: str_excause = "Emulation single step"; break;
                default:  str_excause = "Reserved??"; break;
            }

            urj_log (URJ_LOG_LEVEL_NORMAL, "Core [%d] DBGSTAT = 0x%"PRIx16"\n",
                     chain->active_part, dbgstat);

            urj_log (URJ_LOG_LEVEL_NORMAL,
                     "\tEMUDOF     = %u\n"
                     "\tEMUDIF     = %u\n"
                     "\tEMUDOOVF   = %u\n"
                     "\tEMUDIOVF   = %u\n"
                     "\tEMUREADY   = %u\n"
                     "\tEMUACK     = %u\n"
                     "\tEMUCAUSE   = 0x%x (%s)\n"
                     "\tBIST_DONE  = %u\n"
                     "\tLPDEC0     = %u\n"
                     "\tIN_RESET   = %u\n"
                     "\tIDLE       = %u\n"
                     "\tCORE_FAULT = %u\n"
                     "\tLPDEC1     = %u\n",
                     part_dbgstat_is_emudof (chain, chain->active_part),
                     part_dbgstat_is_emudif (chain, chain->active_part),
                     part_dbgstat_is_emudoovf (chain, chain->active_part),
                     part_dbgstat_is_emudiovf (chain, chain->active_part),
                     part_dbgstat_is_emuready (chain, chain->active_part),
                     part_dbgstat_is_emuack (chain, chain->active_part),
                     excause, str_excause,
                     part_dbgstat_is_bist_done (chain, chain->active_part),
                     part_dbgstat_is_lpdec0 (chain, chain->active_part),
                     part_dbgstat_is_in_reset (chain, chain->active_part),
                     part_dbgstat_is_idle (chain, chain->active_part),
                     part_dbgstat_is_core_fault (chain, chain->active_part),
                     part_dbgstat_is_lpdec1 (chain, chain->active_part));
        }
        else if (strcmp (params[2], "singlestep") == 0)
        {
            part_dbgstat_get (chain, chain->active_part);

            if (!part_dbgstat_is_emuready (chain, chain->active_part))
            {
                urj_error_set (URJ_ERROR_BFIN, "Run '%s' first",
                               "bfin emulation enter");
                return URJ_STATUS_FAIL;
            }

            /* TODO  Allow an argument to specify how many single steps.  */

            part_scan_select (chain, chain->active_part, DBGCTL_SCAN);
            part_dbgctl_bit_set_esstep (chain, chain->active_part);
            urj_tap_chain_shift_data_registers_mode (chain, 0, 1, URJ_CHAIN_EXITMODE_UPDATE);
            part_emuir_set (chain, chain->active_part, INSN_RTE, URJ_CHAIN_EXITMODE_IDLE);
            part_scan_select (chain, chain->active_part, DBGCTL_SCAN);
            part_dbgctl_bit_clear_esstep (chain, chain->active_part);
            urj_tap_chain_shift_data_registers_mode (chain, 0, 1, URJ_CHAIN_EXITMODE_UPDATE);
        }
        else
        {
            urj_error_set (URJ_ERROR_BFIN,
                           "unknown emulation subcommand '%s'", params[2]);
            return URJ_STATUS_FAIL;
        }

        return URJ_STATUS_OK;
    }
    else if (strcmp (params[1], "execute") == 0)
    {
        int execute_ret = URJ_STATUS_FAIL;

        part_dbgstat_get (chain, chain->active_part);

        if (!part_dbgstat_is_emuready (chain, chain->active_part))
        {
            urj_error_set (URJ_ERROR_BFIN, "Run '%s' first",
                           "bfin emulation enter");
            return URJ_STATUS_FAIL;
        }

        if (num_params > 2)
        {
            int i;
            struct bfin_insn *insns = NULL;
            struct bfin_insn **last = &insns;
            char tmp[8];
            char *tmpfile = NULL;

            for (i = 2; i < num_params; i++)
            {
                if (params[i][0] == '[' && params[i][1] == '0')
                {
                    uint64_t n;

                    if (sscanf (params[i], "[0%[xX]%"PRIx64"]", tmp, &n) != 2)
                        goto execute_cleanup;

                    *last = (struct bfin_insn *) malloc (sizeof (struct bfin_insn));
                    if (*last == NULL)
                        goto execute_cleanup;

                    (*last)->i = n;
                    (*last)->type = BFIN_INSN_SET_EMUDAT;
                    (*last)->next = NULL;
                    last = &((*last)->next);
                }
                else if (params[i][0] == '0')
                {
                    uint64_t n;

                    if (sscanf (params[i], "0%[xX]%"PRIx64, tmp, &n) != 2)
                        goto execute_cleanup;

                    *last = (struct bfin_insn *) malloc (sizeof (struct bfin_insn));
                    if (*last == NULL)
                        goto execute_cleanup;

                    (*last)->i = n;
                    (*last)->type = BFIN_INSN_NORMAL;
                    (*last)->next = NULL;
                    last = &((*last)->next);
                }
                else
                {
#ifndef HAVE_SYS_WAIT_H
                    urj_error_set (URJ_ERROR_BFIN,
                                   "Sorry, dynamic code not available for your platform");
                    goto execute_cleanup;
#else
                    unsigned char raw_insn[4];
                    char *tmp_buf;
                    char *tuples[] = {"uclinux", "linux-uclibc", "elf"};
                    size_t t;
                    FILE *fp;

                    /* 1024 should be plenty.  */
                    char insns_string[1024];
                    char *p = insns_string;

                    for (; i < num_params; i++)
                    {
                        p += snprintf (p, sizeof (insns_string) - (p - insns_string),
                                       "%s ", params[i]);
                        if (params[i][strlen (params[i]) - 1] == '"')
                            break;
                        if (params[i][strlen (params[i]) - 1] == ';')
                            break;
                    }
                    if (i == num_params)
                    {
                        urj_error_set (URJ_ERROR_BFIN,
                                       "unbalanced double quotes");
                        goto execute_cleanup;
                    }

                    /* p points past the '\0'. p - 1 points to the ending '\0'.
                       p - 2 points to the last double quote.  */
                    *(p - 2) = ';';
                    if (insns_string[0] == '"')
                        insns_string[0] = ' ';

                    /* HRM states that branches and hardware loop setup results
                       in undefined behavior.  Should check opcode instead?  */
                    if (strcasestr(insns_string, "jump") ||
                        strcasestr(insns_string, "call") ||
                        strcasestr(insns_string, "lsetup"))
                        urj_warning (_("jump/call/lsetup insns may not work in emulation\n"));

                    /* get a temporary file to work with -- a little racy */
                    if (!tmpfile)
                    {
                        tmpfile = tmpnam (NULL);
                        if (!tmpfile)
                            goto execute_cleanup;
                        tmpfile = strdup (tmpfile);
                        if (!tmpfile)
                            goto execute_cleanup;
                    }

                    /* try to find a toolchain in $PATH */
                    for (t = 0; t < ARRAY_SIZE(tuples); ++t)
                    {
                        int ret;

                        /* TODO  Pass -mcpu= to gas.  */
                        ret = asprintf (&tmp_buf,
                                        "bfin-%3$s-as --version >/dev/null 2>&1 || exit $?;"
                                        "echo '%1$s' | bfin-%3$s-as - -o \"%2$s\""
                                        " && bfin-%3$s-objcopy -O binary \"%2$s\"",
                                        insns_string, tmpfile, tuples[t]);
                        if (ret == -1)
                        {
                            urj_error_set (URJ_ERROR_OUT_OF_MEMORY, _("asprintf() failed"));
                            goto execute_cleanup;
                        }
                        ret = system (tmp_buf);
                        free (tmp_buf);
                        if (WIFEXITED(ret))
                        {
                            if (WEXITSTATUS(ret) == 0)
                                break;
                            /* 127 -> not found in $PATH */
                            else if (WEXITSTATUS(ret) == 127)
                                continue;
                            else
                            {
                                urj_error_set (URJ_ERROR_BFIN, "GAS failed parsing: %s",
                                               insns_string);
                                goto execute_cleanup;
                            }
                        }
                    }
                    if (t == ARRAY_SIZE(tuples))
                    {
                        urj_error_set (URJ_ERROR_BFIN,
                                       "unable to find Blackfin toolchain in $PATH\n");
                        goto execute_cleanup;
                    }

                    /* Read the binary blob from the toolchain */
                    fp = fopen (tmpfile, FOPEN_R);
                    if (fp == NULL)
                        goto execute_cleanup;

                    /* Figure out how many instructions there are */
                    t = 0;
                    p = insns_string;
                    while ((p = strchr(p, ';')) != NULL)
                    {
                        ++t;
                        ++p;
                    }

                    while (t-- && fread (raw_insn, 1, 2, fp) == 2)
                    {
                        uint16_t iw = raw_insn[0] | (raw_insn[1] << 8);
                        uint64_t n = iw;
                        int is_multiinsn = INSN_IS_MULTI (raw_insn[1]);

                        if ((iw & 0xf000) >= 0xc000)
                        {
                            if (fread (raw_insn, 1, 2, fp) != 2)
                                goto execute_cleanup;

                            iw = raw_insn[0] | (raw_insn[1] << 8);
                            n = (n << 16) | iw;
                        }

                        if (is_multiinsn)
                        {
                            if (fread (raw_insn, 1, 4, fp) != 4)
                                goto execute_cleanup;

                            n = (n << 32)
                                | ((uint64_t)raw_insn[0] << 16)
                                | ((uint64_t)raw_insn[1] << 24)
                                | raw_insn[2] | (raw_insn[3] << 8);
                        }

                        *last = (struct bfin_insn *) malloc (sizeof (struct bfin_insn));
                        if (*last == NULL)
                            goto execute_cleanup;

                        (*last)->i = n;
                        (*last)->type = BFIN_INSN_NORMAL;
                        (*last)->next = NULL;
                        last = &((*last)->next);
                    }

                    fclose (fp);
#endif
                }
            }

            part_execute_instructions (chain, chain->active_part, insns);
            execute_ret = URJ_STATUS_OK;

          execute_cleanup:
            if (tmpfile)
            {
                unlink (tmpfile);
                free (tmpfile);
            }
            while (insns)
            {
                struct bfin_insn *tmp = insns->next;
                free (insns);
                insns = tmp;
            }
        }

        if (execute_ret == URJ_STATUS_OK)
        {
            uint64_t emudat;

            emudat = part_emudat_get (chain, chain->active_part, URJ_CHAIN_EXITMODE_UPDATE);
            urj_log (URJ_LOG_LEVEL_NORMAL, "EMUDAT = 0x%"PRIx64"\n", emudat);

            part_dbgstat_get (chain, chain->active_part);
            if (part_dbgstat_is_core_fault (chain, chain->active_part))
                urj_warning (_("core fault detected\n"));
        }

        return execute_ret;
    }
    else if (strcmp (params[1], "reset") == 0)
    {
        int reset_what = 0;

        part_dbgstat_get (chain, chain->active_part);

        if (!part_dbgstat_is_emuready (chain, chain->active_part))
        {
            urj_error_set (URJ_ERROR_BFIN, "Run '%s' first",
                           "bfin emulation enter");
            return URJ_STATUS_FAIL;
        }

        if (num_params == 3)
        {
            if (!strcmp (params[2], "core"))
                reset_what |= 0x1;
            else if (!strcmp (params[2], "system"))
                reset_what |= 0x2;
            else
            {
                urj_error_set (URJ_ERROR_BFIN, "bad parameter '%s'", params[2]);
                return URJ_STATUS_FAIL;
            }
        }
        else if (num_params == 2)
            reset_what = 0x1 | 0x2;
        else
        {
            urj_error_set (URJ_ERROR_BFIN,
                           "'bfin emulation' requires 0 or 1 parameter, not %d",
                           num_params - 2);
            return URJ_STATUS_FAIL;
        }

        urj_log (URJ_LOG_LEVEL_NORMAL,
                 _("%s: reseting processor ... "), "bfin");
        fflush (stdout);
        if (reset_what == 0x3)
            software_reset (chain, chain->active_part);
        else if (reset_what & 0x1)
            bfin_core_reset (chain, chain->active_part);
        else if (reset_what & 0x2)
            chain_system_reset (chain);
        urj_log (URJ_LOG_LEVEL_NORMAL, _("OK\n"));

        return URJ_STATUS_OK;
    }
    else
    {
        urj_error_set (URJ_ERROR_BFIN,
                       "unknown command '%s'", params[1]);
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}