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

STM8L152, LCD, halt mode...

Поскольку до конца картина не утряслась, объясняю сумбурно (за что прошу извинения).

 

Итак, устройство ради минимального потребления все время в active halt, просыпаясь, обновляет значения на индикаторе и вновь засыпает. Все обновляло, пока реально в halt не вгонял, а с halt - перестало. Как я понимаю, содержимое регистров LCD в состоянии halt вообще не желает переписываться в регистры драйверов (регистры обновляю, а на экране стоит как вкопанное), так что полез глубже, переписывая саму работу с LCD. И стали открываться совсем уже мрачные чудеса:

 

1. Несмотря на то, что в даташите написано, что прерывания LCD из halt не поднимают, по крайней мере из active halt все же работает. Это радует. Но ! Просто тупо раскрыл прерывания для только LCD, в обработчике дергаю ногой, в основном цикле просто halt и цикл. Работает. Секунды две-три-пять. Потом встает (прерываний нет, нога не дергается). Ладно - вычитал, что подъем из halt может некорректно работать при тактовой больше 8 MHz +5% (а у меня, между прочим, изначально делитель на два, т.е. тактовая как раз 8 и не больше). Стал ставить /4 перед halt, меняя его на /2 после - вроде зависать перестало, прерывания идут не срываясь. Хотя явное несоответствие даже errata уже напрягает...

 

2. Прерывания-то идут, только не одиночно, а пачкой (12 шт) - выходит из halt и тут же опять, основной цикл (в котором тоже ножкой помахиваю) до этой ножки не доходит, 12 прерываний в течении ~60 us (вероятно, чуть меньше 2/32768). Естественно, в обработчике бит SOF я сбрасываю (установкой SOFC). Вот только и это (сброс SOF) работает более чем странно - если выставить SOFC и реально попробовать дождаться деактивации SOF в самом обработчике, сброс не происходит вообще, из цикла проверки никогда не выходит ! А вот если обработчик копирует состояние SOF на ногу и выходит - все ж сбрасывается (но через те самые 60 us).

 

Потихоньку занимаюсь шаманством (и, надеюсь, что-нибудь все ж придумаю), но гложет вопрос - наверняка ведь на эти грабли кто-то и раньше наступал, как их правильно обходят ? Т.е. как правильно выполнить обновление показаний на LCD и при этом оставаясь в максимально экономичном состоянии ?

 

 

upd:

 

Все чудесатее и чудесатее ! Оказывается, в обработчике прерывания LCD я не могу не только сбросить SOF, но даже и обнулить SOFIE !!! т.е. я его перевожу в 0 - а все равно десяток с лишним прерываний происходит с одного SOF. Решил зациклить проверку SOFIE после сброса (т.е. циклюсь, пока после сброса SOFIE в "0" он реально не станет нулем) - и все, так в этом цикле в обработчике прерывания и остаюсь ! И как прикажете сделать однократный вызов обработчика SOF ? Сейчас попробую - если заполнение LCD_RAMx займет те же 60 или больше us, возможно, что и проблемы не будет. Но все равно коряво до ужаса... Более корявого ядра я пока вообще не встречал, идиотизм на идиотизме плюс компилятор неземной кривизны...

 

upd2:

 

Как я понимаю, SOF и SOFIE реально сбрасываются только (и сразу) после выхода из обработчика прерываний, но при этом должно пройти не менее 60 us (иначе все равно будет повторный вызов обработчика). Когда основная программа получила управления, эти биты уже заведомо сброшены.

 

Если в обработчике прерываний что-то делать в течении 60 us, и сбросить SOF перед выходом(!), повторного входа в обработчик уже не будет. Но в LCD_RAMx в эти 60 us писать бесполезно - на экране ничего не изменится (!!!). Реальное изменение произойдет только если (в обработчике) что-то делать 60 us, а потом записать в LCD_RAMx. Мда, квест тот еще...

 

Еще забавно - в момент вызова обработчика прерывания LCD не только содержимое LCD_CR3 не хочет корректироваться, но даже и содержимое LCD_RAMx. Т.е. если что-то в LCD_RAMx там (в обработчике) записать, и потом вычитать - вычитается вовсе не то, что записано только что. А вычитается состояние, попавшее в этот регистр тогда, когда это можно было сделать (и что вызывает изменения на экране), т.е. после 60 us от появления SOF !!! Хм... Может, в каких-нибудь ANxxx описано ? В эрратах нет...

Изменено пользователем rx3apf

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


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

Под три сотни просмотров, и ни одного ответа... То ли вообще никто не пользуется STM8 с LCD, то ли никто не использует halt и не заморачивается микропотребением.

 

Ладно - вторая часть Марлезонского балета...

 

 

Итак, с LCD вроде разобрался, работает. Отдал образцы. Образцы возвращаются - погас экран. Разбираюсь - все работает, кроме экрана (и жрет, соответственно, на 3.5 uA меньше - LCD явно выключился). Сервисный интерфейс работает. Отлично, добавляю контрольный вывод LCD_CRx по запросу. Где-то через сутки получаю погасший экран и, предвкушая, лезу смотреть. Ага - LCD_CR3 обнулился, экран, соответственно, погас. Только вот незадача - у меня-то в коде нигде нет ни прямо ни косвенно записи в этот регистр кроме первоначального включения и явного управления битами прерываний. Делаю трассировку, чтобы узнать последовательность событий до "неисправности". Нормальная последовательность:

 

1. событие индикации (1 раз в две секунды)

2. Подготовил новые данные для индикации

3. Раскрыл прерывания SOF

4. Ушел в halt

5. Вышел из halt (обработав прерывание SOF), увидел, что новый интервал не завершен, ушел на пункт 4

6. Вышел из halt, увидел, что завершен новый интервал - это п.1

 

Когда же исказился LCD_CR3, видим - в п.1...4 регистр цел, пункта 5 нет (прерывание SOF не выполнялось), в пункте 6 регистр уже искажен !

 

Никакие другие обработчики не работают, никто никуда больше лезть не может. До входа в halt у меня тактовая снижена до 2 MHz (поскольку уже нарвался, что при даже 8 MHz выход из halt может произойти с непредсказуемыми последствиями). Поскольку команда mov CLK_CKDIVR,#3 непосредственно предшествовала halt, предположил было, что влияет конвеер, но шесть штук nop между картину не изменили.

 

Я в полнейшем недоумении ! Вероятнее всего, не просто нарушается содержимое регистра (причем не обязательно LCDEN сбрасывается, младшие биты тоже могут произвольно измениться), а несанкционированно выполняется какой-то неизвестный кусок кода (может быть даже из родного загрузчика). Отследить-то искажение я могу, и могу восстановить, но нет ни малейшей гарантии, что не будут еще запорчены какие-нибудь важные области (к тому же, по мере "перемещения" кода из-за вставок, теперь LCDEN обычно не обнуляется, зато искажаются младшие биты и уже пару раз заблокировался и сервисный интерфейс.

 

Пока для пробы еще снизил тактовую на входе в halt и добавил пропечатку регистров периферии по запросу, буду ждать результата.

 

Событие происходит достаточно редко (от единиц до десятков тысяч циклов индикации), придется, наверное, делать отдельный тест в ускоренном режиме. Но что с этими результатами потом делать ?

 

И что вообще тут можно сделать ? Если это проблемы пробуждения flash, то даже вынос куска с halt в RAM ничем не поможет, поскольку пробуждение должно происходить по прерыванию с вызовом обработчика, а вектор все равно по-любому из флешака берется. Ненавижу STM8 !

Изменено пользователем rx3apf

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


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

Пардон, может не заметил, а какой компилятор для разработки-отладки используете ?

Какой вариант кода дает "крендель", debug/release ?

Для начала отлова демона проверьте что процессор не выполняет "дикий" код (в нужных местах алгоритма

проставить ногодрыг, который мониторится осцилографом напредмет регулярности. Если появляется нерегулярная картина -

это "влет" в выполнение чего-попало или нештатные рестарт).

Ну, и т д . . .

 

ps

То что написано выше исходя из некоей гипотезы, что сбой в Вашей системе присутствует постоянно,

но его видимое (Вами) проявление - как Вы указываете, редко.

 

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

режима, в том числе errata. Я имел честь работать с MSP430, по которым у меня исключительно положительные впечатления.

В 430 в тактовой системе есть контроль работоспособности системы тактирования, флаги ошибок, которые надо анализировать при инициализации

и просыпаниях. Выход напряжение ядра - тоже.

 

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


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

Родной .asm, терминал, никаких дополнительных "сущностей". Выполнение "дикого кода" отследить нельзя, поскольку есть вход в halt, есть выход их halt и между ними ничего.

 

Но, похоже, причина все ж не та, что я предположил. Тоже, конечно, "интересная", но тут больше я сам виноват. Уточню и "доложусь".

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


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

Итак, ловушка сработала очередной раз и появилась окончательная ясность:

 

1 и 2 из первого письма - следствие моей невнимательности. В RM0031 это документировано, но не в разделе LCD (как я бы ожидал), а в описании режима halt. При выходе из halt происходит (всегда) переключение тактирования модуля LCD на системный тактовый генератор, и занимает это те самые мной измеренные ~2/32768.

 

Трактованное как некорректный выход из halt (зависание без признаков жизни на тесте) - это следствие искажения LCD_CR3 (прерывания SOF запрещаются и все встает).

 

Самое-то интересное вот в чем - обработчик прерывания SOF у меня завершается такой конструкцией:

 

LCDint1:

bset LCD_CR3,#3 ; сброс SOF

btjt LCD_CR3,#4,LCDint1 ; ожидаем сброс SOF

bres LCD_CR3,#5 ; дальнейшие прерывания LCD SOF запрещаются

 

Т.е. жду (окончания тех самых 2/32768), когда сбросится SOF, чтобы переписать сегментные регистры (раньше этого делать нельзя), все время пытаясь сбрасывать SOF. А в RM0031 написано, что до истечении интервала синхронизации писать в регистры LCD нельзя. И, оказывается, писать нельзя не потому, что не получится записать (что я и наблюдал изначально), а результат операции вообще непредсказуем - устанавливаю третий бит, а произвольно сбрасываются как минимум 0..2 и 6 ! Т.е искажение LCD_CR3 результат ошибки синхронизации, а не выполнения постороннего кода (трассировку сделал неудачно, не увидел последнего вызова обработчика прерывания, отсюда и неправильный вывод).

 

По мере снижения тактовой вероятность такой ситуации уменьшается, а когда уменьшил до 1 MHz, перетасовка сегментов обеспечила необходимую задержку до синхронизации, и проблема решилась полностью.

 

Таким образом, при работе с LCD с переходом в halt необходимо соблюдать осторожность при записи в регистры LCD (в первую очередь в обработчике прерывания LCD). Какого-то отдельного флага синхронизации нет, поэтому интервал не менее 2/32768 надо отсчитать любым иным способом (таймером или растактовкой кода).

 

 

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


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

Какого-то отдельного флага синхронизации нет, . . .
Кьюуууу . . . .

Хорошо что не из "Errata, future releases".

 

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


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

LCD на stm8 запускал лет 6 назад, все работало, никаких танцев с бубном, все сразу работало. Такое ощущение что у Вас то ли выход за границы массивов, и соответственно трется регистр, то ли что-то с сбросом. В общем имхо баг какой-то. Информации для анализа недостаточно.

ЗЫ halt не использовал, поэтому видимо проблем не возникало

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


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

Так без halt никаких проблем и не было. Подозреваю, что если бы я не использовал быстрый старт (не дожидаясь стабилизации intref), то тоже даже не узнал бы, что такое бывает. Ситуация очень похожа на проблемы AVR TMR2 в асинхронном режиме при RC-тактировании, но там, правда, есть возможность поллить флаг.

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


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

Так без halt никаких проблем и не было. Подозреваю, что если бы я не использовал быстрый старт (не дожидаясь стабилизации intref), то тоже даже не узнал бы, что такое бывает. Ситуация очень похожа на проблемы AVR TMR2 в асинхронном режиме при RC-тактировании, но там, правда, есть возможность поллить флаг.

там с halt вообще все не просто, разница в <2мкА, а вот время просыпания больше, так как это по сути сброс, время инициализации тоже приличное, в итоге если просыпаться достаточно часто, lpwait может оказаться не хуже.

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


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

lpwait - это что и где ? А, намек понял - ну, как очень крайний вариант да, но по потреблению уже практически на грани. У меня сценарий - один раз в две секунды просыпаться, обновлять показания (из-за этого, обновления LCD, "сдвоенный" halt с паузой на максимум интервал кадра). И очень лимитированное потребление - сейчас чуть больше 5 uA при включенном экране (если выключить экран, то вообще полтора).

Изменено пользователем rx3apf

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


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

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

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

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

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

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

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

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

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

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