|
|
  |
Запись в Serial EEprom. |
|
|
|
Apr 12 2016, 09:08
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(jcxz @ Apr 12 2016, 14:59)  Да, а потом ещё не забыть сделать обработку этих возвращаемых статусов ошибок во всех точках вызова (что обычно обязательно забывают где-нить сделать). Или вернуть этот статус выше и там обработать. В любом случае с этой ошибкой (таймаут неготовности) надо что-то делать. А что делать? Ведь если превышен таймаут (который выставлен правильно в соответствии с даташитом), то значит микросхема не функционирует. Вы все характеристики всех элементов в схеме проверяете на их соответствие заявленным в даташите, или всё же предполагаете, что она должна функционировать как обещал производитель? Я обычно тоже делаю контроль таймаута в таких случаях, но при возникновении события таймаута (превышения времени заявленного в даташите) не возвращаю какой-то статус, а вызываю событие "критическая ошибка" (так как это явно отказ аппаратуры). Обработчик такого события или просто выполняет аппаратный сброс или например входит в состояние "критическая ошибка" с индикацией этого состояния (в режиме отладки).
Хорошо, вот наступил этот таймаут. Ваши действия? Что после этого делать-то? это уже следующий этап. сейчас мне важно чтоб система не зависла. в принцине у меня есть переменная которая содержит флаги ошибок которые я периодически тестирю в коде. Цитата(jcxz @ Apr 12 2016, 15:03)  А как такое может быть - "обращения к SPI при выключенном клоке"??? Ведь этим клоком должен управлять этот-же код, который управляет обменом по SPI. Значит он сам его и выключил? это маловероятно - но на этот случай есть таймаут.
|
|
|
|
|
Apr 12 2016, 09:16
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Jenya7 @ Apr 12 2016, 15:05)  это уже следующий этап. сейчас мне важно чтоб система не зависла. в принцине у меня есть переменная которая содержит флаги ошибок которые я периодически тестирю в коде. Так а как Вы вообще отлаживаете? Что значит "не важно"? Вот у Вас скажем одно из обращений к EEPROM закончилось таймаутом, выставился где-то какой-то флаг и поехало дальше выполнение. Дальше опять вызывается транзакция с этой EEPROM, а у Вас при старте транзакции не проверятся что предыдущая завершилась (а предыдущая завершилась таймаутом и EEPROM всё ещё busy) и Вы начинаете гнать туда какие-то байты, считая что идёт запись. В это время EEPROM по середине этих данных наконец снимает статус busy и воспринимает очередной байт данных как некую команду (например стирания или записи или перевода в сон и т.п.). И что будет после этого в Вашем ПО и EEPROM? Каша! Вот именно поэтому и могут происходить такие проблемы как Вы писали в первом посте. Ну а если вообще также халтурно подходить к написанию ПО, то вообще где угодно могут быть проблемы. Цитата(Jenya7 @ Apr 12 2016, 15:08)  это маловероятно - но на этот случай есть таймаут. Пипец просто! Вы читаете что Вам пишут? Ваш таймаут - это костыль на Ваши же баги. Таймаут вообще не для этого нужен. Он нужен чтобы отследить сбои в работе вызванные внешними причинами (неисправностью внешней микросхемы), а не проблемами в Вашем коде.
|
|
|
|
|
Apr 12 2016, 09:21
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(jcxz @ Apr 12 2016, 15:16)  Так а как Вы вообще отлаживаете? Что значит "не важно"? Вот у Вас скажем одно из обращений к EEPROM закончилось таймаутом, выставился где-то какой-то флаг и поехало дальше выполнение. Дальше опять вызывается транзакция с этой EEPROM, а у Вас при старте транзакции не проверятся что предыдущая завершилась (а предыдущая завершилась таймаутом и EEPROM всё ещё busy) и Вы начинаете гнать туда какие-то байты, считая что идёт запись. В это время EEPROM по середине этих данных наконец снимает статус busy и воспринимает очередной байт данных как некую команду (например стирания или записи или перевода в сон и т.п.). И что будет после этого в Вашем ПО и EEPROM? Каша!
Вот именно поэтому и могут происходить такие проблемы как Вы писали в первом посте. Ну а если вообще также халтурно подходить к написанию ПО, то вообще где угодно могут быть проблемы.
Пипец просто! Вы читаете что Вам пишут? Ваш таймаут - это костыль на Ваши же баги. Таймаут вообще не для этого нужен. Он нужен чтобы отследить сбои в работе вызванные внешними причинами (неисправностью внешней микросхемы), а не проблемами в Вашем коде. Вы знаете мне бы хотелось для начала отладить запись в EEPROM а потом уже решать остальные проблемы. и если рассуждать логически - если заменив это Код while(SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP) { //NO TIMEOUT } на это Код Delay_us(5000); все успевает прописаться то очевидно предыдущий код не содержит смертных грехов.
|
|
|
|
|
Apr 12 2016, 10:02
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(aaarrr @ Apr 12 2016, 15:50)  Взял первую попавшуюся цифру для SPI - 3uA/MHz. Но не надо забывать, что это цифра для работающей периферии, а не простаивающей с включенным клоком. Реальное значение лучше замерить, и сомневаюсь, что Вы найдете сколько-нибудь значительную разницу. моя система потребляет 6 микро в ожидающем режиме. много-мало это беспредметный спор - все зависит от требований. вот почему статус бит не тестируется - вот это вопрос. желательно разрешить проблему пока предупреждения не досигли 100%. Товарищ Herz не дремлет, спасибо ему.  в даташит написано Код tWC (Note 13) Write Cycle Time 5 ms .
13.tWC is the time from the rising edge of CS after a valid write sequence to the end of the internal write cycle. получается как ни крути а 5мс нужно ждать?
Сообщение отредактировал Jenya7 - Apr 12 2016, 12:48
|
|
|
|
|
Apr 12 2016, 13:10
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Jenya7 @ Apr 12 2016, 13:02)  моя система потребляет 6 микро в ожидающем режиме. Верю. Но тут вопрос сколько она потребляет в активном режиме, и сколько на этом фоне занимает SPI. Цитата(Jenya7 @ Apr 12 2016, 13:02)  получается как ни крути а 5мс нужно ждать? Почему? 5мс - максимальное время записи, опрашивать статусный регистр можно и нужно.
|
|
|
|
|
Apr 12 2016, 13:36
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
чобы было легче дебагировать я немного переделал опрос регистра статуса. Код busy = 1; //wait for write operation to complete while(busy) { busy = (SPIEEPROM_ReadStatus() & SPIEEPROM_STATUS_WIP); } когда то бит обнуляется. в режиме отладчика реальное время трудно замерять. но подозреваю что бит не отражает реальное положение вещей.
|
|
|
|
|
Apr 12 2016, 13:53
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Jenya7 @ Apr 12 2016, 16:02)  получается как ни крути а 5мс нужно ждать? Нет. Нужно правильно написать чтение статуса. Цитата(Jenya7 @ Apr 12 2016, 19:36)  когда то бит обнуляется. в режиме отладчика реальное время трудно замерять. но подозреваю что бит не отражает реальное положение вещей. Отражает. Ищите баги у себя.
|
|
|
|
|
Apr 12 2016, 14:18
|
Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Apr 13 2016, 05:46
|
Гуру
     
Группа: Свой
Сообщений: 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 так умеет, тогда не нужно периодически выдавать команду чтения статуса - достаточно её передать один раз.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|