| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <errno.h> |
| #include <zephyr.h> |
| #include <misc/printk.h> |
| #include <device.h> |
| #include <spi.h> |
| |
| /** |
| * @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 u8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH]; |
| |
| static int mb85rs64v_access(struct device *spi, struct spi_config *spi_cfg, |
| u8_t cmd, u16_t addr, void *data, size_t len) |
| { |
| u8_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(struct device *spi, struct spi_config *spi_cfg) |
| { |
| u8_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(struct device *spi, struct spi_config *spi_cfg, |
| u16_t addr, u8_t *data, u32_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(struct device *spi, struct spi_config *spi_cfg, |
| u16_t addr, u8_t *data, u32_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; |
| } |
| |
| void main(void) |
| { |
| struct device *spi; |
| struct spi_config spi_cfg; |
| int err; |
| |
| printk("fujitsu FRAM example application\n"); |
| |
| spi = device_get_binding(CONFIG_SPI_1_NAME); |
| if (!spi) { |
| printk("Could not find SPI driver\n"); |
| return; |
| } |
| |
| spi_cfg.operation = SPI_WORD_SET(8); |
| spi_cfg.frequency = 256000; |
| |
| |
| err = mb85rs64v_read_id(spi, &spi_cfg); |
| if (err) { |
| printk("Could not verify FRAM ID\n"); |
| return; |
| } |
| |
| /* Do one-byte read/write */ |
| data[0] = 0xAE; |
| err = write_bytes(spi, &spi_cfg, 0x00, data, 1); |
| if (err) { |
| printk("Error writing to FRAM! errro code (%d)\n", err); |
| return; |
| } 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; |
| } 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; |
| } 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; |
| } 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 (u32_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; |
| } else { |
| printk("Wrote %d bytes to address 0x00.\n", |
| (u32_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; |
| } else { |
| printk("Read %d bytes from address 0x00.\n", |
| (u32_t) sizeof(data)); |
| } |
| |
| err = 0; |
| for (u32_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"); |
| } |
| } |