nvmem_at45d.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2009 by egnite GmbH
00003  * Copyright (C) 2006 by egnite Software GmbH
00004  *
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holders nor the names of
00017  *    contributors may be used to endorse or promote products derived
00018  *    from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * For additional information see http://www.ethernut.de/
00034  */
00035 
00045 #include <cfg/eeprom.h>
00046 #include <cfg/memory.h>
00047 
00048 #include <dev/board.h>
00049 #include <dev/spi_at45d.h>
00050 
00051 #include <sys/nutdebug.h>
00052 
00053 #include <stdlib.h>
00054 #include <string.h>
00055 #include <memdebug.h>
00056 
00057 #include <dev/nvmem_at45d.h>
00058 
00059 static NUTDEVICE *devSysConf;
00060 
00071 static int SpiAt45dConfigDevice(void)
00072 {
00073 #if !defined(DEV_SPIBUS)
00074     return -1;
00075 #else /* DEV_SPIBUS */
00076     if (devSysConf == NULL) {
00077         NUTSPINODE *node;
00078         NUTDEVICE *dev;
00079 #if NUT_CONFIG_AT45D == 0
00080         dev = &devSpiAt45d0;
00081 #elif NUT_CONFIG_AT45D == 1
00082         dev = &devSpiAt45d1;
00083 #elif NUT_CONFIG_AT45D == 2
00084         dev = &devSpiAt45d2;
00085 #elif NUT_CONFIG_AT45D == 3
00086         dev = &devSpiAt45d3;
00087 #else
00088         return -1;
00089 #endif
00090         node = (NUTSPINODE *) dev->dev_icb;
00091         NUTASSERT(node != NULL);
00092         if (node->node_bus == NULL) {
00093             NUTSPIBUS *bus;
00094             bus = &DEV_SPIBUS;
00095             node->node_bus = bus;
00096         }
00097 #ifdef NUT_CONFIG_AT45D_CS
00098         node->node_cs = NUT_CONFIG_AT45D_CS;
00099 #endif
00100         NUTASSERT(node->node_bus->bus_initnode != NULL);
00101         if ((*node->node_bus->bus_initnode) (node)) {
00102             return -1;
00103         }
00104         NutEventPost(&node->node_bus->bus_mutex);
00105         if (SpiAt45dInit(dev)) {
00106             return -1;
00107         }
00108         devSysConf = dev;
00109     }
00110     return 0;
00111 #endif /* DEV_SPIBUS */
00112 }
00113 
00114 static uint32_t SpiAt45dConfigPage(void)
00115 {
00116 #ifdef NUT_CONFIG_AT45D_PAGE
00117     return NUT_CONFIG_AT45D_PAGE;
00118 #else
00119     return SpiAt45dPages(devSysConf) - 1;
00120 #endif
00121 }
00122 
00134 size_t SpiAt45dConfigSize(void)
00135 {
00136     int rc = 0;
00137 
00138     if (SpiAt45dConfigDevice() == 0) {
00139 #ifdef NUT_CONFIG_AT45D_SIZE
00140         rc = NUT_CONFIG_AT45D_SIZE;
00141         NUTASSERT(NUT_CONFIG_AT45D_SIZE <= SpiAt45dPageSize(devSysConf));
00142 #else
00143         rc = (size_t) SpiAt45dPageSize(devSysConf);
00144 #endif
00145     }
00146     return rc;
00147 }
00148 
00158 int SpiAt45dConfigRead(size_t pos, void *data, size_t len)
00159 {
00160     int rc = -1;
00161     uint8_t *buff;
00162     int csize = SpiAt45dConfigSize();
00163 
00164     /* Load the complete configuration area. */
00165     if (csize >= pos + len && (buff = malloc(csize)) != NULL) {
00166         uint32_t cpage = SpiAt45dConfigPage();
00167 
00168         if (SpiAt45dPageRead(devSysConf, cpage, buff, csize) == csize) {
00169             /* Copy requested contents to caller's buffer. */
00170             memcpy(data, buff + pos, len);
00171             rc = 0;
00172         }
00173         free(buff);
00174     }
00175     return rc;
00176 }
00177 
00187 int SpiAt45dConfigWrite(size_t pos, CONST void *data, size_t len)
00188 {
00189     int rc = -1;
00190     uint8_t *buff;
00191     int csize = SpiAt45dConfigSize();
00192 
00193     /* Load the complete configuration area. */
00194     if (csize >= pos + len && (buff = malloc(csize)) != NULL) {
00195         uint32_t cpage = SpiAt45dConfigPage();
00196 
00197         if (SpiAt45dPageRead(devSysConf, cpage, buff, csize) == csize) {
00198             /* Compare old with new contents. */
00199             if (memcmp(buff + pos, data, len)) {
00200                 /* New contents differs. Copy it into the sector buffer. */
00201                 memcpy(buff + pos, data, len);
00202                 /* Erase sector and write new data. */
00203                 if (SpiAt45dPageWrite(devSysConf, cpage, buff, csize) == csize) {
00204                     rc = 0;
00205                 }
00206             } else {
00207                 rc = 0;
00208             }
00209         }
00210         free(buff);
00211     }
00212     return rc;
00213 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/