реклама на сайте
подробности

 
 
> Запись в Serial EEprom.
Jenya7
сообщение Apr 11 2016, 13:01
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Записывая в память нужно следить чтобы не перейти страницу.
Код
#define USE_STATUS_REG 0   //doesn't help any way

void LOGGER_PageWrite(uint32_t address, uint32_t length, uint8_t *buffer)
{
    #if USE_STATUS_REG
    uint32_t timer;
    #endif
    volatile uint32_t page_limit=0;
    volatile uint32_t bytes_to_fit=0;
    volatile uint32_t bytes_to_write=0;

    //find a page limit for the address
    while (address > page_limit)
    {
        page_limit += 64;
    }
    //actual page limit
    page_limit--;

    bytes_to_fit = page_limit - address;
    bytes_to_write = bytes_to_fit;

    // Note!!!Every write operation demands a write enable!!!
    SPI_CSlow();
    SPI_SendByte(SPIEEPROM_CMD_WREN);
    SPI_CShigh();

    // start write
    SPI_CSlow();
    // send write command
    SPI_SendByte(SPIEEPROM_CMD_WRITE);
    // send address
    SPI_SendByte(address>>8);
    SPI_SendByte(address&0x00FF);
    while(bytes_to_write--)
    {
        // send data to be written
         SPI_SendByte(*buffer++);
    }
    // stop write
    SPI_CShigh();

    #if USE_STATUS_REG
    timer = LOGGER_DELAY;
    //wait for write operation to complete
    while(SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP)
    {
        if(!--timer)
           break;
    }
    #else
    //needs 5ms for page write
    Delay_us_sys(5000);
    #endif

    if (bytes_to_fit <= length)
    {
        address += bytes_to_fit+1;
        bytes_to_write = length - bytes_to_fit;

         // Note!!!Every write operation demands a write enable!!!
        SPI_CSlow();
        SPI_SendByte(SPIEEPROM_CMD_WREN);
        SPI_CShigh();

        // start write
        SPI_CSlow();
        // send write command
        SPI_SendByte(SPIEEPROM_CMD_WRITE);
        // send address
        SPI_SendByte(address>>8);
        SPI_SendByte(address&0xFF);
        while(bytes_to_write--)
        {
            // send data to be written
            SPI_SendByte(*buffer++);
        }
        // stop write
        SPI_CShigh();

        #if USE_STATUS_REG
        timer = LOGGER_DELAY;
        //wait for write operation to complete
        while(SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP)
        {
            if(!--timer)
                break;
        }
        #else
        //needs 5ms for page write
        Delay_us_sys(5000);
        #endif
    }
}

проверяю. пишу по середине большое количество байт чтоб перейти на другую страницу.
Код
uint8_t rxbuffer[50];
for (int i=0; i < 50; i++)
{
    rxbuffer[i] = i+1;
}
LOGGER_PageWrite(80, 50, rxbuffer);

и потом считываю.
Код
uint8_t txbuffer[50];
LOGGER_Read(80, 50,txbuffer);

результаты такие:
в адрессе 80-127 я вижу данные 1-47 и это правильно
в адрессе 128-130 я вижу /0, 48, 49

то есть первый адресс следующей страницы не прописывается. целый день бьюсь над проблемой не могу понять в чем дело.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Jenya7
сообщение Apr 12 2016, 14:18
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



ввел задержку.
Код
busy = 1;
//wait for write operation to complete
while(busy)
{
    busy = (SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP);
    Delay_us(1);
}

теперь все прописывается корректно. очевидно нога слейв селект не успевала отработать в цикле.
спасибо за помощь.

что интересно - во всех примерах статус регистр опрашивается в цикле без задержки. или это я такой особенный или ребята выдают код с багами.

вобщем я оптимизировал чтение статус регистра.
функцию чтения нужно переписать так
Код
uint8_t SPIEEPROM_ReadStatus(void)
{
    uint8_t status;
    //SPI_CSlow();  //outside

    // send read status register command
    //SPI_SendByte(SPIEEPROM_CMD_RDSR);  //transfer - not send
    SPI_TransferByte(SPIEEPROM_CMD_RDSR);

    // get status register value
    status = SPI_TransferByte(0xFF);

    //SPI_CShigh();  //outside

    return status;
}

а управление слейв селект вынести вне цикла.
Код
busy = 1;
//wait for write operation to complete
SPI_CSlow();
while(busy)
{
    busy = (SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP);
}
SPI_CShigh();


Сообщение отредактировал Jenya7 - Apr 12 2016, 14:47
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 13 2016, 05:46
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Jenya7 @ Apr 12 2016, 20:18) *
ввел задержку.
Delay_us(1);
теперь все прописывается корректно. очевидно нога слейв селект не успевала отработать в цикле.

Я Вам несколько раз писал, что у Вас между CShigh и следующим CSlow нет никакого интервала времени.

Цитата(Jenya7 @ Apr 12 2016, 20:18) *
а управление слейв селект вынести вне цикла.
...

Лучше каждую новую команду к EEPROM начинать с нового спада импульса на CS. Каждый спад CS должен сбрасывать автомат состояний внутри микросхемы (перезапускать битовые и прочие счётчики).
Бит занятости в слове статуса - 0-й бит? Если да - можно ещё попробовать просто выдать команду чтения статуса и дальше просто держать CS и смотреть на состояние линии MISO: некоторые микросхемы SPI-flash, в которых в статусном регистре бит занятости 0й, могут выдавать в этом случае на линию MISO текущее состояние бита. Т.е. - просто ждёте пока линия не перейдёт в состояние свободно - операция записи закончилась. Если Ваша EEPROM так умеет, тогда не нужно периодически выдавать команду чтения статуса - достаточно её передать один раз.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 13 2016, 06:29
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(jcxz @ Apr 13 2016, 11:46) *
Я Вам несколько раз писал, что у Вас между CShigh и следующим CSlow нет никакого интервала времени.


Лучше каждую новую команду к EEPROM начинать с нового спада импульса на CS. Каждый спад CS должен сбрасывать автомат состояний внутри микросхемы (перезапускать битовые и прочие счётчики).
Бит занятости в слове статуса - 0-й бит? Если да - можно ещё попробовать просто выдать команду чтения статуса и дальше просто держать CS и смотреть на состояние линии MISO: некоторые микросхемы SPI-flash, в которых в статусном регистре бит занятости 0й, могут выдавать в этом случае на линию MISO текущее состояние бита. Т.е. - просто ждёте пока линия не перейдёт в состояние свободно - операция записи закончилась. Если Ваша EEPROM так умеет, тогда не нужно периодически выдавать команду чтения статуса - достаточно её передать один раз.

бит 0-й но насколько я понял чтобы получить статус регистор надо каждый раз передавать команду. если передергивать слейв селект надо вводить задержку. не знаю насколько это хорошо.

Сообщение отредактировал Jenya7 - Apr 13 2016, 06:33
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 13 2016, 06:33
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Jenya7 @ Apr 13 2016, 12:29) *
бит 0-й но насколько я понял чтобы получить статус регистор надо каждый раз передавать команду. если передергивать слейв селект надо вводить задержку.

Откройте диаграмму чтения слова состояния в даташите. Там обычно рисуют что после последнего клока остаётся состояние последнего выдвинутого бита сколько угодно долго. Вопрос только в том - выводится ли там текущее состояние бита занятости или защёлкнутое в момент перепада SCLK.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 13 2016, 06:50
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(jcxz @ Apr 13 2016, 12:33) *
Откройте диаграмму чтения слова состояния в даташите. Там обычно рисуют что после последнего клока остаётся состояние последнего выдвинутого бита сколько угодно долго. Вопрос только в том - выводится ли там текущее состояние бита занятости или защёлкнутое в момент перепада SCLK.

там написано так.
Цитата
To read the status register, the host simply sends a RDSR command. After receiving the last bit of the command, the CAT25256 will shift out the contents of the status register on the SO pin (Figure 10). The status register may be read at any time, including during an internal write cycle. While the internal write cycle is in progress, the RDSR command will
output the full content of the status register (New product, Rev. E) or the RDY (Ready) bit only (i.e., data out = FFh) for previous product revisions C, D (Mature product). For easy detection of the internal write cycle completion, both during writing to the memory array and to the status register, we
recommend sampling the RDY bit only through the polling routine. After detecting the RDY bit “0”, the next RDSR instruction will always output the expected content of the status register.

они рекомендуют поллинг то есть обращение к регистру в цикле. непонятно только что делать с ногой слейв селект.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 13 2016, 16:41
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Apr 13 2016, 09:50) *
непонятно только что делать с ногой слейв селект.

Цитата

Every communication session between host and CAT25256 must be preceded by a
high to low transition and concluded with a low to high transition of the CS input.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 13 2016, 17:01
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Автор совершенно не желает читать даташит..... sad.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Jenya7   Запись в Serial EEprom.   Apr 11 2016, 13:01
- - aaarrr   Какой-то ужас, если честно. Кодvoid eep_write...   Apr 11 2016, 20:26
|- - jcxz   Цитата(aaarrr @ Apr 12 2016, 02:26) Какой...   Apr 12 2016, 07:07
- - Jenya7   я извиняюсь немного непонятно это Кодdata += a; ad...   Apr 12 2016, 07:03
|- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 10:03) я изв...   Apr 12 2016, 07:09
- - Jenya7   большое спасибо так работает. причем тестироват...   Apr 12 2016, 07:25
|- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 10:25) нужно...   Apr 12 2016, 07:53
|- - jcxz   Цитата(aaarrr @ Apr 12 2016, 13:53) Может...   Apr 12 2016, 08:16
|- - aaarrr   Цитата(jcxz @ Apr 12 2016, 11:16) А зачем...   Apr 12 2016, 08:26
|- - jcxz   Цитата(aaarrr @ Apr 12 2016, 14:26) Выход...   Apr 12 2016, 08:59
|- - Jenya7   Цитата(jcxz @ Apr 12 2016, 14:59) Да, а п...   Apr 12 2016, 09:08
|- - jcxz   Цитата(Jenya7 @ Apr 12 2016, 15:05) это у...   Apr 12 2016, 09:16
|- - Jenya7   Цитата(jcxz @ Apr 12 2016, 15:16) Так а к...   Apr 12 2016, 09:21
- - esaulenka   ЦитатаСуд. Бракоразводный процесс. Судья спрашивае...   Apr 12 2016, 08:05
- - Jenya7   таймаут нужен чтоб не застрять навсегда в цикле. у...   Apr 12 2016, 08:27
|- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 11:27) тайма...   Apr 12 2016, 08:39
|- - Jenya7   Цитата(aaarrr @ Apr 12 2016, 14:39) Вот д...   Apr 12 2016, 08:48
|- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 11:48) у мен...   Apr 12 2016, 08:51
||- - Jenya7   Цитата(aaarrr @ Apr 12 2016, 14:51) А смы...   Apr 12 2016, 09:00
||- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 12:00) ничег...   Apr 12 2016, 09:50
||- - jcxz   Цитата(aaarrr @ Apr 12 2016, 15:50) Взял ...   Apr 12 2016, 09:59
||- - Jenya7   Цитата(aaarrr @ Apr 12 2016, 15:50) Взял ...   Apr 12 2016, 10:02
||- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 13:02) моя с...   Apr 12 2016, 13:10
||- - jcxz   Цитата(Jenya7 @ Apr 12 2016, 16:02) получ...   Apr 12 2016, 13:53
|- - jcxz   Цитата(Jenya7 @ Apr 12 2016, 14:48) но ес...   Apr 12 2016, 09:03
- - Jenya7   чобы было легче дебагировать я немного переделал о...   Apr 12 2016, 13:36
- - aaarrr   Цитата(Jenya7 @ Apr 12 2016, 17:18) что и...   Apr 12 2016, 14:45


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 23:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01485 секунд с 7
ELECTRONIX ©2004-2016