Example #1
0
 private FlashRange getFlashRange(int address) {
   if (main_range.isInRange(address)) {
     return main_range;
   }
   if (info_range.isInRange(address)) {
     return info_range;
   }
   return null;
 }
Example #2
0
  public boolean addressInFlash(int address) {
    if (main_range.isInRange(address)) {
      return true;
    }
    if (info_range.isInRange(address)) {
      return true;
    }

    return false;
  }
Example #3
0
  public void flashWrite(int address, int data, AccessMode dataMode) {
    int wait_time = -1;

    if (locked) {
      if (DEBUG) {
        log("Write to flash blocked because of LOCK flag.");
      }
      return;
    }

    if (cpu.isFlashBusy || wait == false) {
      if (!((mode & BLKWRT) != 0 && wait)) {
        triggerAccessViolation("Flash write prohbited while BUSY=1 or WAIT=0");
        return;
      }
    }

    switch (currentWriteMode) {
      case ERASE_SEGMENT:
        int a_area_start[] = new int[1];
        int a_area_end[] = new int[1];
        getSegmentRange(address, a_area_start, a_area_end);
        int area_start = a_area_start[0];
        int area_end = a_area_end[0];

        if (DEBUG) {
          log(
              "Segment erase @"
                  + Utils.hex(address, 4)
                  + ": erasing area "
                  + Utils.hex(area_start, 4)
                  + "-"
                  + Utils.hex(area_end, 4));
        }
        for (int i = area_start; i < area_end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(SEGMENT_ERASE_TIME);
        break;

      case ERASE_MAIN:
        if (!main_range.isInRange(address)) {
          return;
        }
        for (int i = main_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(MASS_ERASE_TIME);
        break;

      case ERASE_ALL:
        for (int i = main_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        for (int i = info_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(MASS_ERASE_TIME);
        break;
      case WRITE_SINGLE:
      case WRITE_BLOCK:
        if (currentWriteMode == WriteMode.WRITE_BLOCK) {
          wait = false;
          // TODO: Register target block and verify all writes stay in the same
          // block. What does the real hardware on random writes?!?
          if (blockwriteCount == 0) {
            wait_time = BLOCKWRITE_FIRST_TIME;
            if (DEBUG) {
              log("Flash write in block mode started @" + Utils.hex(address, 4));
            }
            if (addressInFlash(cpu.getPC())) {
              logw(
                  WarningType.EXECUTION,
                  "Oops. Block write access only allowed when executing from RAM.");
            }
          } else {
            wait_time = BLOCKWRITE_TIME;
          }
        } else {
          wait_time = WRITE_TIME;
        }
        /* Flash memory allows clearing bits only */
        memory[address] &= data & 0xff;
        if (dataMode != AccessMode.BYTE) {
          memory[address + 1] &= (data >> 8) & 0xff;
          if (dataMode == AccessMode.WORD20) {
            /* TODO should the write really write the full word? CHECK THIS */
            memory[address + 2] &= (data >> 16) & 0xff;
            memory[address + 3] &= (data >> 24) & 0xff;
          }
        }
        if (DEBUG) {
          log(
              "Writing $"
                  + Utils.hex20(data)
                  + " to $"
                  + Utils.hex(address, 4)
                  + " ("
                  + dataMode.bytes
                  + " bytes)");
        }
        waitFlashProcess(wait_time);
        break;
    }
  }