|
I2C LPC2xxx |
|
|
|
Sep 25 2009, 16:51
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Есть исходник, работающий через I2C с термометром. Тестирую его без FreeRTOS - работает стабильно и долго. Запускаю Ось - глючит сильно, и иногда работает. I2C работает через прерывание. Компилятор CW. Под Осью оно описано так: Код void vI2C_ISR_Wrapper( void ) { /* Save the context of the interrupted task. */ portSAVE_CONTEXT();
/* Call the handler. This must be a separate function from the wrapper to ensure the correct stack frame is set up. */ vI2C_ISR_Handler();
/* Restore the context of whichever task is going to run next. */ portRESTORE_CONTEXT(); } без оси так: Код void vI2C_ISR_Handler( void ) { asm("STMDB SP!,{R0-R12,LR}"); // пролог для IRQ ... VICVectAddr = 0; /* Acknowledge Interrupt */ asm( "LDMIA SP!,{R0-R12,LR} \n" // эпиолог для IRQ "SUBS PC,LR,#4 "); } Прерывания в обоих случаях внутри обработчиков запрещены. Начинка прерывания была взята из примеров с сайта NXP, хотя немного переделана. Параллельно с работой I2C прерывания работает FIQ с частотой 8 КГц. FIQ работает стабильно под осью и без оси, и на глюки в обоих вариантах (с осью/без) не влияет. Вопрос: куда копать? Может кто описать особенности "написания программы" под FreeRTOS ? В том смысле, что вот этого например делать нельзя, или на вот это нужно обратить особое внимание, или ещё что-нить. Проект большой, так что выложить бОльшие куски кода пока не могу.
Сообщение отредактировал GetSmart - Sep 25 2009, 17:02
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 25 2009, 20:01
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(GetSmart @ Sep 25 2009, 18:51)  глючит сильно Исчерпывающе  . Цитата Может кто описать особенности "написания программы" под FreeRTOS ? Да нет никаких особенных особенностей. Цитата(HARMHARM @ Sep 25 2009, 21:50)  Нужно ли вообще сохранять контекст внутри прерывания? Подозреваю, что для столь медленного девайса, как I2C термометр это (обеспечение вызова переключения контекста из обработчика) по любому излишество.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 25 2009, 21:28
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(zltigo @ Sep 26 2009, 02:01)  Исчерпывающе  .  Правильнее было бы написать, что принимаются неправильные данные по i2c. Вероятнее всего криво написанный обработчик, точнее сама его начинка, а не прологи/эпилоги. Я с того времени накатал простенький обработчик i2c. Вот, если кто обнаружит ошибки - буду признателен. Проц LPC2368 CODE void vI2C_ISR_Handler( void ) { asm("STMDB SP!,{R0-R12,LR}"); // пролог для IRQ
switch ( I20STAT ) { case 0x08: // передан первый START, далее передать SLA case 0x10: // передан повторный START без STOP-a // I20CONCLR = STA; //??? I20CONSET = AA; I2CMasterState = I2C_STARTED; if (WrIndex < I2CWriteLength) // если есть данные для передачи I20DAT = I2CMasterAddr; else I20DAT = I2CMasterAddr | 0x01; // иначе будет чтение данных break;
case 0x18: // принят ACK после SLA+W case 0x28: // принят ACK после Byte Send I2CMasterState = DATA_ACK; if (WrIndex < I2CWriteLength) { I20DAT = I2CBuffer[WrIndex++]; I20CONSET = AA; } else if (I2CReadLength != 0) // если требуется что-то прочитать { I20CONSET = STA | AA; // повторить START для чтения данных } else { I20CONSET = STO | AA; // завершить обмен по I2C I2CMasterState = DATA_NACK; // реально - удачное завершение обмена } break;
case 0x50: // передан ACK после Byte Receive case 0x58: // передан NACK после Byte Receive (проверить реально ли NACK ?) if (RdIndex < I2CReadLength) I2CBuffer[RdIndex++] = I20DAT; case 0x40: // принят ACK после SLA+R // I2CMasterState = DATA_ACK; if ((RdIndex+1) < I2CReadLength) I20CONSET = AA; // будет ACK // если есть место куда ложить байты else if ((RdIndex+1) == I2CReadLength) I20CONCLR = AA; // будет NACK // если есть место куда ложить байты else { I20CONSET = STO | AA; // завершить обмен по I2C I2CMasterState = DATA_NACK; // реально - удачное завершение обмена } break;
case 0x20: // после SLA+W принят NACK case 0x30: // после Byte Send принят NACK case 0x48: // после SLA+R принят NACK I20CONSET = STO | AA; // case 0x38: // потеря арбитража default: I2CMasterState = DATA_ERROR; // завершение обмена break; }
I20CONCLR = SI;
VICVectAddr = 0; /* Acknowledge Interrupt */ asm( "LDMIA SP!,{R0-R12,LR} \n" // эпиолог для IRQ "SUBS PC,LR,#4 "); } И ещё я не понял, как мастер узнаёт когда передавать 9 клоков после передачи SLA+R и получении ACK ? Проц взводит флаг SI, I20STAT становится = 0x40, входит в прерывание. С какого момента начинают передаваться клоки - сразу после доступа к I20CONSET/I20CONCLR или по сбросу SI или ещё когда? И после приёма байта когда мастер начинает вырабатывать 9 клоков - аналогично предыдущему случаю или сразу после чтения I20DAT ? Или может проц вырабатывает 8 клоков, и только после записи AA вырабатывает 9-ый. Осцилла нет да сроки поджимают очень, а так бы проверил. Цитата(zltigo @ Sep 26 2009, 02:01)  Подозреваю, что для столь медленного девайса, как I2C термометр это (обеспечение вызова переключения контекста из обработчика) по любому излишество. То есть, во FreeRTOS можно (рекомендуется?) делать IRQ без обёрток portSAVE_CONTEXT() ? То есть самым обыкновенным способом, как я сделал в примере без оси?
Сообщение отредактировал GetSmart - Sep 25 2009, 21:18
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 25 2009, 21:55
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(GetSmart @ Sep 25 2009, 23:28)  То есть, во FreeRTOS можно (рекомендуется?) делать IRQ без обёрток portSAVE_CONTEXT() ? То есть самым обыкновенным способом, как я сделал в примере без оси? Ни нафиг не сдались, если не преключать контекст из обработчика прерывания. Для только перепланировки есть отдельная группа функций "from isr". Ваш обработчик не читал. Образчик своего когда-то на на форуме выкладывал. Пользуюсь постоянно в основном для EEPROМ в том числе и на высоких скоростях. P.S. Увлечение asm вставками зачем?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 25 2009, 22:33
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(zltigo @ Sep 26 2009, 03:55)  Увлечение asm вставками зачем? Я тут уже отчитывался по кривому коду, генерируемому CW 1.7.9 http://electronix.ru/forum/index.php?showt...st&p=651216Вот такой прототип обратботчика void NameIntr() __attribute__((interrupt("IRQ"))); правильно работает только на 0 уровне оптимизации, то есть с самым тормознутым кодом. На уровнях 1 и выше приходится делать ручные вставки. Цитата(zltigo @ Sep 26 2009, 03:55)  Образчик своего когда-то на на форуме выкладывал. Вот этот? http://electronix.ru/forum/index.php?showt...ost&p=90212А он для 2368 подойдёт? Там ничего не поменяли? Я злой  На Manual 2368. Где там указано, что при статусе 0x08/0x10 нужно сбрасывать STA (I20CONCLR = STA) ? В разделе (((10.6 Master states->10.6.1 State : 0x08))) нету такого. И ещё непонятно зачем почти для всех статусов нужно записывать AA в I2CONSET. Зря я NXP-шников защищал когда-то.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 25 2009, 23:02
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(GetSmart @ Sep 26 2009, 00:33)  На Manual 2368... Не читал  контроллер I2C не менялся со времен филипсовских 51. В первых мануалах на LPC2114 даже вообще не описывали никак. Цитата Вот этот? Да, лабораторная работа, так сказать. Реальный отличается, но не принципиально.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 25 2009, 23:14
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Грёбаный компилятор CW. Я щас с ума сойду от таких ошибок. Оптимизация = level1 Упс. Там мой косяк. Написал ненароком if (WrIndex >= I2CWriteLength) tmp | 0x01; А компилер даже не заругался.
Сообщение отредактировал GetSmart - Sep 25 2009, 23:23
Эскизы прикрепленных изображений
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 25 2009, 23:35
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(aaarrr @ Sep 26 2009, 05:23)  Может, сменить/починить инструмент, коли все так запущено? А на что его сменить? Студия-то неплохая, компилятор (внешний, GNU) - ховно. Цитата(zltigo @ Sep 26 2009, 05:02)  Да, лабораторная работа, так сказать. Реальный отличается, но не принципиально. У Вас там не всё гладко. Не формируется NACK на последнем принимаемом байте, из-за этого статуса 0x58 никогда не будет. А если (гипотетически) туда залетит прога, то зачем-то снова START формируется.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|