/* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include /** * @file Sample app using the Fujitsu MB85RS64V FRAM through SPI. */ #define MB85RS64V_MANUFACTURER_ID_CMD 0x9f #define MB85RS64V_WRITE_ENABLE_CMD 0x06 #define MB85RS64V_READ_CMD 0x03 #define MB85RS64V_WRITE_CMD 0x02 #define MAX_USER_DATA_LENGTH 1024 static uint8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH]; static int mb85rs64v_access(const struct device *spi, struct spi_config *spi_cfg, uint8_t cmd, uint16_t addr, void *data, size_t len) { uint8_t access[3]; struct spi_buf bufs[] = { { .buf = access, }, { .buf = data, .len = len } }; struct spi_buf_set tx = { .buffers = bufs }; access[0] = cmd; if (cmd == MB85RS64V_WRITE_CMD || cmd == MB85RS64V_READ_CMD) { access[1] = (addr >> 8) & 0xFF; access[2] = addr & 0xFF; bufs[0].len = 3; tx.count = 2; if (cmd == MB85RS64V_READ_CMD) { struct spi_buf_set rx = { .buffers = bufs, .count = 2 }; return spi_transceive(spi, spi_cfg, &tx, &rx); } } else { tx.count = 1; } return spi_write(spi, spi_cfg, &tx); } static int mb85rs64v_read_id(const struct device *spi, struct spi_config *spi_cfg) { uint8_t id[4]; int err; err = mb85rs64v_access(spi, spi_cfg, MB85RS64V_MANUFACTURER_ID_CMD, 0, &id, 4); if (err) { printk("Error during ID read\n"); return -EIO; } if (id[0] != 0x04) { return -EIO; } if (id[1] != 0x7f) { return -EIO; } if (id[2] != 0x03) { return -EIO; } if (id[3] != 0x02) { return -EIO; } return 0; } static int write_bytes(const struct device *spi, struct spi_config *spi_cfg, uint16_t addr, uint8_t *data, uint32_t num_bytes) { int err; /* disable write protect */ err = mb85rs64v_access(spi, spi_cfg, MB85RS64V_WRITE_ENABLE_CMD, 0, NULL, 0); if (err) { printk("unable to disable write protect\n"); return -EIO; } /* write cmd */ err = mb85rs64v_access(spi, spi_cfg, MB85RS64V_WRITE_CMD, addr, data, num_bytes); if (err) { printk("Error during SPI write\n"); return -EIO; } return 0; } static int read_bytes(const struct device *spi, struct spi_config *spi_cfg, uint16_t addr, uint8_t *data, uint32_t num_bytes) { int err; /* read cmd */ err = mb85rs64v_access(spi, spi_cfg, MB85RS64V_READ_CMD, addr, data, num_bytes); if (err) { printk("Error during SPI read\n"); return -EIO; } return 0; } int main(void) { const struct device *spi; struct spi_config spi_cfg = {0}; int err; printk("fujitsu FRAM example application\n"); spi = DEVICE_DT_GET(DT_ALIAS(spi_1)); if (!device_is_ready(spi)) { printk("SPI device %s is not ready\n", spi->name); return 0; } spi_cfg.operation = SPI_WORD_SET(8); spi_cfg.frequency = 256000U; err = mb85rs64v_read_id(spi, &spi_cfg); if (err) { printk("Could not verify FRAM ID\n"); return 0; } /* Do one-byte read/write */ data[0] = 0xAE; err = write_bytes(spi, &spi_cfg, 0x00, data, 1); if (err) { printk("Error writing to FRAM! error code (%d)\n", err); return 0; } else { printk("Wrote 0xAE to address 0x00.\n"); } data[0] = 0x86; err = write_bytes(spi, &spi_cfg, 0x01, data, 1); if (err) { printk("Error writing to FRAM! error code (%d)\n", err); return 0; } else { printk("Wrote 0x86 to address 0x01.\n"); } data[0] = 0x00; err = read_bytes(spi, &spi_cfg, 0x00, data, 1); if (err) { printk("Error reading from FRAM! error code (%d)\n", err); return 0; } else { printk("Read 0x%X from address 0x00.\n", data[0]); } data[0] = 0x00; err = read_bytes(spi, &spi_cfg, 0x01, data, 1); if (err) { printk("Error reading from FRAM! error code (%d)\n", err); return 0; } else { printk("Read 0x%X from address 0x01.\n", data[0]); } /* Do multi-byte read/write */ /* get some random data, and clear out data[] */ for (uint32_t i = 0; i < sizeof(cmp_data); i++) { cmp_data[i] = k_cycle_get_32() & 0xFF; data[i] = 0x00; } /* write them to the FRAM */ err = write_bytes(spi, &spi_cfg, 0x00, cmp_data, sizeof(cmp_data)); if (err) { printk("Error writing to FRAM! error code (%d)\n", err); return 0; } else { printk("Wrote %d bytes to address 0x00.\n", (uint32_t) sizeof(cmp_data)); } err = read_bytes(spi, &spi_cfg, 0x00, data, sizeof(data)); if (err) { printk("Error reading from FRAM! error code (%d)\n", err); return 0; } else { printk("Read %d bytes from address 0x00.\n", (uint32_t) sizeof(data)); } err = 0; for (uint32_t i = 0; i < sizeof(cmp_data); i++) { if (cmp_data[i] != data[i]) { printk("Data comparison failed @ %d.\n", i); err = -EIO; } } if (err == 0) { printk("Data comparison successful.\n"); } return 0; }