Lines Matching +full:reg +full:- +full:offset
4 * SPDX-License-Identifier: Apache-2.0
22 BUILD_ASSERT((FLASH_WRITE_BLK_SZ % sizeof(uint32_t)) == 0, "unsupported write-block-size");
84 struct flash_sam0_data *ctx = dev->data; in flash_sam0_sem_take()
86 k_sem_take(&ctx->sem, K_FOREVER); in flash_sam0_sem_take()
93 struct flash_sam0_data *ctx = dev->data; in flash_sam0_sem_give()
95 k_sem_give(&ctx->sem); in flash_sam0_sem_give()
99 static int flash_sam0_valid_range(off_t offset, size_t len) in flash_sam0_valid_range() argument
101 if (offset < 0) { in flash_sam0_valid_range()
102 LOG_WRN("0x%lx: before start of flash", (long)offset); in flash_sam0_valid_range()
103 return -EINVAL; in flash_sam0_valid_range()
105 if ((offset + len) > CONFIG_FLASH_SIZE * 1024) { in flash_sam0_valid_range()
106 LOG_WRN("0x%lx: ends past the end of flash", (long)offset); in flash_sam0_valid_range()
107 return -EINVAL; in flash_sam0_valid_range()
116 while (NVMCTRL->STATUS.bit.READY == 0) { in flash_sam0_wait_ready()
119 while (NVMCTRL->INTFLAG.bit.READY == 0) { in flash_sam0_wait_ready()
124 static int flash_sam0_check_status(off_t offset) in flash_sam0_check_status() argument
129 NVMCTRL_INTFLAG_Type status = NVMCTRL->INTFLAG; in flash_sam0_check_status()
132 NVMCTRL->INTFLAG.reg = status.reg; in flash_sam0_check_status()
134 NVMCTRL_STATUS_Type status = NVMCTRL->STATUS; in flash_sam0_check_status()
137 NVMCTRL->STATUS = status; in flash_sam0_check_status()
141 LOG_ERR("programming error at 0x%lx", (long)offset); in flash_sam0_check_status()
142 return -EIO; in flash_sam0_check_status()
144 LOG_ERR("lock error at 0x%lx", (long)offset); in flash_sam0_check_status()
145 return -EROFS; in flash_sam0_check_status()
147 LOG_ERR("NVM error at 0x%lx", (long)offset); in flash_sam0_check_status()
148 return -EIO; in flash_sam0_check_status()
158 * be 16 or 32 bits. 8-bit writes to the page buffer are not allowed and
161 static int flash_sam0_write_page(const struct device *dev, off_t offset, in flash_sam0_write_page() argument
166 uint32_t *dst = FLASH_MEM(offset); in flash_sam0_write_page()
170 NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY; in flash_sam0_write_page()
172 NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_PBC | NVMCTRL_CTRLB_CMDEX_KEY; in flash_sam0_write_page()
182 NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_WP | NVMCTRL_CTRLA_CMDEX_KEY; in flash_sam0_write_page()
184 NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_WP | NVMCTRL_CTRLB_CMDEX_KEY; in flash_sam0_write_page()
187 err = flash_sam0_check_status(offset); in flash_sam0_write_page()
192 if (memcmp(data, FLASH_MEM(offset), len) != 0) { in flash_sam0_write_page()
193 LOG_ERR("verify error at offset 0x%lx", (long)offset); in flash_sam0_write_page()
194 return -EIO; in flash_sam0_write_page()
200 static int flash_sam0_erase_row(const struct device *dev, off_t offset) in flash_sam0_erase_row() argument
202 *FLASH_MEM(offset) = 0U; in flash_sam0_erase_row()
204 NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY; in flash_sam0_erase_row()
206 NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_EB | NVMCTRL_CTRLB_CMDEX_KEY; in flash_sam0_erase_row()
208 return flash_sam0_check_status(offset); in flash_sam0_erase_row()
215 struct flash_sam0_data *ctx = dev->data; in flash_sam0_commit()
227 &ctx->buf[page * FLASH_PAGE_SIZE], ROW_SIZE); in flash_sam0_commit()
236 static int flash_sam0_write(const struct device *dev, off_t offset, in flash_sam0_write() argument
239 struct flash_sam0_data *ctx = dev->data; in flash_sam0_write()
243 LOG_DBG("0x%lx: len %zu", (long)offset, len); in flash_sam0_write()
245 err = flash_sam0_valid_range(offset, len); in flash_sam0_write()
261 off_t start = offset % sizeof(ctx->buf); in flash_sam0_write()
262 off_t base = offset - start; in flash_sam0_write()
263 size_t len_step = sizeof(ctx->buf) - start; in flash_sam0_write()
264 size_t len_copy = MIN(len - pos, len_step); in flash_sam0_write()
266 if (len_copy < sizeof(ctx->buf)) { in flash_sam0_write()
267 memcpy(ctx->buf, (void *)base, sizeof(ctx->buf)); in flash_sam0_write()
269 memcpy(&(ctx->buf[start]), &(pdata[pos]), len_copy); in flash_sam0_write()
272 offset += len_step; in flash_sam0_write()
289 static int flash_sam0_write(const struct device *dev, off_t offset, in flash_sam0_write() argument
295 err = flash_sam0_valid_range(offset, len); in flash_sam0_write()
300 if ((offset % FLASH_WRITE_BLK_SZ) != 0) { in flash_sam0_write()
301 LOG_WRN("0x%lx: not on a write block boundary", (long)offset); in flash_sam0_write()
302 return -EINVAL; in flash_sam0_write()
307 return -EINVAL; in flash_sam0_write()
315 size_t eop_len = FLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE); in flash_sam0_write()
319 err = flash_sam0_write_page(dev, offset, pdata, write_len); in flash_sam0_write()
324 offset += write_len; in flash_sam0_write()
326 len -= write_len; in flash_sam0_write()
344 static int flash_sam0_read(const struct device *dev, off_t offset, void *data, in flash_sam0_read() argument
349 err = flash_sam0_valid_range(offset, len); in flash_sam0_read()
354 memcpy(data, (uint8_t *)CONFIG_FLASH_BASE_ADDRESS + offset, len); in flash_sam0_read()
359 static int flash_sam0_erase(const struct device *dev, off_t offset, in flash_sam0_erase() argument
364 err = flash_sam0_valid_range(offset, ROW_SIZE); in flash_sam0_erase()
369 if ((offset % ROW_SIZE) != 0) { in flash_sam0_erase()
370 LOG_WRN("0x%lx: not on a page boundary", (long)offset); in flash_sam0_erase()
371 return -EINVAL; in flash_sam0_erase()
376 return -EINVAL; in flash_sam0_erase()
383 for (size_t addr = offset; addr < offset + size; in flash_sam0_erase()
405 off_t offset; in flash_sam0_write_protection() local
408 for (offset = 0; offset < CONFIG_FLASH_SIZE * 1024; in flash_sam0_write_protection()
409 offset += LOCK_REGION_SIZE) { in flash_sam0_write_protection()
410 NVMCTRL->ADDR.reg = offset + CONFIG_FLASH_BASE_ADDRESS; in flash_sam0_write_protection()
414 NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_LR | in flash_sam0_write_protection()
417 NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_UR | in flash_sam0_write_protection()
422 NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_LR | in flash_sam0_write_protection()
425 NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_UR | in flash_sam0_write_protection()
429 err = flash_sam0_check_status(offset); in flash_sam0_write_protection()
460 struct flash_sam0_data *ctx = dev->data; in flash_sam0_init()
462 k_sem_init(&ctx->sem, 1, 1); in flash_sam0_init()
467 PM->APBBMASK.bit.NVMCTRL_ = 1; in flash_sam0_init()
469 MCLK->APBBMASK.reg |= MCLK_APBBMASK_NVMCTRL; in flash_sam0_init()
474 NVMCTRL->CTRLB.bit.MANW = 1; in flash_sam0_init()
477 NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN_Val; in flash_sam0_init()