I2C EEPROM-bit-banging: записывает нормально, но только если первый бит не установлен

9

В настоящее время я работаю над проектом I2C EEPROM, использующим битовые удары для управления линиями SDA и SCL.

Моя функция чтения работает нормально, но всякий раз, когда я пишу какой-либо байт с ведущей «1», я всегда читаю FF назад; даже если байт был запрограммирован с чем-то еще раньше. Ведущий «0» идеален. Это не моя рутина чтения; как я вижу по области, он возвращает FF.

Я ищу предложения о том, почему это может быть. Есть ли очевидное, что я мог пропустить, что может вызвать проблемы? [Я не могу опубликовать код - компания конфиденциальна ... :(]

Каждая форма волны, на которую я смотрю, точно соответствует спецификации. Я отделяю EEPROM. Мои подтягивания 2,2 к, так что в пределах спецификации. Я работаю на частоте около 500 Гц в этом прототипе. Чип отправляет ACK на каждый из моих байтов, чтобы он их распознал. Но это просто не работает ...

Я использую микрочип 24LC256 .

Упрощенный алгоритм записи для одного байта:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

Упрощенный алгоритм чтения для одного байта:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte
Томас О
источник
1
@ Джастин - я думаю, он говорит, что запись значения 0x7F на любой адрес работает, но запись 0x80 на любой адрес не работает.
Ракетный
1
Это то, что заставляет меня ненавидеть I2C.
Ракетный
1
У меня сумасшедшая догадка. В вашем для каждого битового кода вы невольно расширяете знак с помощью операции сдвига вправо? Если вы станете лидером, со временем вы получите 0xFF после 7 смен.
Викацю
3
Ирония здесь в том, что это кодекс компании. Это ценно для них. Все остальные здесь делятся кодом, который работает. Что отличает код этой компании от других, так это то, что он не работает.
gbarry
2
Трудно представить, почему компания так отчаянно нуждается в сохранении конфиденциальности кода. В интернете так много всего.
Ракетный

Ответы:

4

Вы читаете данные после того, как часы снова низки. Вам придется делать это между повышением часов и снижением их. После того, как время на часах низкое, ведомому разрешается изменять линию данных, а не когда она высокая.

введите описание изображения здесь

Так что чтение должно быть таким:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte
stevenvh
источник
Неплохо подмечено; Я исправлю это. Тем не менее, мои данные все еще отображаются как «все единицы» (FF) в моей области видимости, поэтому мое чтение не может быть проблемой ... :(
Thomas O
3

В конце концов, проблема заключалась в том, что я случайно отправлял условие STOP при некоторых условиях из-за искаженного времени. Я отказался от использования прицела и вышел из логического анализатора, и смог исправить проблему за 15 минут, поскольку он выдвинул на первый план ОСТАНОВКУ, которой не должно было быть. Я выберу, кому отдать награду, основываясь на наиболее полезном ответе. Спасибо за все решения.

Томас О
источник
Рад, что вы решили это «проверить время записи»
3
Я говорил вам, что это можно решить, посмотрев на форму волны.
Ракетный
@Rocketmagnet Я всегда смотрел на форму волны, но никогда не замечал ее раньше.
Томас О
Да, но вы не показали нам форму волны, несмотря на то, что мы неоднократно просили вас об этом. Вы могли бы решить эту проблему несколько дней назад.
Ракетный
@Rocket - согласен. Хотелось бы, чтобы в то время у меня была камера. У Tek DPO, который я использовал, был дисковод, но нет дискеты. Я бы опубликовал картинку, если бы мог.
Томас О
2

Хорошо, ваша область действия доказывает, что 1-й байт, поступающий в PIC, плох, так что это не функция чтения PIC.

Вы проверили правильность времени записи на принимающей стороне?

Это терпит неудачу в обоих режимах ниже?

- Byte mode sequential
- Page mode Sequential

Спецификация показывает, что «самый старший бит (MSB) 'b7' отправляется первым». Это также совпадает, когда b7 = 1, что весь байт считывается как FF. Таким образом, либо он не записывается, а стирается (состояние ошибки), когда b7 = 1, или плохо считывается как FF независимо от предыдущего содержимого. Поскольку каждая запись перед записью является стиранием шириной в байт, может ли она быть плохой записью или неправильным чтением, или время первого байта отличается.

Предложение: Проверьте сигнал PTC во время записи / чтения, чтобы обеспечить нормальную работу. введите описание изображения здесь

Существует возможность использования внешних часов для синхронизации продолжительности цикла E / W с использованием PTC. Вы пытались использовать это?

время цикла tE / W

  • внутренний генератор 7 мс
  • внешние часы 4 ~ 10 мс мин ~ макс

Это соответствует этим критериям?


источник
1

Похоже, это может быть пара вещей:

  1. Что еще есть в автобусе? Может ли быть конфликт шины с другим устройством, которое находится в состоянии сброса или неинициализировано?
  2. Правильно ли вы меняете направление контакта ввода-вывода? Если он работает нормально в выходном случае, вы могли случайно забыть изменить направление вывода на вход и всегда будете читать 0xFF. Вывод может быть оставлен в качестве выхода, управляющего шиной, в то время как вы будете читать с него.
  3. Есть ли у вас внутренние подтяжки на самом выводе и / или на линиях ввода / вывода? Микроконтроллеры обычно дают диапазон сопротивления, а не фиксированное значение. Возможно, вы захотите отключить подтягивания на микро и просто использовать дискретные на шине, поскольку вы можете получить более точное сопротивление подтягиванию от дискретных компонентов.
  4. Полярность часов - Вы уверены, что измеряете по правому краю / фазе между часами / данными? Вы могли бы следить за тем, что вам нравится в области действия, но если фаза находится за пределами строки, все, что вы увидите в EEPROM - это 0xFFs (и, скорее всего, вернет то же самое, что, вероятно, неверная команда / условие).
Джоэл Б
источник
1. Просто EEPROM и MCU. 2. Да, я верю, что EEPROM может удерживать SDA / SCL на низком уровне. 3. На плате, расположенной рядом с EEPROM, есть 2.2k 5% подтягиваний.
Томас О
для # 2, вы уверены, что EEPROM - та, которая держит автобус на низком уровне? Есть ли в ЭСППЗУ какие-либо условия в таблице данных, где она будет возвращать все 0xFFs? Смотрите мои правки выше тоже.
Джоэл Б
# 4. EEPROM «подтверждает» мои запросы и работает с некоторыми словами, но не со всеми.
Томас О
0

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

У меня есть безумное предчувствие, что это почти наверняка ошибка программного обеспечения низкого уровня, связанная с сигнатурой некоторых переменных. В вашем для каждого битового кода вы невольно расширяете знак с помощью операции сдвига вправо? Если вы станете лидером, со временем вы получите 0xFF после 7 смен.

Стивен упомянул об этом в комментарии, но вы были свидетелем святости ваших операций записи на осциллографе, или вы только предполагаете, что они работают, основываясь на том, что половина считываний выглядит хорошо? Если вы не пробовали смотреть на операцию записи значения 0xAA, это может быть полезно.

Если вы можете предоставить фактический код вашего внутреннего цикла и объявления переменных, мы могли бы обнаружить ошибку.

vicatcu
источник
Мои записи хороши; Я вижу это по объему. Еще одна странность: адреса с ведущим MSB в порядке. Только данные вызывают проблемы! Я думаю о публикации кода в ближайшее время.
Томас О
1
В поддержку этого ответа: если это код C, измените все объявления char на unsigned char и попробуйте снова.
Воутер ван Ойджен