В статье "Часть 12. STM32 и C++. I2C в Cortex-M4" я описал, как работать с I2C на ядрах Cortex-M4. Продолжая работать с I2C на других чипах, я столкнулся с тем что данный способ общения с I2C корректен не для всех ядер. Описанный способ точно подходит для STM32F405xx и STM32F407xx, вполне возможно что подходит также и для STM32F415, STM32F417 и STM32F43x. Проверить это утверждение я не могу, так как нет необходимых МК. Что точно могу сказать, для серии STM32F411xx этот метод точно не походит, но к этому МК вернёмся чуть позже.
Сейчас рассмотрим STM32F030x4/x6/x8/xC и STM32F070x6/xB (про серию STM32F0x1/STM32F0x2/STM32F0x8 пока сказать ничего не могу, позже проверю и в комментариях отпишу). У него, да и у многих других МК, в регистре CR2 есть два интересных поля: NBYTES[7:0] - в который пишется количество байт/слов которое мы хотим передать и SADD[9:0] - в который пишется адрес устройства, к которому мы хотим обратиться. А так как не нужны пляски с бубном, как у F407, здесь код получается попроще. Я не буду приводить длиннющие куски кода, просто опишу алгоритм, а как это оформлено можно посмотреть в библиотеке.
Алгоритм чтения.
- Ждём флаг BUSY
- В регистре CR2:
- Сбрасываем:
- SADD
- NBYTES
- RELOAD
- AUTOEND
- RD_WRN
- START
- STOP
- Устанавливаем:
- SADD
- NBYTES
- AUTOEND или RELOAD
- READ
- START
- Сбрасываем:
- Ждём флаг RXNE
- В цикле из регистра RXDR считываем данные
- Ждём флаг STOP
- В регистре статуса ICR сбрасываем флаг STOPCF
- В регистре CR2 сбрасываем:
- SADD
- HEAD10R
- NBYTES
- RELOAD
- RD_WRN
- Выходим
Вроде всё просто, но есть нюансы.
Шаг 2 - я написал флаги и регистры по порядку, но не всё так просто. Есть МК, у которых эти команды можно выполнить пошагово, на F030CCx я столкнулся с тем, что необходимо считать регистр целиком, сбросить необходимые биты, установить необходимые биты и записать это всё обратно. Как только запишем получившуюся команду, I2C выплюнет на линию адрес с запросом на чтение и будет ждать ответа. Ещё один нюанс, на обычных I2C устройствах этот шаг не критичен, а при работе с микросхемами памяти - критичен. Если при работе с памятью мы не выполним это условие, то зависнем на третьем шаге.
Шаг 3 - интереса не представляет.
Шаг 4 - в шаге 2.2.3 указано два флага, а не один. Эти флаги влияют на количество принимаемых байт. Регистр NBYTES имеет длину 8 бит. Соответственно, мы можем передать только 255 байт/слов, а мы хотим принять 100500. Для приёма всей информации нам нужно разбить её на блоки по 255 байт. Мы записываем в NBYTES число 255, устанавливаем указатель на на