Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Silabs C8051F32X & 24LC16B
http://mcu-bg.com/mcu_site/viewtopic.php?f=2&t=3819
Страница 1 от 2

Автор:  Реконструктор [ Пон Мар 05, 2007 11:33 am ]
Заглавие:  Silabs C8051F32X & 24LC16B

Набутах се с тоя тъп процесор и взеха да изскачат някви безумни проблеми... :cry: Въпроса, с който ще ви занимая е изключително странен и тъп, много от вас сигурно едва ли ще повярват че се случва точно това, но всеки съмняващ се е добре дошъл за демонстрация.
Проблема се състои в следното. Първоначално подкарах въпросния процесор заедно с въпросната памет, но докато си тествах софтуера, използвах само първите няколко десетки байта. Когато вчера реших да пиша повече, се случи нещо доста странно - всичко спря да работи. След генериране още на най-първия START, с който започва всяка операция с паметта, SI флагът (SMBus Interrupt Flag, SMB0CN.0) изобщо не се вдига никога. Програмата си зацикля там, операциите са с полиране на флага, т.е. блокиращи, не ползвам вектор на прекъсване, а и да ползвам файда няма. Изключване от захранването, 1/2 час престой без захранване и други подобни малоумни подходи, които само един изпаднал програмист може да измисли не дадоха резултат. След като поблъсках няколко часа над проблема, с неохота приех, че нещо съм горнал по платката и се наложи да прехвърля всички жици и периферия на другата, резервна, платка. Подкарах я, и всичко си работеше, докато не реших да отново да пиша повече - случи се същото нещо. Забива на цикъла за проверката SI и толкова. Успях да разбера, че май всичко се скапва след писането на 200-ния байт, може би след първата страница (256 байта), но нямах възможността да разбера повече, щото нямам повече девствени EEPROM-и за тест.
Случайно открих, че ако изтрия програмния флаш, (т.е. запиша FF навсякъде), и после го програмирам на чисто, четенето се оправя, но само до първия reset или опит за писане - след това пак същото. Изключване от захранването и от всичко не дава никви резултати.
Ако някой съвсем, съвсем случайно има няква бегла представа какво може да се случва, бирата е от мен. :cry:

Автор:  Nikola Kirov [ Пон Мар 05, 2007 4:04 pm ]
Заглавие: 

Нещо много мистериозен проблема ти. :)

За да пишеш по големите еепроми има една особенност. Повечето производители ги правят от 24C64 нагоре така.
Ако размера на страницата ти е 64 баита например в един цикъл на запис можеш да пишеш само в границата на една страница началото на всяка страница са адресите кратни на 64.
Тоест ако искаш от адрес 62 да запишеш 4 баита ще трябва да го направиш с 2 записа. Първия на адреси 62 и 63 и в следващия останалите 2 баита. Просто са в различни страници.
Предполагам проблема ти е в това.
А блокването на шината ти вероятно е грешка в функциите на ниско ниво за работа с I2C то. Предполагам че паметта ти остава в състояние в което дава акнолидж и забива SDA.
Трябва да имаш при начално инициализиране и при грешка при комуникацията по шината функция която да инициализира SCL като изход да генерира 2-3 импулса и пак да го конфигурира като управляван от I2C то. Така се излиза от това състояние при което някой слейв при някаква грешка е останал с състояние на акнолидж.

Не е тъп процесора,и при ATmegi ите и при AT91 и при STR712 ми се е налагало да правя такава процедура. Не е хардуерно направена и търябва да се погрижиш софтуерно за това. Дори и да си работи всичко без това ако някой път се получи грешка ситемата забива перманентно.

Автор:  Реконструктор [ Пон Мар 05, 2007 7:20 pm ]
Заглавие: 

Да, предполагах, че може да има нещо такова. В примерния сорс на силабс за четене от еепром, има следният код:

Код:
   // If slave is holding SDA low because of an improper SMBus reset or error
   while(!SDA)
   {
      // Provide clock pulses to allow the slave to advance out
      // of its current state. This will allow it to release SDA.
      XBR1 = 0x40;                     // Enable Crossbar
      SCL = 0;                         // Drive the clock low
      for(i = 0; i < 255; i++);        // Hold the clock low
      SCL = 1;                         // Release the clock
      while(!SCL);                     // Wait for open-drain
                                       // clock output to rise
      for(i = 0; i < 10; i++);         // Hold the clock high
      XBR1 = 0x00;                     // Disable Crossbar
   }


Само че, при мен това не работи, зацикля брзкрайно, защото SDA никога не става 1. Което е доста странно, тъй като като го замеря там си има перфектно напрежение. 8O

Автор:  Реконструктор [ Пон Мар 05, 2007 7:27 pm ]
Заглавие: 

баси, като го мернах, SDA взе, че се дигна и цикъла се прекъсна 8O 8O :?

Автор:  Nikola Kirov [ Пон Мар 05, 2007 8:25 pm ]
Заглавие: 

Да точно това което казвам е проблема ти в такъв случай.
Не съм правил за Cygnal но ако закъсаш ще ти дам моята библиотека за работа с ЕЕпром-и от този тип да си я вържеш към твоята I2C библиотека.
А това за генерирането на няколко клок импулса трябва така или иначе да си го направиш.

Автор:  evc [ Вто Мар 06, 2007 9:12 am ]
Заглавие: 

Точно с този чип на силабс не съм работил, но ти имаш ли някакъв пул-ъп на шините клок и данни? Направи ми впечатление, че "като го мернах" се вдигнало ... Ако си на 400кХц сложи по 1к към +5V, ей така за всеки случай.

Автор:  Predator_MF [ Вто Мар 06, 2007 1:15 pm ]
Заглавие: 

Едва ли е забравил Pullup резисторите, аз подобен проблем съм имал като разчитам на вътрешни pullups на PIC, ама имах 3 устройства на шината и на едното все не му идваше ACK. Тоя номер с разцъкване на SCL за изчакване на ACK е също толкова съмнителен, колкото и проблема, ако всичко е наред в хардуера, ползвай нещо подобно на това:

Код:
char wait_ack(unsigned int wait_time){
unsigned int counter=0;
unsigned char ACK_State;
while( (!SDA) || (counter < wait_time) ){
SCL = 0;
counter++;
}
ACK_State = !SDA;
SCL = 1;
return ACK_State;
}


На процесора все още не съм намерил косур, освен това непериодично прекъсване на USB трансфера, но може и да има някакъв проблем в компютъра ми

Автор:  Nikola Kirov [ Вто Мар 06, 2007 1:48 pm ]
Заглавие: 

Хищник не е съмнителен метода с разцъкването на SCL-a. Това е трик който е наложителен.
Не е изключена възможноста външно смущение да вкара устройството ти в състояние при което някой от слейвовете на шината да остане в състояние на акнолидж.

При това положение поне при процесорите които съм посочил по горе хардуерното I2C изобщо не започва прредаването при положение че SDA е свалена от слейва.
И нормално от това положение няма излизане ако не генерираш един клок импулс така че слейва да освободи шината.

Най често се среща проблем при дебъга на система която постоянно работи с I2C шината. Спираш процесора в момента на клока през които имаш акнолидж и рестартираш. Без този трик I2C то ти просто умира. Вероятно има процесори при които има предвидено хардуерно решение на тази ситуация но аз не съм попадал на такъв.

А това с wait time си е задължително. След изтичането му минаваш в I2C_Error() да кажем и там отработваш грешката

Автор:  Реконструктор [ Сря Мар 07, 2007 5:00 am ]
Заглавие: 

Това преди всяка операция с паметта ли трябва да се прави?

Автор:  Nikola Kirov [ Сря Мар 07, 2007 12:15 pm ]
Заглавие: 

Не разбира се. В началото при инициализацията на хардуера и след това само ако се получи грешка при комуникацията в функцията която обработва грешката.

Автор:  Реконструктор [ Сря Мар 07, 2007 2:08 pm ]
Заглавие: 

Май го подкарах! :D :D За сега бачка стабилно. Оставям го така, няма да пипам нищо, няма дори да дишам. :-#
Благодаря за полезните съвети. :D

Автор:  valioman [ Сря Мар 07, 2007 2:42 pm ]
Заглавие: 

Реконструктор написа:
Май го подкарах! :D :D За сега бачка стабилно. Оставям го така, няма да пипам нищо, няма дори да дишам. :-#
Благодаря за полезните съвети. :D



А ще споделиш как аджеба го подкара и какъв се оказа проблема....?

Автор:  Реконструктор [ Пет Мар 09, 2007 9:01 pm ]
Заглавие: 

valioman написа:
А ще споделиш как аджеба го подкара и какъв се оказа проблема....?


Доста комплексен. :) Добавих кода за разклащане на шината при инициализация. Самия компилатор (KEIL) не се справя добре с много ситуации. Избягвайте безтипови указатели с кастване към тип след това, например:

Код:
void Send(void* pBuff, int nLen)
{
int i;
char* pData = (char*)pBuff;

while (nLen--)
  SendByte(*pData++);
}


В много случаи омазва локалните променливи. Те са на практика статични такива, когато ф-ята не е декларирана като reentrant, а когато е декларирана, то си прави някакъв софтуерен стек, щото хардуерния не е достатъчен. В първия случай има проблеми, във втория софтуера ми изобщо спря да работи. :?

Автор:  ДедоБоре [ Пет Мар 09, 2007 10:51 pm ]
Заглавие: 

8051 е една от най-куците архитектури, които съм виждал (след PIC)
може би компилатора не е съвсем виновен (на крив космос всички ракети са му криви), ама и ти недей да правиш такива неща.
това е по-скоро за истински процесори, а не за демо версийте [-(

Автор:  Реконструктор [ Пон Мар 12, 2007 11:41 am ]
Заглавие: 

ДедоБоре написа:
8051 е една от най-куците архитектури, които съм виждал (след PIC)
може би компилатора не е съвсем виновен (на крив космос всички ракети са му криви), ама и ти недей да правиш такива неща.
това е по-скоро за истински процесори, а не за демо версийте [-(


Абе във времето, когато 256 байта са стигали за всичко (c), и програмистките техники не са били толкова рафинирани и абстрактни, може да е бил достатъчен като архитектура, ма днеска определено не е.

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/