Пример #1
0
/**
 * @brief     Write data to EEPROM.
 * @details   Only one EEPROM page can be written at once. So fucntion
 *            splits large data chunks in small EEPROM transactions if needed.
 * @note      To achieve the maximum effectivity use write operations
 *            aligned to EEPROM page boundaries.
 */
static size_t write(void *ip, const uint8_t *bp, size_t n) {

    size_t   len = 0;     /* bytes to be written at one trasaction */
    uint32_t written; /* total bytes successfully written */
    uint16_t pagesize;
    uint32_t firstpage;
    uint32_t lastpage;

    chDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL), "write");

    if (n == 0)
        return 0;

    n = __clamp_size(ip, n);
    if (n == 0)
        return 0;

    pagesize  =  ((EepromFileStream *)ip)->cfg->pagesize;
    firstpage = (((EepromFileStream *)ip)->cfg->barrier_low +
                 eepfs_getposition(ip)) / pagesize;
    lastpage  = (((EepromFileStream *)ip)->cfg->barrier_low +
                 eepfs_getposition(ip) + n - 1) / pagesize;

    written = 0;
    /* data fitted in single page */
    if (firstpage == lastpage) {
        len = n;
        __fitted_write(ip, bp, len, &written);
        bp += len;
        return written;
    }

    else {
        /* write first piece of data to first page boundary */
        len =  ((firstpage + 1) * pagesize) - eepfs_getposition(ip);
        len -= ((EepromFileStream *)ip)->cfg->barrier_low;
        __fitted_write(ip, bp, len, &written);
        bp += len;

        /* now writes blocks at a size of pages (may be no one) */
        while ((n - written) > pagesize) {
            len = pagesize;
            __fitted_write(ip, bp, len, &written);
            bp += len;
        }

        /* wrtie tail */
        len = n - written;
        if (len == 0)
            return written;
        else {
            __fitted_write(ip, bp, len, &written);
        }
    }

    return written;
}
Пример #2
0
/**
 * Read some bytes from current position in file. After successful
 * read operation the position pointer will be increased by the number
 * of read bytes.
 */
static size_t read(void *ip, uint8_t *bp, size_t n) {
    msg_t status = RDY_OK;

    chDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL), "read");

    if (n == 0)
        return 0;

    n = __clamp_size(ip, n);
    if (n == 0)
        return 0;

    /* Stupid I2C cell in STM32F1x does not allow to read single byte.
       So we must read 2 bytes and return needed one. */
#if defined(STM32F1XX_I2C)
    if (n == 1) {
        uint8_t __buf[2];
        /* if NOT last byte of file requested */
        if ((eepfs_getposition(ip) + 1) < eepfs_getsize(ip)) {
            if (read(ip, __buf, 2) == 2) {
                eepfs_lseek(ip, (eepfs_getposition(ip) + 1));
                bp[0] = __buf[0];
                return 1;
            }
            else
                return 0;
        }
        else {
            eepfs_lseek(ip, (eepfs_getposition(ip) - 1));
            if (read(ip, __buf, 2) == 2) {
                eepfs_lseek(ip, (eepfs_getposition(ip) + 2));
                bp[0] = __buf[1];
                return 1;
            }
            else
                return 0;
        }
    }
#endif /* defined(STM32F1XX_I2C) */

    /* call low level function */
    status  = eeprom_read(((I2CEepromFileStream *)ip)->cfg,
                          eepfs_getposition(ip), bp, n);
    if (status != RDY_OK)
        return 0;
    else {
        eepfs_lseek(ip, (eepfs_getposition(ip) + n));
        return n;
    }
}
Пример #3
0
/**
 * Read some bytes from current position in file. After successful
 * read operation the position pointer will be increased by the number
 * of read bytes.
 */
static size_t read(void *ip, uint8_t *bp, size_t n) {
    msg_t status = RDY_OK;

    chDbgCheck((ip != NULL) && (((EepromFileStream*)ip)->vmt != NULL), "");

    if (n == 0)
        return 0;

    n = __clamp_size(ip, n);
    if (n == 0)
        return 0;

    /* Stupid STM32 I2C cell does not allow to read less than 2 bytes.
       So we must read 2 bytes and return needed one. */
#if (defined(STM32F4XX) || defined(STM32F2XX) || defined(STM32F1XX) || \
                                                 defined(STM32L1XX))
    if (n == 1) {
        uint8_t __buf[2];
        /* if NOT last byte of file requested */
        if ((getposition(ip) + 1) < getsize(ip)) {
            if (read(ip, __buf, 2) == 2) {
                lseek(ip, (getposition(ip) + 1));
                bp[0] = __buf[0];
                return 1;
            }
            else
                return 0;
        }
        else {
            lseek(ip, (getposition(ip) - 1));
            if (read(ip, __buf, 2) == 2) {
                lseek(ip, (getposition(ip) + 2));
                bp[0] = __buf[1];
                return 1;
            }
            else
                return 0;
        }
    }
#endif

    /* call low level function */
    status  = eeprom_read(getposition(ip), bp, n);
    if (status != RDY_OK)
        return 0;
    else {
        lseek(ip, (getposition(ip) + n));
        return n;
    }
}
Пример #4
0
/**
 * @brief     Write data to EEPROM.
 * @details   Only one EEPROM page can be written at once. So fucntion
 *            splits large data chunks in small EEPROM transactions if needed.
 * @note      To achieve the maximum effectivity use write operations
 *            aligned to EEPROM page boundaries.
 */
static size_t write(void *ip, const uint8_t *bp, size_t n) {
    msg_t status = RDY_OK;

    size_t   len = 0;     /* bytes to be written at one trasaction */
    uint32_t written = 0; /* total bytes successfully written */
    uint32_t firstpage = getposition(ip) / EEPROM_PAGE_SIZE;
    uint32_t lastpage  = (getposition(ip) + n - 1) / EEPROM_PAGE_SIZE;

    chDbgCheck((ip != NULL) && (((EepromFileStream*)ip)->vmt != NULL), "");

    if (n == 0)
        return 0;

    n = __clamp_size(ip, n);
    if (n == 0)
        return 0;

    /* data fitted in single page */
    if (firstpage == lastpage) {
        len = n;
        __fitted_write();
        return written;
    }

    else {
        /* write first piece of data to first page boundary */
        len = ((firstpage + 1) * EEPROM_PAGE_SIZE) - getposition(ip);
        __fitted_write();

        /* now writes blocks at a size of pages (may be no one) */
        while ((n - written) > EEPROM_PAGE_SIZE) {
            len = EEPROM_PAGE_SIZE;
            __fitted_write();
        }

        /* wrtie tail */
        len = n - written;
        if (len == 0)
            return written;
        else {
            __fitted_write();
        }
    }
    return written;
}