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

MSP430FR4133 LPM

Очень редкие проекты у меня на MSP. А с режимами сна вообще дел не имел.

Немного повозился - понял, что там вообще свой подход к написанию проектов нужен. А он у меня не выработан. ((

Короче проект маленький. ОС не нужна не разу. Потребление - основное.

Периферии много задействовано. 3 ноги (прерывания), RTC, LCD, 2 таймера, ADC, USART и I2C. На постоянку только ноги, LCD и RTC. То есть LPM3.5.

Остальная периферия запускается разово. По даташиту на МК нашёл табл. 6-1 "Operating Modes (continued)", где указано что I2C и UART работают только в LPM0 (собственно эти узлы тактируются только SMCLK).

Остальная периферия может спать в LPM3.

Я сейчас в ячейке храню битовый список запущенных узлов. Чтобы знать в какой именно режим сна я имею возможность войти. Но у мне не совсем понятно с выходом из сна.

Приведу пример.

Я работаю с усартом. То есть нахожусь в LPM0. Тут приходит прерывание от ножки (геркон) я просыпаюсь выполняю работу запускаю таймер для задержки на дребезг и надо выйти в голову. То есть выйти из LPM0.

Но если я не работаю с UART, то мне надо выходить из прерывания по LPM3.

И я что-то недогоняю. Достаточно ли мне сделать __bic_SR_register_on_exit(LPM3_bits) и это решит проблему в обоих случаях. Или мне требуется анализировать из какого режима я попал в прерывание?

 

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


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

Вы хоть сами поняли, что у Вас происходит? Если Вы в LPM0, при чём здесь LPM3? Просто вышли по LPM3 и ничего не произошло.

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


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

Извиняюсь за бестактный вопрос.

У Вас есть работающий пример с LPM ?

msp430x54xA_LPM3_1.c Enters LPM3 (ACLK = LFXT1)

msp430x54xA_LPM3_2.c Enters LPM3 (ACLK = VLO)

msp430x54xA_LPM4.c Enters LPM4; LFXT1, REF0 disabled, SVS disabled

slac166m.zip - это для семейства F543xA.

 

 

PS - Вы не указали тип процессора.

Вот пример "украденный" из исходников FreeRTOS, serial.c

 

    /*
     * UART Tx interrupt service routine.
     */
    #pragma vector=UART1TX_VECTOR
    __interrupt void vTxISR( void )
    {
    signed char cChar;
    portBASE_TYPE xTaskWoken = pdFALSE;
    
        /* The previous character has been transmitted.  See if there are any
        further characters waiting transmission. */
    
        if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xTaskWoken ) == pdTRUE )
        {
            /* There was another character queued - transmit it now. */
            U1TXBUF = cChar;
        }
        else
        {
            /* There were no other characters to transmit. */
            sTHREEmpty = pdTRUE;
        }

        /* Make sure any low power mode bits are clear before leaving the ISR. */
        __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
    }
    /*-----------------------------------------------------------*/

 

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

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


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

Прошу прощения. Просто сформулировать грамотно не могу.

Написал проект. В отладчике он работает. Если режимы сна отрубить - тоже. В готовом изделии - не хочет.

Особенность проекта (хотя я просто наверняка неправильно изначально его спроектировал) в том, что надо менять режимы сна.

Например. Спим в LPM3.5. Приходит прерывание от RTC, обрабатывается и, например раз в сутки надо замерить текущую температуру.

Для этого надо выйти из прерывания со сбросом режима сна подать питание на датчик температуры, зарядить таймаут на таймер 0 и заснуть уже в режиме LPM3.

Потому что если я засну в режиме 3.5, то таймер идёт лесом. Теоретически может одновременно придти несколько прерываний. В которых потребуется разная периферия и, соответственно, мне надо заснуть в таком режиме чтобы вся эта периферия работала.

Как выглядит типовой проект в таком случае? Я сейчас просто выделил байт в BACKMEM где храню флаги рабочей на данный момент периферии. И при засыпании анализирую этот байт.

Но похоже - что-то не так.

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


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

Прошу прощения. Просто сформулировать грамотно не могу.

Написал проект. В отладчике он работает. Если режимы сна отрубить - тоже. В готовом изделии - не хочет.

....

 

Не понятно "в готовом изделии".

В отладчике в смысле debug (то что компилируется в файл mmm.d43) ?

или симулятор.

 

Например нечто такое:

 

main.c

-----

main()

{

InitAll();

. . . .

while(1)

{

GetPeriferialAll(); // загрузить состояние периферии

mode = AnalizeAll(); // проанализировать все переменные-флаги-порты итд

Run( mode ); // выполнить действия в зависимости от режима

if( mode == 1 ) Go_LPM2();

else

if( mode == 2 ) Go_LPM3();

else

. . . . . . .

 

}

}

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


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

Не понятно "в готовом изделии".

Я отлаживаю с MSP-FET по моему. Короче JTAG отладчик.

Вот всё работатет. Отключаю этот отладчик, передёргиваю питание, и эта же прога работает не так. Причём произвольно не так. Может запустится - всё Ок. Может после прихода прерывания всё выровняться.

Я всё пересмотрел уже 10 раз. Весь мозг сломал. Ничего найти не могу.

Например нечто такое:

Вот именно так я и делаю.

Я вот вижу, что нет атомарности при этом выборе. Например я проанализировал что у меня режим 3.5, и только в сон входить, а тут бах прерывание, из прерывания вышел, по факту уже режим изменился, но я это не анализирую и в сон ухожу.

:(

Проанализировал. Получается, что, по видимому, менять режим сна надо именно в прерывании. Если это сделать в голове, то есть шанс войти не в тот режим сна.

То есть получается в голове совсем проги не должно быть. Как у них в примерах.

Вечером осмыслю - попробую.

PS: Вообще, похоже, один режим сна должен быть. Иначе очень сложно разрулить.

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


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

Я отлаживаю с MSP-FET по моему. Короче JTAG отладчик.

В серийном изделии JTAG отладчика НЕТ. И отлаживать надо по BSL

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


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

Например. Спим в LPM3.5. Приходит прерывание от RTC, обрабатывается и, например раз в сутки надо замерить текущую температуру.

Для этого надо выйти из прерывания со сбросом режима сна подать питание на датчик температуры, зарядить таймаут на таймер 0 и заснуть уже в режиме LPM3.

Если у Вас МК вошёл в ISR, то естественно он уже не режиме сна, а в run-mode находится. Как это может быть непонятно??

Как всегда - у вопрошающего каша в голове...

И по выходу из ISR, можно вернуться в сон или продолжить выполнение фонового процесса с инструкции, следующей после той инструкции, что погрузила в сон.

Т.е. - именно инструкция выхода из прерывания, загружает значение в статусный регистр МК, содержащий биты сна.

Атомарный вход в сон:

    __bic_SR_register(GIE);
    if (!(mainFL & (1 << MAIN_F_TASK_MEASURE | 1 << MAIN_F_TASK_RX)))
      if (keyboard == KBD_NONE) {
      mainFL |= 1 << MAIN_F_SLEEP;
      __bis_SR_register(LPM3 | GIE);
      __bic_SR_register(GIE);
    }
    mainFL &= ~(1 << MAIN_F_SLEEP);
    __bis_SR_register(GIE);

В mainFL содержатся флаги-требования обработки некоторых событий (MAIN_F_TASK_RX, MAIN_F_TASK_MEASURE). Эти флаги выставляются в ISR-ах (которые могут срабатывать в режимах сна, пробуждая МК, или в run-mode, если уже идёт какая-то обработка одного из событий).

После этого участка идёт код проверяющий эти флаги и обслуживающий их.

Есть также флаг MAIN_F_SLEEP - по нему ISR-ы определяют из какого режима они вызвались (если им это нужно).

 

То есть получается в голове совсем проги не должно быть. Как у них в примерах.

Неправильно. Основную обработку лучше располагать в фоновом процессе.

Активация фонового процесса: срабатывает ISR, выставляет флаг в переменной запросов сервисов фонового процесса, выходит из ISR в run-mode.

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

Если переменная запросов ==0 - вход в сон.

Весь цикл:

enum {MAIN_F_SLEEP, MAIN_F_TASK_MEASURE, MAIN_F_TASK_RX, ...};

while (1) {
  __bic_SR_register(GIE);
  if (!(mainFL & (1 << MAIN_F_TASK_MEASURE | 1 << MAIN_F_TASK_RX | ...))) {
    mainFL |= 1 << MAIN_F_SLEEP;
    __bis_SR_register(LPM3 | GIE);
    __bic_SR_register(GIE);
  }
  mainFL &= ~(1 << MAIN_F_SLEEP);
  __bis_SR_register(GIE);
  do {
    if (mainFL & 1 << MAIN_F_TASK_MEASURE) {
      __bic_SR_register(GIE);
      mainFL &= ~(1 << MAIN_F_TASK_MEASURE);
      __bis_SR_register(GIE);
      ... //сервис MAIN_F_TASK_MEASURE
    }
    if (mainFL & 1 << MAIN_F_TASK_RX) {
      __bic_SR_register(GIE);
      mainFL &= ~(1 << MAIN_F_TASK_RX);
      __bis_SR_register(GIE);
      ... //сервис MAIN_F_TASK_RX
    }
    ... //другие сервисы
  } while (mainFL & (1 << MAIN_F_TASK_MEASURE | 1 << MAIN_F_TASK_RX | ...));
}

В принципе, возможно запреты прерываний при модификации флагов mainFL возможно излишни, так как IAR эти операции генерит в виде одной инструкции чтения-модификации-записи (которая атомарна, как я понимаю, для контроллера прерываний).

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


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

Прошу прощения. Писал ответ, но почему то не вижу его ...

Если у Вас МК вошёл в ISR, то естественно он уже не режиме сна, а в run-mode находится. Как это может быть непонятно??

Как всегда - у вопрошающего каша в голове...

У меня нет каши в голове. Возможно не верно выразился.

За пример - спасибо. В принципе так и делаю. Правда чёто переклинило, прерывания не запрещал на момент разбора. Это исправил.

Неправильно. Основную обработку лучше располагать в фоновом процессе.

Активация фонового процесса: срабатывает ISR, выставляет флаг в переменной запросов сервисов фонового процесса, выходит из ISR в run-mode.

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

Если переменная запросов ==0 - вход в сон.

...

В принципе, возможно запреты прерываний при модификации флагов mainFL возможно излишни, так как IAR эти операции генерит в виде одной инструкции чтения-модификации-записи (которая атомарна, как я понимаю, для контроллера прерываний).

В принципе всё так и было сделано...

...

Это халтурка, в общем-то. Плата сделана очень плохо. Плюс куча хомутов. А работаю вечером, когда уже устал.

...

На выходных сделал отладочный вывод. Выяснилось 2 проблемы. Первая - основная. Я разместил регистр флагов (там где формируется цепочка событий, которые потом в фоне обрабатываются), в неиспользуемом регистре LCDE LCDMхх. Он у меня не задействован был (ноги так разведены). Так вот эта память разрушалась почему-то. Причём в режиме, когда я подключён к MSP-FET всё нормально, когда стартую готовое изделие, что-то искажается. Память LCDBMхх при этом, абсолютно цела. Там хранятся некоторые данные, я их проверяю - всё достоверно. Как только вынес переменную флагов (у меня статус) в память BACKUP, то всё заработало. Интересно, что 2 изделия работало по-разному. Но в целом неправильно. Сейчас сделал отладку на индикатор и вылизал всё.

Всем спасибо, особенно jcxz.

===

Есть ещё вопрос, если несложно, отзовитесь, кто работал.

По LCDE контроллеру. Есть фича со стабилизацией контрастности. При этом сразу указываешь напряжение. Я так понимаю в таком режиме он потребляет больше? Хотелось бы услышать рекомендации от тех кто проводил эксперименты.

Да ещё один момент. Не вижу пока заявленного потребления в режиме LPM3.5. То что прибор находится в нём - гарантирую. Пока потребление даже больше чем на старом контролере MSP430f415. Он в LPM3 он в LPM3 работал. Индикатор тот же. Правда пока не подтверждённые данные. Тестером мерил .. ))

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


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

Да ещё один момент. Не вижу пока заявленного потребления в режиме LPM3.5. То что прибор находится в нём - гарантирую. Пока потребление даже больше чем на старом контролере MSP430f415. Он в LPM3 он в LPM3 работал. Индикатор тот же. Правда пока не подтверждённые данные. Тестером мерил .. ))

Я работал с немного другим МК (MSP430FR5739) тоже LPM3 (или LPM3.5 не помню точно). С потреблением всё ок - соответствует написанному.

Возможно Вы что-то забыли отключить внутри МК (какую-то периферию). Или утечка через какой-то GPIO. Отладчик надеюсь отключаете когда меряете потребление?

Сейчас сплю с XT1 ==32768, но и раньше с VLO было всё нормально.

Пока сплю, из периферии работает только один таймер от ACLK (ну и возможны прерывания от GPIO). ACLK тактируется XT1 с прескалером ==4.

Потребление - единицы мкА. А у Вас сколько?

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


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

Если у Вас программа работает с регулярным циклом,

то пожирателя энергии будет проще найти, если промониторить потребление тока за цикл.

Осцилограф синхнонизируете по началу цикла (дрыганог), сигнал берете с шунт-резистора (10-30 Ом),

включенного в минусовую цепь питания прибора.

Батарея(+) --- (+) прибора

Батарея(-) --- <резистор 10 Ом> ---- <A> ----- (+) прибора

 

GND осцилографа включена на минус батареи.

Сигнальный вход - на точку <A>.

 

 

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


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

Прошу прощения, за нерегулярность постов. 2 дня отсидел в командировке.

Ещё раз подтверждаю, что данные разрушаются в LCDM.. Причину не понимаю. Все косяки, которые я нашёл, чётко описаны в даташите. Короче не устраняют, а описывают. )) Ну хотя бы так.

По LCDE контроллеру перерыл всё не нашёл ничего подозрительного. Единственное, что нашёл, это многократное упоминание про "The LCD memory registers can also be accessed as word".

У меня там флаги были, но на uint16_t, то есть в моём понимании, я ничего не нарушил. Я попробую просмотреть листинг, может ли при этом компилятор побайтно обращаться в конструкции типа status.bit.

На текущий момент всё прекрасно работает. Вчера все тайминги вылизал и правильность включения/ отключения периферии.

===

2 jcxz, из не выключенной периферии может быть только что-то включенное по умолчанию. За используемой я слежу. Удобно, когда питание узлов МК где-то отдельно включается. Как, например, в ARM. ))

А здесь как-то всё разбросано по кристаллу. Закончу функционал, приступлю к вылизыванию по потреблению.

У меня по умолчанию (если не трогать ничего) работает только 32768, RTC, LCD и по 3 ногам прерывания. Прерывание по RTC - раз в минуту. Так что замерить можно на прямую. Сижу в LPM3.5. По даташиту должно быть порядка 2 мкА. Старый прибор был на f415. Жрал 7-12 мкА. На новом я вижу значение 14. Пока измерено тестером, так что за достоверность данных не ручаюсь. В ближайшее время измерю выложу достоверные данные.

2 k155la3. Спасибо опробую и Вашу методику. Хотя, понятно, что она оценочная. Осцилограф неточный прибор по напряжению

 

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


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

2 jcxz, из не выключенной периферии может быть только что-то включенное по умолчанию. За используемой я слежу. Удобно, когда питание узлов МК где-то отдельно включается. Как, например, в ARM. ))

А здесь как-то всё разбросано по кристаллу. Закончу функционал, приступлю к вылизыванию по потреблению.

У ARM нет включения/выключения - эти функции не включены в ядро. А у Cortex-ов разных производителей, не питание узлов обычно включается, а тактирование.

А здесь (в MSP430) удобнее сделано управление тактированием. Не нужно следить какой источник тактирует какой узел, не нужно составлять бит-карту подключенных к данному источнику тактирования периферийных узлов и отключать его при обнулении карты. Здесь всё это делается аппаратно - каждый источник тактирования сам отслеживает какие есть в данный момент активные запросы тактирования от каких периферийных узлов и, если таковых нет, сам отключается. И сам включается если появляется запрос тактирования от какой-то периферии. Достаточно только изначально проинитить все источники тактирования, которые где-либо будут использоваться, а в конфигурации каждой периферии правильно прописать какой источник тактирования использовать.

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


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

В серийном изделии JTAG отладчика НЕТ. И отлаживать надо по BSL

Проясните пожалуйста. У меня отладчик MSP-FET USB-IF. Родной. В закладке я вижу, что есть и JTAG и SBW. Причём выбор автоматический. На плате у меня заведены сигналы JTAG 4 шт + Reset + test.

1) Что у меня ухудшится в плане отладки, если я заведу только SBW.

2) Я так понял, что для SBW мне нужны следующие ноги: Rst, Test, Usart Tx, Usart Rx? Непонятно нужны ли ещё ноги.

3) Какой прогой я смогу прошить контроллер и залочить его. MspFet мой кристалл не поддерживает.

4) Что делать в проекте с ногами JTAG, чтобы максимально защитить от взлома.

 

Прошлую прошивку считали китайцы. И поставляют на завод подделки. Причём открыто. Не могу утверждать что она была защищена должным образом. В этот раз попробуем защитится на всех уровнях. От китайцев поддержки никакой. Поэтому опять обратились к нам.

С уважением.

PS: Честно говоря, пока не понимаю. Раньше была прога MspFet. Мы ей пользовались. Сейчас абсолютно непонятно чем можно воспользоваться на замену.

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


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

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

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

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

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

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

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

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

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

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