Nut/OS  4.10.3
API Reference
spi_blkio_at45d.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2011 by egnite GmbH
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the copyright holders nor the names of
00016  *    contributors may be used to endorse or promote products derived
00017  *    from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * For additional information see http://www.ethernut.de/
00033  */
00034 
00044 #include <cfg/memory.h>
00045 #include <sys/nutdebug.h>
00046 
00047 #include <dev/blockdev.h>
00048 #include <dev/spi_node_at45d.h>
00049 
00054 
00062 static int At45dBlkIoInit(NUTDEVICE * dev)
00063 {
00064     NUTBLOCKIO *blkio;
00065     NUTSPINODE *node;
00066     AT45D_INFO *df;
00067 
00068     NUTASSERT(dev != NULL);
00069     NUTASSERT(dev->dev_dcb != NULL);
00070     NUTASSERT(dev->dev_icb != NULL);
00071     blkio = dev->dev_dcb;
00072     node = dev->dev_icb;
00073 
00074     df = At45dNodeProbe(node);
00075     if (df) {
00076         /* Known DataFlash type detected. */
00077         blkio->blkio_info = (void *) df;
00078         blkio->blkio_blk_cnt = df->at45d_pages;
00079         blkio->blkio_blk_siz = df->at45d_psize;
00080         return 0;
00081     }
00082     /* No known DataFlash type detected. */
00083     return -1;
00084 }
00085 
00097 static int At45dBlkIoRead(NUTDEVICE * dev, uint32_t pgn, void *data, int len)
00098 {
00099     NUTBLOCKIO *blkio;
00100     AT45D_INFO *info;
00101 
00102     NUTASSERT(dev != NULL);
00103     NUTASSERT(dev->dev_dcb != NULL);
00104     blkio = dev->dev_dcb;
00105 
00106     info = (AT45D_INFO *) blkio->blkio_info;
00107     NUTASSERT(blkio->blkio_info != NULL);
00108 
00109     if (pgn >= info->at45d_pages) {
00110         return -1;
00111     }
00112     pgn <<= info->at45d_pshft;
00113 
00114     if (At45dNodeLock((NUTSPINODE *) dev->dev_icb) ||
00115         At45dNodeTransfer((NUTSPINODE *) dev->dev_icb, DFCMD_CONT_READ, pgn, 8, NULL, data, len)) {
00116         At45dNodeUnlock((NUTSPINODE *) dev->dev_icb);
00117         return -1;
00118     }
00119     At45dNodeUnlock((NUTSPINODE *) dev->dev_icb);
00120     return len;
00121 }
00122 
00140 static int At45dBlkIoWrite(NUTDEVICE * dev, uint32_t pgn, CONST void *data, int len)
00141 {
00142     int rc = -1;
00143     uint8_t *dp = (uint8_t *) data;
00144     int step;
00145     uint_fast8_t pshft;
00146     uint32_t limit;
00147     NUTBLOCKIO *blkio;
00148     NUTSPINODE *node;
00149 
00150     /* Sanity check. */
00151     if (len == 0) {
00152         return 0;
00153     }
00154     NUTASSERT(data != NULL);
00155     NUTASSERT(dev != NULL);
00156     NUTASSERT(dev->dev_dcb != NULL);
00157     NUTASSERT(dev->dev_icb != NULL);
00158     blkio = (NUTBLOCKIO *) dev->dev_dcb;
00159     node = (NUTSPINODE *) dev->dev_icb;
00160     NUTASSERT(blkio->blkio_info != NULL);
00161     pshft = ((AT45D_INFO *) blkio->blkio_info)->at45d_pshft;
00162     step = ((AT45D_INFO *) blkio->blkio_info)->at45d_psize;
00163     limit = ((AT45D_INFO *) blkio->blkio_info)->at45d_pages;
00164 
00165     while (len) {
00166         if (step > len) {
00167             step = len;
00168         }
00169         if (At45dNodeLock(node)) {
00170             break;
00171         }
00172         /* Copy data to the internal DataFlash RAM buffer. */
00173         if (At45dNodeTransfer(node, DFCMD_BUF1_WRITE, 0, 4, dp, NULL, step)) {
00174             break;
00175         }
00176         /* Erase the page and flash the RAM buffer contents. */
00177         if (At45dNodeCommand(node, DFCMD_BUF1_FLASH, pgn << pshft, 4)) {
00178             break;
00179         }
00180         if (At45dNodeWaitReady(node, AT45_WRITE_POLLS, 1)) {
00181             break;
00182         }
00183         At45dNodeUnlock(node);
00184         if (rc < 0) {
00185             rc = 0;
00186         }
00187         rc += step;
00188         dp += step;
00189         len -= step;
00190         if (++pgn >= limit) {
00191             break;
00192         }
00193     }
00194     return rc;
00195 }
00196 
00197 #ifdef __HARVARD_ARCH__
00198 static int At45dBlkIoWrite_P(NUTDEVICE * dev, uint32_t pgn, PGM_P data, int len)
00199 {
00200     return -1;
00201 }
00202 #endif
00203 
00221 static int At45dBlkIoCtl(NUTDEVICE * dev, int req, void *conf)
00222 {
00223     int rc = 0;
00224 
00225     switch (req) {
00226     case NUTBLKDEV_MEDIAAVAIL:
00227         /* Modification required for DataFlash cards. */
00228         {
00229             int *flg;
00230             NUTASSERT(conf != NULL);
00231             flg = (int *) conf;
00232             *flg = 1;
00233         }
00234         break;
00235     case NUTBLKDEV_MEDIACHANGE:
00236         /* Modification required for DataFlash cards. */
00237         {
00238             int *flg;
00239             NUTASSERT(conf != NULL);
00240             flg = (int *) conf;
00241             *flg = 0;
00242         }
00243         break;
00244     default:
00245         rc = -1;
00246         break;
00247     }
00248     return rc;
00249 }
00250 
00251 #ifndef BLKIO_MOUNT_OFFSET_AT45D0
00252 #ifdef MOUNT_OFFSET_AT45D0
00253 #define BLKIO_MOUNT_OFFSET_AT45D0       MOUNT_OFFSET_AT45D0
00254 #else
00255 #define BLKIO_MOUNT_OFFSET_AT45D0       0
00256 #endif
00257 #endif
00258 
00259 #ifndef BLKIO_MOUNT_TOP_RESERVE_AT45D0
00260 #ifdef MOUNT_TOP_RESERVE_AT45D0
00261 #define BLKIO_MOUNT_TOP_RESERVE_AT45D0  MOUNT_TOP_RESERVE_AT45D0
00262 #else
00263 #define BLKIO_MOUNT_TOP_RESERVE_AT45D0  1
00264 #endif
00265 #endif
00266 
00270 static NUTBLOCKIO blkIoAt45d0 = {
00271     NULL,                       
00272     0,                          
00273     0,                          
00274     BLKIO_MOUNT_OFFSET_AT45D0,  
00275     BLKIO_MOUNT_TOP_RESERVE_AT45D0,     
00276     At45dBlkIoRead,             
00277     At45dBlkIoWrite,            
00278 #ifdef __HARVARD_ARCH__
00279     At45dBlkIoWrite_P,          
00280 #endif
00281     At45dBlkIoCtl               
00282 };
00283 
00287 NUTDEVICE devSpiBlkAt45d0 = {
00288     NULL,                       
00289     {'A', 'T', '4', '5', 'D', '0', 0, 0, 0},    
00290     IFTYP_BLKIO,                
00291     0,                          
00292     0,                          
00293     &nodeAt45d0,                
00294     &blkIoAt45d0,               
00295     At45dBlkIoInit,             
00296     NutBlockDeviceIOCtl,        
00297     NutBlockDeviceRead,         
00298     NutBlockDeviceWrite,        
00299 #ifdef __HARVARD_ARCH__
00300     NutBlockDeviceWrite_P,      
00301 #endif
00302     NutBlockDeviceOpen,         
00303     NutBlockDeviceClose,        
00304     NutBlockDeviceSize          
00305 };
00306 
00307 #ifndef BLKIO_MOUNT_OFFSET_AT45D1
00308 #ifdef MOUNT_OFFSET_AT45D1
00309 #define BLKIO_MOUNT_OFFSET_AT45D1       MOUNT_OFFSET_AT45D1
00310 #else
00311 #define BLKIO_MOUNT_OFFSET_AT45D1       0
00312 #endif
00313 #endif
00314 
00315 #ifndef BLKIO_MOUNT_TOP_RESERVE_AT45D1
00316 #ifdef MOUNT_TOP_RESERVE_AT45D1
00317 #define BLKIO_MOUNT_TOP_RESERVE_AT45D1  MOUNT_TOP_RESERVE_AT45D1
00318 #else
00319 #define BLKIO_MOUNT_TOP_RESERVE_AT45D1  1
00320 #endif
00321 #endif
00322 
00326 static NUTBLOCKIO blkIoAt45d1 = {
00327     NULL,                       
00328     0,                          
00329     0,                          
00330     BLKIO_MOUNT_OFFSET_AT45D1,  
00331     BLKIO_MOUNT_TOP_RESERVE_AT45D1,     
00332     At45dBlkIoRead,             
00333     At45dBlkIoWrite,            
00334 #ifdef __HARVARD_ARCH__
00335     At45dBlkIoWrite_P,          
00336 #endif
00337     At45dBlkIoCtl               
00338 };
00339 
00343 NUTDEVICE devSpiBlkAt45d1 = {
00344     NULL,                       
00345     {'A', 'T', '4', '5', 'D', '1', 0, 0, 0},    
00346     IFTYP_BLKIO,                
00347     0,                          
00348     0,                          
00349     &nodeAt45d1,                
00350     &blkIoAt45d1,               
00351     At45dBlkIoInit,             
00352     NutBlockDeviceIOCtl,        
00353     NutBlockDeviceRead,         
00354     NutBlockDeviceWrite,        
00355 #ifdef __HARVARD_ARCH__
00356     NutBlockDeviceWrite_P,      
00357 #endif
00358     NutBlockDeviceOpen,         
00359     NutBlockDeviceClose,        
00360     NutBlockDeviceSize          
00361 };
00362 
00363 #ifndef BLKIO_MOUNT_OFFSET_AT45D2
00364 #ifdef MOUNT_OFFSET_AT45D2
00365 #define BLKIO_MOUNT_OFFSET_AT45D2       MOUNT_OFFSET_AT45D2
00366 #else
00367 #define BLKIO_MOUNT_OFFSET_AT45D2       0
00368 #endif
00369 #endif
00370 
00371 #ifndef BLKIO_MOUNT_TOP_RESERVE_AT45D2
00372 #ifdef MOUNT_TOP_RESERVE_AT45D2
00373 #define BLKIO_MOUNT_TOP_RESERVE_AT45D2  MOUNT_TOP_RESERVE_AT45D2
00374 #else
00375 #define BLKIO_MOUNT_TOP_RESERVE_AT45D2  1
00376 #endif
00377 #endif
00378 
00382 static NUTBLOCKIO blkIoAt45d2 = {
00383     NULL,                       
00384     0,                          
00385     0,                          
00386     BLKIO_MOUNT_OFFSET_AT45D2,  
00387     BLKIO_MOUNT_TOP_RESERVE_AT45D2,     
00388     At45dBlkIoRead,             
00389     At45dBlkIoWrite,            
00390 #ifdef __HARVARD_ARCH__
00391     At45dBlkIoWrite_P,          
00392 #endif
00393     At45dBlkIoCtl               
00394 };
00395 
00399 NUTDEVICE devSpiBlkAt45d2 = {
00400     NULL,                       
00401     {'A', 'T', '4', '5', 'D', '2', 0, 0, 0},    
00402     IFTYP_BLKIO,                
00403     0,                          
00404     0,                          
00405     &nodeAt45d2,                
00406     &blkIoAt45d2,               
00407     At45dBlkIoInit,             
00408     NutBlockDeviceIOCtl,        
00409     NutBlockDeviceRead,         
00410     NutBlockDeviceWrite,        
00411 #ifdef __HARVARD_ARCH__
00412     NutBlockDeviceWrite_P,      
00413 #endif
00414     NutBlockDeviceOpen,         
00415     NutBlockDeviceClose,        
00416     NutBlockDeviceSize          
00417 };
00418 
00419 #ifndef BLKIO_MOUNT_OFFSET_AT45D3
00420 #ifdef MOUNT_OFFSET_AT45D3
00421 #define BLKIO_MOUNT_OFFSET_AT45D3       MOUNT_OFFSET_AT45D3
00422 #else
00423 #define BLKIO_MOUNT_OFFSET_AT45D3       0
00424 #endif
00425 #endif
00426 
00427 #ifndef BLKIO_MOUNT_TOP_RESERVE_AT45D3
00428 #ifdef MOUNT_TOP_RESERVE_AT45D3
00429 #define BLKIO_MOUNT_TOP_RESERVE_AT45D3  MOUNT_TOP_RESERVE_AT45D3
00430 #else
00431 #define BLKIO_MOUNT_TOP_RESERVE_AT45D3  1
00432 #endif
00433 #endif
00434 
00438 static NUTBLOCKIO blkIoAt45d3 = {
00439     NULL,                       
00440     0,                          
00441     0,                          
00442     BLKIO_MOUNT_OFFSET_AT45D3,  
00443     BLKIO_MOUNT_TOP_RESERVE_AT45D3,     
00444     At45dBlkIoRead,             
00445     At45dBlkIoWrite,            
00446 #ifdef __HARVARD_ARCH__
00447     At45dBlkIoWrite_P,          
00448 #endif
00449     At45dBlkIoCtl               
00450 };
00451 
00455 NUTDEVICE devSpiBlkAt45d3 = {
00456     NULL,                       
00457     {'A', 'T', '4', '5', 'D', '3', 0, 0, 0},    
00458     IFTYP_BLKIO,                
00459     0,                          
00460     0,                          
00461     &nodeAt45d3,                
00462     &blkIoAt45d3,               
00463     At45dBlkIoInit,             
00464     NutBlockDeviceIOCtl,        
00465     NutBlockDeviceRead,         
00466     NutBlockDeviceWrite,        
00467 #ifdef __HARVARD_ARCH__
00468     NutBlockDeviceWrite_P,      
00469 #endif
00470     NutBlockDeviceOpen,         
00471     NutBlockDeviceClose,        
00472     NutBlockDeviceSize          
00473 };
00474