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); }
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); }
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; }
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); }
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); }
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; } }
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; }
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; }
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); }
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); }
// 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(); }