Перейти к содержанию
    

При запуске из отладчика программа работает, когда отключаешь и снова включаешь STM32 программа перестает работать

Дык, вы и меня поймите: раз без ногодрыга I2C гарантированно работать не может, то в моем случае я вообще отказался от аппаратного I2C

и сделал все ногодрыгом.

Почему не может?

Во-первых: это не штатная работа, а процесс инициализации из произвольного состояния (сброса без снятия питания).

Во-вторых: это только на данном МК так (STM32F4xx), возможно там можно сделать такой сброс и через возможности штатного контроллера I2C, но оно особо не нужно разбираться - это однократная короткая операция при старте, по большому счёту без разницы как она работает. А вот штатный обмен да ещё со множеством устройств да ещё когда среди этих устройств есть FRAM-память с пересылками в несколько десятков КБ и есть устройства выдающие периодически пачки в десятки-сотни байт (тачскрин) - делать это не то что без DMA, а ещё и ногодрыгом - ну это просто какая-то уже совершенно абдуринщина в запущенной стадии. :laughing:

 

PS: У меня в текущем проекте на XMC4500, контроллер I2C гораздо мощнее STM-ного. Здесь думаю сделать процедуру сброса при старте (несколько СТОП-условий) силами самого I2C-контроллера. Потому что на XMC4500 это сделать даже проще чем ногодрыгом. У него вообще можно всю транзакцию (СТАРТ+адрес+W, запись адреса регистра, РЕСТАРТ+адрес+R, N-чтений с ACK, 1 чтение NACK, СТОП) - можно записать одним блоком сразу в FIFO I2C и запустить на выполнение на машине состояний I2C-контроллера. А в конце транзакции получить ОДНО прерывание о завершении и вычитать из FIFO результат. Каждое слово (11 бит) в блоке: младшие 8 бит - слэйв-адрес или байт данных, старшие 3 бита - команда-состояние I2C (СТАРТ,РЕСТАРТ,СТОП,передача,...). И ISR очень простой и всего одно прерывание в конце - просто красота по сравнению с STM. Не говоря уже о ногодрыге... При желании можно подключить и DMA для наполнения FIFO I2C.

Все нештатные ситуации - NACK, lost arbitration и т.п. - отслеживаются самим I2C-контроллером, выдаётся нештатное СТОП-условие на шину (или завершение приёма байта, NACK и СТОП если идёт приём) и прерывание с флагами ошибки в регистре статуса. :rolleyes:

 

А я прекрасно понимаю :laughing: потому что на разных МК модули I2C настолько разные, и частенько, настолько кривые, что применять их просто не хочется.

Так может нужно выбирать МК с хорошей периферией? :rolleyes:

Оцените как выглядит и насколько простая реализация обмена по I2C на XMC4500:

extern "C" void concat(isrUSIC, USIC_UNIT(nUSIC_i2c), _, SRUSIC_SR(nUSIC_SR_i2c_CTRL))()
{
 u32 i = io->PSR;
 if (i & (B0 | B1 | B5 | B6 | B8 | B11 | B16)) trap(TRAP_I2C_ERROR, i);
 io->PSCR = i;
 if (!(i & B4)) return;
 io->TCSR_b[1] = B0;
 IsrEnter();
 MboxPost(mbox);
 IsrExit();
}

//Запись в регистры MPU-6050.
//ra - начальный адрес регистра MPU-6050 для записи;
//data/len - указатель/длина блока записываемых данных.
//return: !=0 - всё ок.
int GyroWr(uint ra, void const *data, uint len)
{
 assert(len <= FIFO_SIZE - 3, TRAPR_GYRO);
 SemPend(sem);
 io->IN[0] = TDF_START | GYRO_ADDR << 1;
 io->IN[0] = TDF_TX | ra;
 for (u8 const *s = (u8 const *)data; (int)--len >= 0; ) io->IN[0] = TDF_TX | *s++;
 io->IN[0] = TDF_STOP;
 io->TCSR_b[1] = B0 | 1 << 2;
 MboxPend(mbox);
 SemPost(sem);
 return 1;
}

//Чтение из регистров MPU-6050.
//ra - начальный адрес регистра MPU-6050 для чтения;
//data/len - указатель/длина блока записываемых данных.
//return: кол-во прочитанных байт; ==0 - произошла ошибка.
int GyroRd(uint ra, void *data, uint len)
{
 assert(data && len - 1 <= FIFO_SIZE - 5, TRAPR_GYRO);
 SemPend(sem);
 io->IN[0] = TDF_START | GYRO_ADDR << 1;
 io->IN[0] = TDF_TX | ra;
 io->IN[0] = TDF_RSTART | GYRO_ADDR << 1 | B0;
 for (ra = len; --ra; ) io->IN[0] = TDF_RX_A;
 io->IN[0] = TDF_RX_NA;
 io->IN[0] = TDF_STOP;
 io->TCSR_b[1] = B0 | 1 << 2;
 MboxPend(mbox);
 if ((ra = io->TRBSR_b[2]) - 1 >= len) trap(TRAP_I2C_RXOVER, ra);
 u8 *s = (u8 *)data;
 len = ra;
 do *s++ = io->OUTR;
 while (--ra);
 SemPost(sem);
 return len;
}

Первая функция - ISR. Пока нет обработки ошибочных ситуаций (не получен ACK на slave addr, lost arbitration и т.п.), позже добавлю - это мелочи.

 

например еще не подано питание на slave или обращение к нему произошло до того, как завершился его startup. Нормальный I2C должен дать ошибку и возможность привести автомат в нормальное состояние, а не впадать в клиническую смерть.

Нормальный драйвер I2C не должен допускать таких ситуаций, ибо то о чём Вы пишете - баги в реализации алгоритма драйвера.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По поводу I2C. До 2010 года активно использовал AVR8 для safety-critical проектов. Машина состояний там имеет аппаратную ошибку, подтвержденную тогда еще Atmel'ом. Сут= ее в том, что помехи на шине приводили к потере арбитража в Multi-master mode и шина зависала. Для решения, одновременно с циклом обмена, запускался таймер в режиме watchdog. Если цикл приема-передачи не завершался вовремя, таймер выключал и тут же включал периферию. После перехода проекта на Cortex-M проверял устойчивость I2C на FPGA(NIOS-II), NXP, Atmel, STM32F2xx/4xx(F1xx сильно отличается). Итого: к NXP нет никаких претензий, Atmel не давал никакой возможности stretch cycle, STM худо-бедно позволяла работать НО без всяких кубов/SPL. При этом, подчеркну, что создавал помехи, подключая на шину GPIO с открытым коллектором, управляемым хаотично(0/1) в короткие промежутки времени(единицы us) и проверял целостность и времена трансферов. The product safety tests were completed succesfully.

Данная информация доведена до вашего сведения, а не для дальнейших дискуссий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...