123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /*
- driver for RAMTRON FRAM persistent memory devices. These are used
- for parameter and waypoint storage on most FMUv1, FMUv2, FMUv3 and FMUv4
- boards
- */
- #include "AP_RAMTRON.h"
- extern const AP_HAL::HAL &hal;
- // register numbers
- #define RAMTRON_RDID 0x9f
- #define RAMTRON_READ 0x03
- #define RAMTRON_RDSR 0x05
- #define RAMTRON_WREN 0x06
- #define RAMTRON_WRITE 0x02
- /*
- list of supported devices. Thanks to NuttX ramtron driver
- */
- const AP_RAMTRON::ramtron_id AP_RAMTRON::ramtron_ids[] = {
- { 0x21, 0x00, 16, 2}, // FM25V01
- { 0x21, 0x08, 16, 2}, // FM25V01A
- { 0x22, 0x00, 32, 2}, // FM25V02
- { 0x22, 0x08, 32, 2}, // FM25V02A
- { 0x22, 0x01, 32, 2}, // FM25VN02
- { 0x23, 0x00, 64, 2}, // FM25V05
- { 0x23, 0x01, 64, 2}, // FM25VN05
- { 0x24, 0x00, 128, 3}, // FM25V10
- { 0x24, 0x01, 128, 3}, // FM25VN10
- { 0x25, 0x08, 256, 3}, // FM25V20A
- { 0x26, 0x08, 512, 3}, // CY15B104Q
- { 0x27, 0x03, 128, 3}, // MB85RS1MT
- { 0x05, 0x09, 32, 3}, // B85RS256B
- };
- // initialise the driver
- bool AP_RAMTRON::init(void)
- {
- dev = hal.spi->get_device("ramtron");
- if (!dev) {
- return false;
- }
- WITH_SEMAPHORE(dev->get_semaphore());
- struct rdid {
- uint8_t manufacturer[6];
- uint8_t memory;
- uint8_t id1;
- uint8_t id2;
- } rdid;
- if (!dev->read_registers(RAMTRON_RDID, (uint8_t *)&rdid, sizeof(rdid))) {
- return false;
- }
- for (uint8_t i=0; i<ARRAY_SIZE(ramtron_ids); i++) {
- if (ramtron_ids[i].id1 == rdid.id1 &&
- ramtron_ids[i].id2 == rdid.id2) {
- id = i;
- return true;
- }
- }
- hal.console->printf("Unknown RAMTRON manufacturer=%02x memory=%02x id1=%02x id2=%02x\n",
- rdid.manufacturer[0], rdid.memory, rdid.id1, rdid.id2);
- return false;
- }
- /*
- send a command and offset
- */
- void AP_RAMTRON::send_offset(uint8_t cmd, uint32_t offset)
- {
- if (ramtron_ids[id].addrlen == 3) {
- uint8_t b[4] = { cmd, uint8_t((offset>>16)&0xFF), uint8_t((offset>>8)&0xFF), uint8_t(offset&0xFF) };
- dev->transfer(b, sizeof(b), nullptr, 0);
- } else /* len 2 */ {
- uint8_t b[3] = { cmd, uint8_t((offset>>8)&0xFF), uint8_t(offset&0xFF) };
- dev->transfer(b, sizeof(b), nullptr, 0);
- }
- }
- // read from device
- bool AP_RAMTRON::read(uint32_t offset, uint8_t *buf, uint32_t size)
- {
- const uint8_t maxread = 128;
- while (size > maxread) {
- if (!read(offset, buf, maxread)) {
- return false;
- }
- offset += maxread;
- buf += maxread;
- size -= maxread;
- }
- WITH_SEMAPHORE(dev->get_semaphore());
- dev->set_chip_select(true);
- send_offset(RAMTRON_READ, offset);
-
- // get data
- dev->transfer(nullptr, 0, buf, size);
- dev->set_chip_select(false);
- return true;
- }
- // write to device
- bool AP_RAMTRON::write(uint32_t offset, const uint8_t *buf, uint32_t size)
- {
- WITH_SEMAPHORE(dev->get_semaphore());
- // write enable
- uint8_t r = RAMTRON_WREN;
- dev->transfer(&r, 1, nullptr, 0);
-
- dev->set_chip_select(true);
- send_offset(RAMTRON_WRITE, offset);
- dev->transfer(buf, size, nullptr, 0);
- dev->set_chip_select(false);
- return true;
- }
|