altos/telefireone-v1.0: Track ao_led_init API change
[fw/altos] / src / drivers / ao_m25.c
index 28cb1dd73078ab71492fe033e8ba30d933888070..72617cc4504f24f18966e1a80f1be4699d2a1fc9 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 #include "ao.h"
 
 /* Total bytes of available storage */
-__pdata uint32_t       ao_storage_total;
+uint32_t       ao_storage_total;
 
 /* Block size - device is erased in these units. At least 256 bytes */
-__pdata uint32_t       ao_storage_block;
+uint32_t       ao_storage_block;
 
 /* Byte offset of config block. Will be ao_storage_block bytes long */
-__pdata uint32_t       ao_storage_config;
+uint32_t       ao_storage_config;
 
 /* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */
-__pdata uint16_t       ao_storage_unit;
+uint16_t       ao_storage_unit;
 
+#define M25_DEBUG      0
 /*
  * Each flash chip is arranged in 64kB sectors; the
  * chip cannot erase in units smaller than that.
@@ -81,13 +83,13 @@ __pdata uint16_t    ao_storage_unit;
 
 #if M25_MAX_CHIPS > 1
 static uint8_t ao_m25_size[M25_MAX_CHIPS];     /* number of sectors in each chip */
-static uint8_t ao_m25_pin[M25_MAX_CHIPS];      /* chip select pin for each chip */
+static ao_port_t ao_m25_pin[M25_MAX_CHIPS];    /* chip select pin for each chip */
 static uint8_t ao_m25_numchips;                        /* number of chips detected */
 #endif
 static uint8_t ao_m25_total;                   /* total sectors available */
-static uint8_t ao_m25_wip;                     /* write in progress */
+static ao_port_t ao_m25_wip;                   /* write in progress */
 
-static __xdata uint8_t ao_m25_mutex;
+static uint8_t ao_m25_mutex;
 
 /*
  * This little array is abused to send and receive data. A particular
@@ -97,10 +99,10 @@ static __xdata uint8_t ao_m25_mutex;
  * of which touch those last three bytes.
  */
 
-static __xdata uint8_t ao_m25_instruction[4];
+static uint8_t ao_m25_instruction[4];
 
-#define M25_SELECT(cs)         ao_spi_get_mask(SPI_CS_PORT,cs)
-#define M25_DESELECT(cs)       ao_spi_put_mask(SPI_CS_PORT,cs)
+#define M25_SELECT(cs)         ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS, AO_SPI_SPEED_FAST)
+#define M25_DESELECT(cs)       ao_spi_put_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS)
 
 #define M25_BLOCK_SHIFT                        16
 #define M25_BLOCK                      65536L
@@ -111,14 +113,14 @@ static __xdata uint8_t    ao_m25_instruction[4];
  * Block until the specified chip is done writing
  */
 static void
-ao_m25_wait_wip(uint8_t cs)
+ao_m25_wait_wip(ao_port_t cs)
 {
        if (ao_m25_wip & cs) {
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDSR;
-               ao_spi_send(ao_m25_instruction, 1);
+               ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
                do {
-                       ao_spi_recv(ao_m25_instruction, 1);
+                       ao_spi_recv(ao_m25_instruction, 1, AO_M25_SPI_BUS);
                } while (ao_m25_instruction[0] & M25_STATUS_WIP);
                M25_DESELECT(cs);
                ao_m25_wip &= ~cs;
@@ -131,11 +133,11 @@ ao_m25_wait_wip(uint8_t cs)
  * so that future operations will block until the WIP bit goes off
  */
 static void
-ao_m25_write_enable(uint8_t cs)
+ao_m25_write_enable(ao_port_t cs)
 {
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_WREN;
-       ao_spi_send(&ao_m25_instruction, 1);
+       ao_spi_send(&ao_m25_instruction, 1, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 }
@@ -145,13 +147,13 @@ ao_m25_write_enable(uint8_t cs)
  * Returns the number of 64kB sectors
  */
 static uint8_t
-ao_m25_read_capacity(uint8_t cs)
+ao_m25_read_capacity(ao_port_t cs)
 {
        uint8_t capacity;
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_RDID;
-       ao_spi_send(ao_m25_instruction, 1);
-       ao_spi_recv(ao_m25_instruction, M25_RDID_LEN);
+       ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
+       ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        /* Check to see if the chip is present */
@@ -165,12 +167,13 @@ ao_m25_read_capacity(uint8_t cs)
        return 1 << (capacity - 0x10);
 }
 
-static uint8_t
+static ao_port_t
 ao_m25_set_address(uint32_t pos)
 {
-       uint8_t chip;
+       ao_port_t       mask;
 #if M25_MAX_CHIPS > 1
        uint8_t size;
+       uint8_t         chip;
 
        for (chip = 0; chip < ao_m25_numchips; chip++) {
                size = ao_m25_size[chip];
@@ -181,16 +184,16 @@ ao_m25_set_address(uint32_t pos)
        if (chip == ao_m25_numchips)
                return 0xff;
 
-       chip = ao_m25_pin[chip];
+       mask = ao_m25_pin[chip];
 #else
-       chip = M25_CS_MASK;
+       mask = AO_M25_SPI_CS_MASK;
 #endif
-       ao_m25_wait_wip(chip);
+       ao_m25_wait_wip(mask);
 
        ao_m25_instruction[1] = pos >> 16;
        ao_m25_instruction[2] = pos >> 8;
        ao_m25_instruction[3] = pos;
-       return chip;
+       return mask;
 }
 
 /*
@@ -210,7 +213,7 @@ ao_m25_scan(void)
 #if M25_MAX_CHIPS > 1
        ao_m25_numchips = 0;
        for (pin = 1; pin != 0; pin <<= 1) {
-               if (M25_CS_MASK & pin) {
+               if (AO_M25_SPI_CS_MASK & pin) {
                        size = ao_m25_read_capacity(pin);
                        if (size != 0) {
                                ao_m25_size[ao_m25_numchips] = size;
@@ -221,7 +224,7 @@ ao_m25_scan(void)
                }
        }
 #else
-       ao_m25_total = ao_m25_read_capacity(M25_CS_MASK);
+       ao_m25_total = ao_m25_read_capacity(AO_M25_SPI_CS_MASK);
 #endif
        if (!ao_m25_total)
                return 0;
@@ -236,9 +239,9 @@ ao_m25_scan(void)
  * Erase the specified sector
  */
 uint8_t
-ao_storage_erase(uint32_t pos) __reentrant
+ao_storage_erase(uint32_t pos) 
 {
-       uint8_t cs;
+       ao_port_t       cs;
 
        if (pos >= ao_storage_total || pos + ao_storage_block > ao_storage_total)
                return 0;
@@ -248,12 +251,11 @@ ao_storage_erase(uint32_t pos) __reentrant
 
        cs = ao_m25_set_address(pos);
 
-       ao_m25_wait_wip(cs);
        ao_m25_write_enable(cs);
 
        ao_m25_instruction[0] = M25_SE;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 
@@ -265,9 +267,9 @@ ao_storage_erase(uint32_t pos) __reentrant
  * Write to flash
  */
 uint8_t
-ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
+ao_storage_device_write(uint32_t pos, void *d, uint16_t len) 
 {
-       uint8_t cs;
+       ao_port_t       cs;
 
        if (pos >= ao_storage_total || pos + len > ao_storage_total)
                return 0;
@@ -280,8 +282,8 @@ ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
 
        ao_m25_instruction[0] = M25_PP;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
-       ao_spi_send(d, len);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
+       ao_spi_send(d, len, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
@@ -292,9 +294,9 @@ ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
  * Read from flash
  */
 uint8_t
-ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
+ao_storage_device_read(uint32_t pos, void *d, uint16_t len) 
 {
-       uint8_t cs;
+       ao_port_t       cs;
 
        if (pos >= ao_storage_total || pos + len > ao_storage_total)
                return 0;
@@ -306,8 +308,8 @@ ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
        /* No need to use the FAST_READ as we're running at only 8MHz */
        ao_m25_instruction[0] = M25_READ;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
-       ao_spi_recv(d, len);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
+       ao_spi_recv(d, len, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
@@ -315,7 +317,7 @@ ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
 }
 
 void
-ao_storage_flush(void) __reentrant
+ao_storage_flush(void) 
 {
 }
 
@@ -328,9 +330,11 @@ ao_storage_setup(void)
 }
 
 void
-ao_storage_device_info(void) __reentrant
+ao_storage_device_info(void) 
 {
-       uint8_t cs;
+#if M25_DEBUG
+       ao_port_t       cs;
+#endif
 #if M25_MAX_CHIPS > 1
        uint8_t chip;
 #endif
@@ -348,16 +352,17 @@ ao_storage_device_info(void) __reentrant
        printf ("Detected chips 1 size %d\n", ao_m25_total);
 #endif
 
+#if M25_DEBUG
        printf ("Available chips:\n");
        for (cs = 1; cs != 0; cs <<= 1) {
-               if ((M25_CS_MASK & cs) == 0)
+               if ((AO_M25_SPI_CS_MASK & cs) == 0)
                        continue;
 
                ao_mutex_get(&ao_m25_mutex);
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDID;
-               ao_spi_send(ao_m25_instruction, 1);
-               ao_spi_recv(ao_m25_instruction, M25_RDID_LEN);
+               ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
+               ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS);
                M25_DESELECT(cs);
 
                printf ("Select %02x manf %02x type %02x cap %02x uid %02x\n",
@@ -368,15 +373,11 @@ ao_storage_device_info(void) __reentrant
                        ao_m25_instruction[M25_UID_OFFSET]);
                ao_mutex_put(&ao_m25_mutex);
        }
+#endif
 }
 
 void
 ao_storage_device_init(void)
 {
-       /* Set up chip select wires */
-       SPI_CS_PORT |= M25_CS_MASK;     /* raise all CS pins */
-       SPI_CS_DIR |= M25_CS_MASK;      /* set CS pins as outputs */
-#ifdef SPI_CS_SEL
-       SPI_CS_SEL &= ~M25_CS_MASK;     /* set CS pins as GPIO */
-#endif
+       ao_spi_init_cs (AO_M25_SPI_CS_PORT, AO_M25_SPI_CS_MASK);
 }