sam3: add twi definitions for SAM3N, SAM3S and SAM3U
[bertos.git] / bertos / drv / sd.c
index 9880dfe15cabde7e7c35b11d1b09f27349e3f088..c12d7592e6660332d57a430c1473e620057ae37a 100644 (file)
@@ -243,10 +243,14 @@ static size_t sd_readDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t
        Sd *sd = SD_CAST(b);
        LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
 
-       if ((sd->r1 = sd_setBlockLen(sd, size)))
+       if (sd->tranfer_len != size)
        {
-               LOG_ERR("setBlockLen failed: %04X\n", sd->r1);
-               return 0;
+               if ((sd->r1 = sd_setBlockLen(sd, size)))
+               {
+                       LOG_ERR("setBlockLen failed: %04X\n", sd->r1);
+                       return 0;
+               }
+               sd->tranfer_len = size;
        }
 
        SD_SELECT(sd);
@@ -274,16 +278,22 @@ static size_t sd_readDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t
 #define SD_WRITE_SINGLEBLOCK 0x58
 #define SD_DATA_ACCEPTED     0x05
 
-static int sd_writeBlock(KBlock *b, block_idx_t idx, const void *buf)
+static size_t sd_writeDirect(KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size)
 {
        Sd *sd = SD_CAST(b);
        KFile *fd = sd->ch;
+       ASSERT(offset == 0);
+       ASSERT(size == SD_DEFAULT_BLOCKLEN);
 
        LOG_INFO("writing block %ld\n", idx);
-       if ((sd->r1 = sd_setBlockLen(sd, SD_DEFAULT_BLOCKLEN)))
+       if (sd->tranfer_len != SD_DEFAULT_BLOCKLEN)
        {
-               LOG_ERR("setBlockLen failed: %04X\n", sd->r1);
-               return sd->r1;
+               if ((sd->r1 = sd_setBlockLen(sd, SD_DEFAULT_BLOCKLEN)))
+               {
+                       LOG_ERR("setBlockLen failed: %04X\n", sd->r1);
+                       return 0;
+               }
+               sd->tranfer_len = SD_DEFAULT_BLOCKLEN;
        }
 
        SD_SELECT(sd);
@@ -294,7 +304,7 @@ static int sd_writeBlock(KBlock *b, block_idx_t idx, const void *buf)
        {
                LOG_ERR("write single block failed: %04X\n", sd->r1);
                sd_select(sd, false);
-               return sd->r1;
+               return 0;
        }
 
        kfile_putc(SD_STARTTOKEN, fd);
@@ -312,7 +322,7 @@ static int sd_writeBlock(KBlock *b, block_idx_t idx, const void *buf)
                return EOF;
        }
 
-       return 0;
+       return SD_DEFAULT_BLOCKLEN;
 }
 
 void sd_writeTest(Sd *sd)
@@ -322,7 +332,7 @@ void sd_writeTest(Sd *sd)
 
        for (block_idx_t i = 0; i < sd->b.blk_cnt; i++)
        {
-               LOG_INFO("writing block %ld: %s\n", i, (sd_writeBlock(&sd->b, i, buf) == 0) ? "OK" : "FAIL");
+               LOG_INFO("writing block %ld: %s\n", i, (sd_writeDirect(&sd->b, i, buf, 0, SD_DEFAULT_BLOCKLEN) == SD_DEFAULT_BLOCKLEN) ? "OK" : "FAIL");
        }
 }
 
@@ -343,7 +353,7 @@ bool sd_test(Sd *sd)
                        kputchar('\n');
        }
 
-       if (sd_writeBlock(&sd->b, 0, buf) != 0)
+       if (sd_writeDirect(&sd->b, 0, buf, 0, SD_DEFAULT_BLOCKLEN) != SD_DEFAULT_BLOCKLEN)
                return false;
 
        memset(buf, 0, sizeof(buf));
@@ -368,17 +378,16 @@ static int sd_error(KBlock *b)
        return sd->r1;
 }
 
-static int sd_clearerr(KBlock *b)
+static void sd_clearerr(KBlock *b)
 {
        Sd *sd = SD_CAST(b);
        sd->r1 = 0;
-       return 0;
 }
 
 static const KBlockVTable sd_unbuffered_vt =
 {
        .readDirect = sd_readDirect,
-       .writeBlock = sd_writeBlock,
+       .writeDirect = sd_writeDirect,
 
        .error = sd_error,
        .clearerr = sd_clearerr,
@@ -387,7 +396,7 @@ static const KBlockVTable sd_unbuffered_vt =
 static const KBlockVTable sd_buffered_vt =
 {
        .readDirect = sd_readDirect,
-       .writeBlock = sd_writeBlock,
+       .writeDirect = sd_writeDirect,
 
        .readBuf = kblock_swReadBuf,
        .writeBuf = kblock_swWriteBuf,
@@ -461,6 +470,7 @@ static bool sd_blockInit(Sd *sd, KFile *ch)
        }
 
        sd->r1 = sd_setBlockLen(sd, SD_DEFAULT_BLOCKLEN);
+       sd->tranfer_len = SD_DEFAULT_BLOCKLEN;
 
        if (sd->r1)
        {
@@ -508,7 +518,7 @@ bool sd_initBuf(Sd *sd, KFile *ch)
        if (sd_blockInit(sd, ch))
        {
                sd->b.priv.buf = sd_buf;
-               sd->b.priv.flags |= KB_BUFFERED;
+               sd->b.priv.flags |= KB_BUFFERED | KB_PARTIAL_WRITE;
                sd->b.priv.vt = &sd_buffered_vt;
                sd->b.priv.vt->load(&sd->b, 0);
                return true;