diff --git a/drivers/mtd_spi_nor/mtd_spi_nor.c b/drivers/mtd_spi_nor/mtd_spi_nor.c index 82628146ea2682b880e2ae5944c46080499ff9ef..f0ca7be4a886abf128db3263c1d52ab8569bce0e 100644 --- a/drivers/mtd_spi_nor/mtd_spi_nor.c +++ b/drivers/mtd_spi_nor/mtd_spi_nor.c @@ -78,23 +78,20 @@ const mtd_desc_t mtd_spi_nor_driver = { * @param[in] count number of bytes to read after the address has been sent */ static void mtd_spi_cmd_addr_read(const mtd_spi_nor_t *dev, uint8_t opcode, - be_uint32_t addr, void* dest, uint32_t count) + be_uint32_t addr, void *dest, uint32_t count) { TRACE("mtd_spi_cmd_addr_read: %p, %02x, (%02x %02x %02x %02x), %p, %" PRIu32 "\n", - (void *)dev, (unsigned int)opcode, addr.u8[0], addr.u8[1], addr.u8[2], - addr.u8[3], dest, count); + (void *)dev, (unsigned int)opcode, addr.u8[0], addr.u8[1], addr.u8[2], + addr.u8[3], dest, count); uint8_t *addr_buf = &addr.u8[4 - dev->addr_width]; if (ENABLE_TRACE) { TRACE("mtd_spi_cmd_addr_read: addr:"); - for (unsigned int i = 0; i < dev->addr_width; ++i) - { + for (unsigned int i = 0; i < dev->addr_width; ++i) { TRACE(" %02x", addr_buf[i]); } TRACE("\n"); } - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); do { /* Send opcode followed by address */ @@ -103,10 +100,7 @@ static void mtd_spi_cmd_addr_read(const mtd_spi_nor_t *dev, uint8_t opcode, /* Read data */ spi_transfer_bytes(dev->spi, dev->cs, false, NULL, dest, count); - } while(0); - - /* Release the bus for other threads. */ - spi_release(dev->spi); + } while (0); } /** @@ -120,23 +114,20 @@ static void mtd_spi_cmd_addr_read(const mtd_spi_nor_t *dev, uint8_t opcode, * @param[in] count number of bytes to write after the opcode has been sent */ static void mtd_spi_cmd_addr_write(const mtd_spi_nor_t *dev, uint8_t opcode, - be_uint32_t addr, const void* src, uint32_t count) + be_uint32_t addr, const void *src, uint32_t count) { TRACE("mtd_spi_cmd_addr_write: %p, %02x, (%02x %02x %02x %02x), %p, %" PRIu32 "\n", - (void *)dev, (unsigned int)opcode, addr.u8[0], addr.u8[1], addr.u8[2], - addr.u8[3], src, count); + (void *)dev, (unsigned int)opcode, addr.u8[0], addr.u8[1], addr.u8[2], + addr.u8[3], src, count); uint8_t *addr_buf = &addr.u8[4 - dev->addr_width]; if (ENABLE_TRACE) { TRACE("mtd_spi_cmd_addr_write: addr:"); - for (unsigned int i = 0; i < dev->addr_width; ++i) - { + for (unsigned int i = 0; i < dev->addr_width; ++i) { TRACE(" %02x", addr_buf[i]); } TRACE("\n"); } - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); do { /* Send opcode followed by address */ @@ -147,10 +138,7 @@ static void mtd_spi_cmd_addr_write(const mtd_spi_nor_t *dev, uint8_t opcode, if (cont) { spi_transfer_bytes(dev->spi, dev->cs, false, (void *)src, NULL, count); } - } while(0); - - /* Release the bus for other threads. */ - spi_release(dev->spi); + } while (0); } /** @@ -162,17 +150,12 @@ static void mtd_spi_cmd_addr_write(const mtd_spi_nor_t *dev, uint8_t opcode, * @param[out] dest read buffer * @param[in] count number of bytes to write after the opcode has been sent */ -static void mtd_spi_cmd_read(const mtd_spi_nor_t *dev, uint8_t opcode, void* dest, uint32_t count) +static void mtd_spi_cmd_read(const mtd_spi_nor_t *dev, uint8_t opcode, void *dest, uint32_t count) { TRACE("mtd_spi_cmd_read: %p, %02x, %p, %" PRIu32 "\n", - (void *)dev, (unsigned int)opcode, dest, count); - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); + (void *)dev, (unsigned int)opcode, dest, count); spi_transfer_regs(dev->spi, dev->cs, opcode, NULL, dest, count); - - /* Release the bus for other threads. */ - spi_release(dev->spi); } /** @@ -184,17 +167,12 @@ static void mtd_spi_cmd_read(const mtd_spi_nor_t *dev, uint8_t opcode, void* des * @param[out] src write buffer * @param[in] count number of bytes to write after the opcode has been sent */ -static void __attribute__((unused)) mtd_spi_cmd_write(const mtd_spi_nor_t *dev, uint8_t opcode, const void* src, uint32_t count) +static void __attribute__((unused)) mtd_spi_cmd_write(const mtd_spi_nor_t *dev, uint8_t opcode, const void *src, uint32_t count) { TRACE("mtd_spi_cmd_write: %p, %02x, %p, %" PRIu32 "\n", - (void *)dev, (unsigned int)opcode, src, count); - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); + (void *)dev, (unsigned int)opcode, src, count); spi_transfer_regs(dev->spi, dev->cs, opcode, (void *)src, NULL, count); - - /* Release the bus for other threads. */ - spi_release(dev->spi); } /** @@ -207,14 +185,9 @@ static void __attribute__((unused)) mtd_spi_cmd_write(const mtd_spi_nor_t *dev, static void mtd_spi_cmd(const mtd_spi_nor_t *dev, uint8_t opcode) { TRACE("mtd_spi_cmd: %p, %02x\n", - (void *)dev, (unsigned int)opcode); - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); + (void *)dev, (unsigned int)opcode); spi_transfer_byte(dev->spi, dev->cs, false, opcode); - - /* Release the bus for other threads. */ - spi_release(dev->spi); } /** @@ -242,9 +215,6 @@ static int mtd_spi_read_jedec_id(const mtd_spi_nor_t *dev, mtd_jedec_id_t *out) DEBUG("mtd_spi_read_jedec_id: rdid=0x%02x\n", (unsigned int)dev->opcode->rdid); - /* Acquire exclusive access to the bus. */ - spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); - /* Send opcode */ spi_transfer_byte(dev->spi, dev->cs, true, dev->opcode->rdid); @@ -270,21 +240,19 @@ static int mtd_spi_read_jedec_id(const mtd_spi_nor_t *dev, mtd_jedec_id_t *out) } } DEBUG("mtd_spi_read_jedec_id: bank=%u manuf=0x%02x\n", (unsigned int)jedec.bank, - (unsigned int)jedec.manuf); + (unsigned int)jedec.manuf); /* Read device ID */ if (status == 0) { spi_transfer_bytes(dev->spi, dev->cs, false, NULL, (char *)&jedec.device[0], sizeof(jedec.device)); } DEBUG("mtd_spi_read_jedec_id: device=0x%02x, 0x%02x\n", - (unsigned int)jedec.device[0], (unsigned int)jedec.device[1]); + (unsigned int)jedec.device[0], (unsigned int)jedec.device[1]); if (status == 0) { *out = jedec; } - /* Release the bus for other threads. */ - spi_release(dev->spi); return status; } @@ -312,16 +280,16 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd; DEBUG("mtd_spi_nor_init: -> spi: %lx, cs: %lx, opcodes: %p\n", - (unsigned long)dev->spi, (unsigned long)dev->cs, (void *)dev->opcode); + (unsigned long)dev->spi, (unsigned long)dev->cs, (void *)dev->opcode); DEBUG("mtd_spi_nor_init: %" PRIu32 " bytes " - "(%" PRIu32 " sectors, %" PRIu32 " bytes/sector, " - "%" PRIu32 " pages, " - "%" PRIu32 " pages/sector, %" PRIu32 " bytes/page)\n", - mtd->pages_per_sector * mtd->sector_count * mtd->page_size, - mtd->sector_count, mtd->pages_per_sector * mtd->page_size, - mtd->pages_per_sector * mtd->sector_count, - mtd->pages_per_sector, mtd->page_size); + "(%" PRIu32 " sectors, %" PRIu32 " bytes/sector, " + "%" PRIu32 " pages, " + "%" PRIu32 " pages/sector, %" PRIu32 " bytes/page)\n", + mtd->pages_per_sector * mtd->sector_count * mtd->page_size, + mtd->sector_count, mtd->pages_per_sector * mtd->page_size, + mtd->pages_per_sector * mtd->sector_count, + mtd->pages_per_sector, mtd->page_size); DEBUG("mtd_spi_nor_init: Using %u byte addresses\n", dev->addr_width); if (dev->addr_width == 0) { @@ -332,15 +300,19 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) DEBUG("mtd_spi_nor_init: CS init\n"); spi_init_cs(dev->spi, dev->cs); + spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); int res = mtd_spi_read_jedec_id(dev, &dev->jedec_id); if (res < 0) { + spi_release(dev->spi); return -EIO; } DEBUG("mtd_spi_nor_init: Found chip with ID: (%d, 0x%02x, 0x%02x, 0x%02x)\n", - dev->jedec_id.bank, dev->jedec_id.manuf, dev->jedec_id.device[0], dev->jedec_id.device[1]); + dev->jedec_id.bank, dev->jedec_id.manuf, dev->jedec_id.device[0], dev->jedec_id.device[1]); uint8_t status; mtd_spi_cmd_read(dev, dev->opcode->rdsr, &status, sizeof(status)); + spi_release(dev->spi); + DEBUG("mtd_spi_nor_init: device status = 0x%02x\n", (unsigned int)status); /* check whether page size and sector size are powers of two (most chips' are) @@ -358,7 +330,7 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) dev->page_addr_mask = mask; dev->page_addr_shift = shift; DEBUG("mtd_spi_nor_init: page_addr_mask = 0x%08" PRIx32 ", page_addr_shift = %u\n", - mask, (unsigned int)shift); + mask, (unsigned int)shift); mask = 0; shift = 0; @@ -373,7 +345,7 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) dev->sec_addr_shift = shift; DEBUG("mtd_spi_nor_init: sec_addr_mask = 0x%08" PRIx32 ", sec_addr_shift = %u\n", - mask, (unsigned int)shift); + mask, (unsigned int)shift); return 0; } @@ -381,7 +353,7 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) static int mtd_spi_nor_read(mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t size) { DEBUG("mtd_spi_nor_read: %p, %p, 0x%" PRIx32 ", 0x%" PRIx32 "\n", - (void *)mtd, dest, addr, size); + (void *)mtd, dest, addr, size); const mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd; size_t chipsize = mtd->page_size * mtd->pages_per_sector * mtd->sector_count; if (addr > chipsize) { @@ -402,7 +374,10 @@ static int mtd_spi_nor_read(mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t return 0; } be_uint32_t addr_be = byteorder_htonl(addr); + + spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); mtd_spi_cmd_addr_read(dev, dev->opcode->read, addr_be, dest, size); + spi_release(dev->spi); return size; } @@ -410,8 +385,9 @@ static int mtd_spi_nor_read(mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t static int mtd_spi_nor_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uint32_t size) { uint32_t total_size = mtd->page_size * mtd->pages_per_sector * mtd->sector_count; + DEBUG("mtd_spi_nor_write: %p, %p, 0x%" PRIx32 ", 0x%" PRIx32 "\n", - (void *)mtd, src, addr, size); + (void *)mtd, src, addr, size); if (size == 0) { return 0; } @@ -430,6 +406,7 @@ static int mtd_spi_nor_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uin } be_uint32_t addr_be = byteorder_htonl(addr); + spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); /* write enable */ mtd_spi_cmd(dev, dev->opcode->wren); @@ -438,13 +415,15 @@ static int mtd_spi_nor_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uin /* waiting for the command to complete before returning */ wait_for_write_complete(dev); + + spi_release(dev->spi); return size; } static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size) { DEBUG("mtd_spi_nor_erase: %p, 0x%" PRIx32 ", 0x%" PRIx32 "\n", - (void *)mtd, addr, size); + (void *)mtd, addr, size); mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd; uint32_t sector_size = mtd->page_size * mtd->pages_per_sector; uint32_t total_size = sector_size * mtd->sector_count; @@ -455,7 +434,7 @@ static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size) * software bugs (the erase-all-your-files kind) */ DEBUG("addr = %" PRIx32 " ~dev->erase_addr_mask = %" PRIx32 "", addr, ~dev->sec_addr_mask); DEBUG("mtd_spi_nor_erase: ERR: erase addr not aligned on %" PRIu32 " byte boundary.\n", - sector_size); + sector_size); return -EOVERFLOW; } if (addr + size > total_size) { @@ -465,6 +444,7 @@ static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size) return -EOVERFLOW; } + spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); while (size) { be_uint32_t addr_be = byteorder_htonl(addr); /* write enable */ @@ -497,6 +477,7 @@ static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size) /* waiting for the command to complete before continuing */ wait_for_write_complete(dev); } + spi_release(dev->spi); return 0; } @@ -505,6 +486,7 @@ static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power) { mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd; + spi_acquire(dev->spi, dev->cs, dev->mode, dev->clk); switch (power) { case MTD_POWER_UP: mtd_spi_cmd(dev, dev->opcode->wake); @@ -513,6 +495,7 @@ static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power) mtd_spi_cmd(dev, dev->opcode->sleep); break; } + spi_release(dev->spi); return 0; }