Ejemplo n.º 1
0
static int
pad_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct gpio_bank bank;
	struct pad_softc *sc;
	int pin_shift;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
		return (EINVAL);

	GPIO_LOCK(sc);
	if (READ4(sc, bank.port, bank.con + 0x4) & (1 << pin_shift))
		*val = 1;
	else
		*val = 0;
	GPIO_UNLOCK(sc);

	return (0);
}
Ejemplo n.º 2
0
static int
pad_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
	struct pad_softc *sc;
	struct gpio_bank bank;
	int pin_shift;
	int reg;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
		return (EINVAL);

	GPIO_LOCK(sc);
	reg = READ4(sc, bank.port, bank.con + 0x4);
	reg &= ~(PIN_OUT << pin_shift);
	if (value)
		reg |= (PIN_OUT << pin_shift);
	WRITE4(sc, bank.port, bank.con + 0x4, reg);
	GPIO_UNLOCK(sc);

	return (0);
}
Ejemplo n.º 3
0
asset* new_asset(asset_file_builder* afb, u32 code, const char* name) {
	asset_bank* b = get_bank(afb, code);
	asset* a = b->assets.push_back(new asset);

	if (!a)
		panic("new_asset: out of memory");

	name_copy(a->name, name);

	return a;
}
Ejemplo n.º 4
0
int writebyte(int myfile, int byte)
{
	struct flos_file *flosfile;

	flosfile = (char *) myfile;
	if (flosfile->name[0]==0)
		return (-1);

	if (write_bytes_to_file( (flosfile)->name, &byte, get_bank(), 1) != 0)
		return (-1);
	flosfile->position++;
	
	return (byte);
}
Ejemplo n.º 5
0
static void
pad_pin_configure(struct pad_softc *sc, struct gpio_pin *pin,
    unsigned int flags)
{
	struct gpio_bank bank;
	int pin_shift;
	int reg;

	GPIO_LOCK(sc);

	/*
	 * Manage input/output
	 */
	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);

		if (get_bank(sc, pin->gp_pin, &bank, &pin_shift) != 0)
			return;

		pin_shift *= 4;

#if 0
		printf("bank is 0x%08x pin_shift %d\n", bank.con, pin_shift);
#endif

		if (flags & GPIO_PIN_OUTPUT) {
			pin->gp_flags |= GPIO_PIN_OUTPUT;
			reg = READ4(sc, bank.port, bank.con);
			reg &= ~(0xf << pin_shift);
			reg |= (PIN_OUT << pin_shift);
			WRITE4(sc, bank.port, bank.con, reg);
		} else {
			pin->gp_flags |= GPIO_PIN_INPUT;
			reg = READ4(sc, bank.port, bank.con);
			reg &= ~(0xf << pin_shift);
			WRITE4(sc, bank.port, bank.con, reg);
		}
	}

	GPIO_UNLOCK(sc);
}
Ejemplo n.º 6
0
void flash_erase(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
    // check there is something to write
    if (num_word32 == 0) {
        return;
    }

    // unlock
    HAL_FLASH_Unlock();

    FLASH_EraseInitTypeDef EraseInitStruct;

    #if defined(MCU_SERIES_L4)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

    // erase the sector(s)
    // The sector returned by flash_get_sector_info can not be used
    // as the flash has on each bank 0/1 pages 0..255
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Banks       = get_bank(flash_dest);
    EraseInitStruct.Page        = get_page(flash_dest);
    EraseInitStruct.NbPages     = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;;
    #else
    // Clear pending flags (if any)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

    // erase the sector(s)
    EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
    EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
    EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
    #endif

    uint32_t SectorError = 0;
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
        // error occurred during sector erase
        HAL_FLASH_Lock(); // lock the flash
        return;
    }
}
Ejemplo n.º 7
0
  PathMan::DirTuple PathMan::DirIter::get_node(uint32_t index)
  {
    Dir * dir;
    DirBank * b;
    DirTuple dt = {0,0};

    if (index) {
      idx = index2idx(index);

      if ((b = get_bank())) {
        /* get */
        dir = &b->nodes[idx - b->start];
        if (dir->isused) {
          dt.node = dir;
          dt.index = index;
          return dt;
        }
      }
    }

    return dt;

  }
Ejemplo n.º 8
0
  PathMan::FileTuple PathMan::FileIter::get_node(uint32_t index)
  {
    File * file;
    FileBank * b;
    FileTuple ft = {0,0};

    if (index) {
      idx = index2idx(index);

      if ((b = get_bank())) {
        /* get */
        file = &b->nodes[idx - b->start];
        if (file->isused) {
          ft.node = file;
          ft.index = index;
          return ft;
        }
      }
    }

    return ft;

  }
Ejemplo n.º 9
0
static int
pad_attach(device_t dev)
{
	struct gpio_bank bank;
	struct pad_softc *sc;
	int pin_shift;
	int reg;
	int i;

	sc = device_get_softc(dev);

	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

	sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
	switch (sc->model) {
	case EXYNOS5250:
		sc->pad_spec = pad_spec_5250;
		sc->gpio_map = gpio_map_5250;
		sc->interrupt_table = interrupt_table_5250;
		sc->gpio_npins = 253;
		sc->nports = 4;
		break;
	case EXYNOS5420:
		sc->pad_spec = pad_spec_5420;
		sc->gpio_map = gpio_map_5420;
		sc->interrupt_table = interrupt_table_5420;
		sc->gpio_npins = 232;
		sc->nports = 5;
		break;
	default:
		goto fail;
	};

	if (bus_alloc_resources(dev, sc->pad_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		goto fail;
	}

	/* Memory interface */

	for (i = 0; i < sc->nports; i++) {
		sc->bst[i] = rman_get_bustag(sc->res[i]);
		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
	};

	sc->dev = dev;

	gpio_sc = sc;

	for (i = 0; i < sc->nports; i++) {
		if ((bus_setup_intr(dev, sc->res[sc->nports + i],
			    INTR_TYPE_BIO | INTR_MPSAFE, port_intr,
			    NULL, sc, &sc->gpio_ih[i]))) {
			device_printf(dev,
			    "ERROR: Unable to register interrupt handler\n");
			goto fail;
		}
	}

	for (i = 0; i < sc->gpio_npins; i++) {
		sc->gpio_pins[i].gp_pin = i;
		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;

		if (get_bank(sc, i, &bank, &pin_shift) != 0)
			continue;

		pin_shift *= 4;

		reg = READ4(sc, bank.port, bank.con);
		if (reg & (PIN_OUT << pin_shift))
			sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT;
		else
			sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT;

		/* TODO: add other pin statuses */

		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
		    "pad%d.%d", device_get_unit(dev), i);
	}
	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL)
		goto fail;

	return (0);

fail:
	for (i = 0; i < sc->nports; i++) {
		if (sc->gpio_ih[i])
			bus_teardown_intr(dev, sc->res[sc->nports + i],
			    sc->gpio_ih[i]);
	}
	bus_release_resources(dev, sc->pad_spec, sc->res);
	mtx_destroy(&sc->sc_mtx);

	return (ENXIO);
}
Ejemplo n.º 10
0
int
pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user)
{
	struct interrupt_entry *entry;
	struct pad_intr *pad_irq;
	struct gpio_bank bank;
	struct pad_softc *sc;
	int pin_shift;
	int reg;
	int i;

	sc = gpio_sc;

	if (sc == NULL) {
		device_printf(sc->dev, "Error: pad is not attached\n");
		return (-1);
	}

	if (get_bank(sc, gpio_number, &bank, &pin_shift) != 0)
		return (-1);

	entry = NULL;
	for (i = 0; i < N_EXT_INTS; i++)
		if (sc->interrupt_table[i].gpio_number == gpio_number)
			entry = &(sc->interrupt_table[i]);

	if (entry == NULL) {
		device_printf(sc->dev, "Cant find interrupt source for %d\n",
		    gpio_number);
		return (-1);
	}

#if 0
	printf("Request interrupt name %s\n", entry->combiner_source_name);
#endif

	pad_irq = &intr_map[gpio_number];
	pad_irq->enabled = 1;
	pad_irq->ih = ih;
	pad_irq->ih_user = ih_user;

	/* Setup port as external interrupt source */
	reg = READ4(sc, bank.port, bank.con);
	reg |= (0xf << (pin_shift * 4));
#if 0
	printf("writing 0x%08x to 0x%08x\n", reg, bank.con);
#endif
	WRITE4(sc, bank.port, bank.con, reg);

	/*
	 * Configure interrupt pin
	 *
	 * 0x0 = Sets Low level
	 * 0x1 = Sets High level
	 * 0x2 = Triggers Falling edge
	 * 0x3 = Triggers Rising edge
	 * 0x4 = Triggers Both edge
	 *
	 * TODO: add parameter. For now configure as 0x0
	 */
	reg = READ4(sc, bank.port, bank.ext_con);
	reg &= ~(0x7 << (pin_shift * 4));
	WRITE4(sc, bank.port, bank.ext_con, reg);

	/* Unmask */
	reg = READ4(sc, bank.port, bank.mask);
	reg &= ~(1 << pin_shift);
	WRITE4(sc, bank.port, bank.mask, reg);

	combiner_setup_intr(entry->combiner_source_name, ext_intr, sc);

	return (0);
}
Ejemplo n.º 11
0
// get the bank of a given flash address
static uint32_t get_bank(uint32_t addr) {
    #if defined(STM32H7)
    if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) {
    #else
    if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0) {
    #endif
        // no bank swap
        if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
            return FLASH_BANK_1;
        } else {
            return FLASH_BANK_2;
        }
    } else {
        // bank swap
        if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
            return FLASH_BANK_2;
        } else {
            return FLASH_BANK_1;
        }
    }
}

#if (defined(STM32L4) && defined(SYSCFG_MEMRMP_FB_MODE))
// get the page of a given flash address
static uint32_t get_page(uint32_t addr) {
    if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
        // bank 1
        return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
    } else {
        // bank 2
        return (addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
    }
}
#endif

#elif defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)

static uint32_t get_page(uint32_t addr) {
    return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}

#endif

uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
    if (addr >= flash_layout[0].base_address) {
        uint32_t sector_index = 0;
        for (int i = 0; i < MP_ARRAY_SIZE(flash_layout); ++i) {
            for (int j = 0; j < flash_layout[i].sector_count; ++j) {
                uint32_t sector_start_next = flash_layout[i].base_address
                    + (j + 1) * flash_layout[i].sector_size;
                if (addr < sector_start_next) {
                    if (start_addr != NULL) {
                        *start_addr = flash_layout[i].base_address
                            + j * flash_layout[i].sector_size;
                    }
                    if (size != NULL) {
                        *size = flash_layout[i].sector_size;
                    }
                    return sector_index;
                }
                ++sector_index;
            }
        }
    }
    return 0;
}

void flash_erase(uint32_t flash_dest, uint32_t num_word32) {
    // check there is something to write
    if (num_word32 == 0) {
        return;
    }

    // unlock
    HAL_FLASH_Unlock();

    FLASH_EraseInitTypeDef EraseInitStruct;

    #if defined(STM32F0)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = flash_dest;
    EraseInitStruct.NbPages     = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
    #elif  (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE))
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Page        = get_page(flash_dest);
    EraseInitStruct.NbPages     = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
    #elif defined(STM32L4)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

    // erase the sector(s)
    // The sector returned by flash_get_sector_info can not be used
    // as the flash has on each bank 0/1 pages 0..255
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Banks       = get_bank(flash_dest);
    EraseInitStruct.Page        = get_page(flash_dest);
    EraseInitStruct.NbPages     = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;;
    #else
    // Clear pending flags (if any)
    #if defined(STM32H7)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
    #else
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
    #endif

    // erase the sector(s)
    EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
    #if defined(STM32H7)
    EraseInitStruct.Banks = get_bank(flash_dest);
    #endif
    EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
    EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
    #endif

    uint32_t SectorError = 0;
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
        // error occurred during sector erase
        HAL_FLASH_Lock(); // lock the flash
        return;
    }
}

/*
// erase the sector using an interrupt
void flash_erase_it(uint32_t flash_dest, uint32_t num_word32) {
    // check there is something to write
    if (num_word32 == 0) {
        return;
    }

    // unlock
    HAL_FLASH_Unlock();

    // Clear pending flags (if any)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);

    // erase the sector(s)
    FLASH_EraseInitTypeDef EraseInitStruct;
    EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
    EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
    EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
    if (HAL_FLASHEx_Erase_IT(&EraseInitStruct) != HAL_OK) {
        // error occurred during sector erase
        HAL_FLASH_Lock(); // lock the flash
        return;
    }
}
*/

void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
    #if defined(STM32L4)

    // program the flash uint64 by uint64
    for (int i = 0; i < num_word32 / 2; i++) {
        uint64_t val = *(uint64_t*)src;
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) {
            // error occurred during flash write
            HAL_FLASH_Lock(); // lock the flash
            return;
        }
        flash_dest += 8;
        src += 2;
    }
    if ((num_word32 & 0x01) == 1) {
        uint64_t val = *(uint64_t*)flash_dest;
        val = (val & 0xffffffff00000000uL) | (*src);
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) {
            // error occurred during flash write
            HAL_FLASH_Lock(); // lock the flash
            return;
        }
    }

    #elif defined(STM32H7)

    // program the flash 256 bits at a time
    for (int i = 0; i < num_word32 / 8; i++) {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, flash_dest, (uint64_t)(uint32_t)src) != HAL_OK) {
            // error occurred during flash write
            HAL_FLASH_Lock(); // lock the flash
            return;
        }
        flash_dest += 32;
        src += 8;
    }

    #else

    // program the flash word by word
    for (int i = 0; i < num_word32; i++) {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_dest, *src) != HAL_OK) {
            // error occurred during flash write
            HAL_FLASH_Lock(); // lock the flash
            return;
        }
        flash_dest += 4;
        src += 1;
    }

    #endif

    // lock the flash
    HAL_FLASH_Lock();
}