LINUX.ORG.RU

MSP430 и timestamps

 ,


1

1

История такова, допиливаю прошивку под MSP430FR6043/FR6047 и подобные.

Исходный код можно посмотреть тут: http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/USSSWLib/USSSWLi...

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

В других embedded устройствах, я встречал использование timestamp-ов, примерно в таком виде:

timestamp = get_timestamp();

...

elapsed_time = calc_elapsed_time(timestamp);

В этой прошивке я такого функционала не нашел. TI говорят, что реализовывать не собираются.

Самое близкое, что есть — rtc_b и timer_b. Но там точность до секунды, вроде как.

Можно генерировать low power mode delay с точностью до миллисекунды функцией USS_generateLPMDelay(), но там происходит что-то, что я не совсем понимаю.

Надежды мало, но возможно кто-то сталкивался с подобной проблемой под MPS430FR..., укажите куда копать.

Или сразу в Job?

★★★

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

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

UPD. Или по коммуникационному порту (какие там есть?) передавать метки и измерять период.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)

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

DuMOHsmol
()
Ответ на: комментарий от DuMOHsmol

Вообще, их там шесть штук 16-разрядных. Вот только вопрос, с какой частотой они могут тикать и надо учитывать, что это тоже занимает время, а тикать они будут часто, поэтому надо будет еще вычитать из натиканного, сколько они сами там сами времени отъели.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

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

Да, это вариант. Но хотелось бы избежать, так как здравый смысл подсказывает, что это как-то можно реализовать програмно. Ведь задержка (LPMDelay) же выставляется! Или не подсказывает?

Вообще, это счетчик газа/воды. С большой точностью я получаю скорость потока в трубе, но чтобы получить объем, мне необходимо эту скорость умножить на время между измерениями.

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

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

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

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Вопрос в том, что измерения не занимают одинаковое время. И иногда производится калибровка, которая занимает дополнительное время.

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

Ну если у тебя калибровка запланирована прошивкой, то в это время не считать объем. Вроде как я не вижу проблем-то. Проводи в моменты калибровки измерения не каждый запланированный период, если это невозможно, а через столько периодов, пока калибровка не закончится. Проблем-то? Просто времени будет в три-четыре раза больше, но оно будет точным.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Тут мы не совсем друг друга поняли, но не важно.

Спасибо за наводку по 6.13.11 и 6.13.12.

Судя по всему, это всё реализуется средствами timer_a.c. Но нигде в коде прошивки эти библиотеки больше не используются, что немного смущает.

Пойду копать.

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

Нет, почему, не поняли. Сначала ты просто спросил, как измерить время между произвольными местами в коде, а потом оказалось, что тебе просто надо скорость на время умножить.

У таймеров выбираешь источник. Например, генератор, ты знаешь его частоту, потом этот генератор наверняка идет через какие-то делители (ты знаешь, на что делит и можешь, наверное, даже выбрать коэффициент деления), а дальше это все в таймер, а он считает. И таймер умеет генерировать прерывание. Ты тупо сидишь и в своей программе считаешь эти прерывания. предположим, ты получаешь прерывания точно с периодом 0.5 мс. Ну и считаешь, скажем, 1000 прерываний. На тысячное прерывание делаешь измерение. Между двумя измерениями точно 0.5 секунд с субмиллисекундной точностью.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от tyakos

На тысячное прерывание делаешь измерение

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

А по поводу калибровки я не знаю, кто у тебя калибровку проводит? Если датчик сам там калибруется, то у него, наверное, есть какой-то флаг «Я калибруюсь. Занят». тогда просто ждешь, пока калибровка не завершится и флаг не сбросится. Если же это ты калибруешь, то и делай эту калибровку, когда тебе удобно, а по ее окончании, запускай таймеры. И останавливай измерения и таймеры, когда снова надо калибровать.

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

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)

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

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

Если промежутки короткие (меньше периода переполнения таймера), то можно обойтись без прерывания. Просто запускаешь таймер тикать раз в миллисекунду, и в нужные моменты считываешь значение счётчика таймера.

Beewek ★★
()
Ответ на: комментарий от Zubok

https://imgur.com/a/m4LA3pT

Как-то так, прошу прощения за paint. Хочу мерять время от конца красного интервала до конца следующего красного интервала.

Вроде бы всё понятно, мне ещё раз разжевали выше. Только не ясно, будет ли всё это работать в low power mode (режим сна) или надо будет считать кусками.

tyakos ★★★
() автор топика
Последнее исправление: tyakos (всего исправлений: 1)
Ответ на: комментарий от tyakos

https://imgur.com/a/m4LA3pT

Картинка и так была понятна со слов и она ничего не объясняет.

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

2. Как долго длится измерение (красный)? Как долго длится калибровка (зеленый)?

3. Время измерения детерминировано? Что об этом сопроводительный текст к программе говорит. потому что если время измерения плюс-минус километр и этот разброс превышает требуемую точность, то надо другой метод думать.

Zubok ★★★★★
()

На аппаратном таймере можно отсчитывать миллисекунды и считывать в нужном месте кода.

aiqu6Ait ★★★★
()
Ответ на: комментарий от aiqu6Ait

На аппаратном таймере можно отсчитывать миллисекунды и считывать в нужном месте кода.

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

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

1. Калибровка плановая. Без измерения калиброваться нельзя.

2. На картинке написано. Длинна зеленого интервала (измерения) варьируется от 21 до 31 миллисекунд.

В этом же и вопрос. Иначе я бы просто умножал скорость на (n+c) или (n+c+d), где с и d продолжительности измерения и калибровки.

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

2. На картинке написано. Длинна зеленого интервала (измерения) варьируется от 21 до 31 миллисекунд.

21 и 31 или прямо вот может быть и 25, и 30? Если так, то это много, по сравнению, с той точностью, которую надо получить. Тогда программируй аппаратный таймер и просто считывай его значения после каждого измерения и запускай его снова. У тебя какая частота тактового генератора?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

К сожалению, да.

Вот суммарное время измерения. Определено методом, рекомендованным TI (плата подключена по USB к компьютеру, время считает он).

https://imgur.com/a/fKRWyP2

Распределение:

221 - 253ms
45728 - 254ms
314498 - 255ms
505888 - 256ms
89885 - 257ms

Есть 32.768 кГц, работает всегда, вроде как. И один 8 МГц, используется во время измерения.

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

Не совсем я понял, а почему 250+ мс. Ты выше написал, что время 25-30 мс. Десять измерений, что ли проводит? Сорри, я пока не совсем вьезжаю. Мы рассинхронизировались.

Есть 32.768 кГц, работает всегда, вроде как.

Это часовой кварц. Можно и его использовать. Использовать как источник для таймера. Дальше я посмотрел, что идет делитель, коэффициент которого можно выбрать 1/2/4/8. Дальше идет в таймер. Можно поставить делитель на 8 и тогда таймер может считать время от 0 до 16 секунд с точностью 1/4096 секунды. (это примерно 0.244... мс - это один тик таймера). Если делитель поставить меньше, то будет считать точнее. но диапазон меньше. Шкалы без преполнения с огромным запасом хватит на замер между двумя измерениями.

Аналогично можно и 8 МГц использовать. Там тоже делители 1/2/4/8.

UPD. Да, насчет сна. При LP0 вроде бы должен спать и при этом считать.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

Не совсем я понял, а почему 250+ мс. Ты выше написал, что время 25-30 мс.

А, я так понял, что это время между измерениями, а не самого измерения.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Да, всё правильно. Суммарное время между измерениями.

Вот данные, где я выставлял сон в 100мс, т.е. время измерения от 17 до 27мс.

https://imgur.com/a/0jDJZij

Вчера я рисовал по памяти :)

tyakos ★★★
() автор топика
Последнее исправление: tyakos (всего исправлений: 2)
Ответ на: комментарий от tyakos

Чувствую, что разгадка таится в этом файле, после твоих объяснений начинает проясняться, но пока до меня не доходит, что надо сделать, и ничего не сломать.

https://pastebin.com/umCy6qTF

Сон, кстати, генерируется commonTimerGenerateLowPowerDelay() в LPM3.

tyakos ★★★
() автор топика
Последнее исправление: tyakos (всего исправлений: 1)
Ответ на: комментарий от tyakos

Сон, кстати, генерируется commonTimerGenerateLowPowerDelay() в LPM3.

Я глянул бегло. Вроде бы в LPM3 источник частоты ACLK остается активным. Значит, если нужен LPM3, надо использовать линию ACLK как источник. MCLK, SMCLK и DCO отрубаются.

Zubok ★★★★★
()

Извини за офтоп, но как ты их прошиваешь? Я себе сдуру купил как-то на али девборду, промучился с ней и понял, что без дорогущего программатора ничего не сделать. А с покупкой дорогущего программатора теряется весь смысл использования MSP340 — тут уж дешевле и практичней будет STM32 гонять.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Мы ti-евские процы шьём через sauris sau-510 USB jtag emulator

У нас, правда, железо из tms320

(к тс-у отношения не имею, если что)

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 1)
Ответ на: комментарий от tyakos

Вот данные, где я выставлял сон в 100мс, т.е. время измерения от 17 до 27мс.

Я так понимаю, что время ты замеряешь компьютером, поэтому разброс может частично вызван неточностью измерения времени компьютером, а не временем одного измерения. Быть может, что измерения как раз по времени примерно равны. Вообще, если углубиться в доки к этой библиотеке, то там написано, что происходит при измерении:

USS_message_code USS_startUltrasonicMeasurement (...) 	

...

The API will perform the following operations:

   - Verify if USS state is READY
        If USS is not READY state (e.g. OFF or STANDBY) it will set USS to READY state following recommended USS Power Up sequence.
   - Triggers USS Capture
   -  Wait in user selected power mode (USS_capture_power_mode_option) until acquisition sequence is done or any of the following errors occurs:
        Data Error Abort
        ASQ Time Mark 4 time out
   - Verifies that SDHS conversion has not been interrupted

Тут, в общем-то, задержка может быть, если датчик ушел в сон (а он уходит в сон у тебя?). Дальше запускает измерение и ждет (в твоем случае в LPM3), когда преобразование закончится, проверяет ошибки и что сигма-дельта преобразование не было прервано (я так понимаю, что пользователем), и выходит. Тут нельзя, конечно, сказать, детерминировано по времени все преобразование или нет. Датчик может спать, поэтому он пока там проснется... А остальные части не факт, что варьируются по времени. Но документация никак не специфицирует время преобразования, поэтому надо исходить из того, что оно варьируется.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

(а он уходит в сон у тебя?).

Сам спросил - сам ответил. Если используется USS_startLowPowerUltrasonicCapture(), то уходит в сон, да.

 User must call «USS_configureUltrasonicMeasurement» before calling this API and USS trigger must be set to USS_Triger_Configuration_Software_Trigger. To reduce power consumption between captures the device will:

    - Put USS Module in OFF state
    - Turn off USSXTAL
    - Go to Low Power Mode 3 (LPM3) mode and wait for timer to expire to to trigger the next channel input. If there are no more channel captures pending. then this delay is skipped and the API returns control to the application.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Датчик это просто конденсатор, грубо говоря. Сам он не уходит в сон. В сон уходит их интерфейс, видимо.

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

Да. Но другого метода у меня пока нет. Сами TI используют этот метод.

https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/811877/3053428#305...

Их библиотеки с математикой закрыты и открывать они их не собираются. Внутри там преобразование Гильберта и ещё что-то.

Короче, сейчас способа выяснить, детерминировано ли время, нет, кроме как посчитать таймером на плате. То есть, чтобы решить, надо ли решать задачу, её надо сначала решить. Да уж.

tyakos ★★★
() автор топика
Ответ на: комментарий от Zubok

Да, видимо их USS Module уходит в сон и выключает 8MHz осциллятор.

tyakos ★★★
() автор топика
Ответ на: комментарий от Zubok

Ну можно еще прерывания от таймера запустить, по прерываниям проводить измерения. При калибровке таймер гасить. Тогда более-менее равные промежутки будут.

aiqu6Ait ★★★★
()
Ответ на: комментарий от aiqu6Ait

Ну можно еще прерывания от таймера запустить, по прерываниям проводить измерения. При калибровке таймер гасить. Тогда более-менее равные промежутки будут.

А вот это как раз выше по треду и сразу предположилось. Вот тут:

MSP430 и timestamps (комментарий)

Но потом оказалось, что весьма вероятно, что само время измерения имеет разброс 10 мс. При требуемой точности измерения времени 1 мс. Поэтому измерение через равные промежутки теряет смысл. А измерять тогда надо, что ТС и хотел делать с самого начала, фактическое время между измерениями по их получению.

Zubok ★★★★★
()
Ответ на: комментарий от aiqu6Ait

Кстати, а это идея!

Сейчас по окончанию измерения в моргаю LEDом. Сейчас попробую подключиться и попробовать замерить время.

tyakos ★★★
() автор топика
Ответ на: комментарий от tyakos

Короче, сейчас способа выяснить, детерминировано ли время, нет, кроме как посчитать таймером на плате

Ну, да, можно тупо измерять точно время, прошедшее между запросом к USS и получением от него данных (то есть значение промежутка, который оценивается в 17-27 мс). Отдельно пробовать в режиме сна USS и без режима сна. И можно узнать, есть ли разброс. Но если будешь измерять фактическое время между измерениями для вычисления объема, то это знание будет иметь просто вспомогательный характер, что ты в курсе, что там разброс в промежутке 10 мс.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Получается, что придется считать время между измерениями, а не делать измерения через равные промежутки времени.

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

Весь тред не читал и не вникал, если что.

aiqu6Ait ★★★★
()
Ответ на: комментарий от tyakos

Спасибо aiqu6Ait!

Подключил осциллограф. Когда ничего не происходит, общее время или 185, или 187 миллисекунд, т.е. не детерминировано. В нормальном режиме работы, при измерении раз в 2 секунды, с погрешностью в 0.1% ещё как-то можно жить.

Но! При включении экрана (при включенном выводе объема/скорости на экран) время меняется значительно. При подключении по USB всё, опять же, меняется.

Тут уже буду думать. Или отключать всё, что может повлиять на время. Или всё-таки пилить таймер, что в принципе правильно. Осталось только найти, как его запускать на этом чипе.

Спасибо, Zubok, что помог понять, как работают таймеры.

tyakos ★★★
() автор топика
Последнее исправление: tyakos (всего исправлений: 1)
Ответ на: комментарий от tyakos

Осталось только найти, как его запускать на этом чипе.

Эта задача решается очень быстро. Тут писать порядка 10 строк. Нужно найти свободный таймер, который не использует библиотка. Инициализация там простая, прерывания не потребуются, так как у тебя переполнений не будет. Дальше чтение значения после измерения и сброс. Источник счета — ACLK. Инициализация таймеров MSP430 в интернете в любой дыре есть. :) Потом расскажешь.

Zubok ★★★★★
()
Ответ на: комментарий от aiqu6Ait

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

Вот как раз к этому и пришли. Причем даже прерываний не потребуется, скорее всего. Измеряем, ждем ответ, считываем таймер, обуняем, и так по циклу.

Zubok ★★★★★
()
Ответ на: комментарий от tyakos

Для устройств с FET есть http://www.ti.com/tool/MSP-FET#2

$115.00(USD) — это ж трешняк какой-то!

STM32 я прошиваю 50-рублевым преобразователем USB<>UART, STM8 прошиваю 100-рублевым st-link. А тут аж 8тыр почти.. Да это уже совсем не хобби получается... Не стоит оно ради древней 8051 так убиваться.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от tyakos

Только ты там внимательно manual читай. Я сейчас глянул. Самое простое будет, если, например, какой-то Timer B свободен. тогда ты просто его конфигурируешь, запускаешь в Continuous Mode с нуля, после измерения (важно!) ОСТАНАВЛИВАЕШЬ (на этот счет есть note в User Guide [1]), сразу считываешь TBxR (сколько натикал), сбрасываешь и тут же снова запускаешь. Должно получиться, но я умозрительно смотрю, так как вообще ничего не помню и надо все эти даташиты перечитывать, но ты и сам там разберешься.

Ну и затем уже существует вариант с прерыванием. Можно потом уже переписать, если что-то не понравится, на прерывания.

P.S. В этих сериях на таймере даже не один делитель, а два подряд - ID и IDEX.

[1] NOTE: Modifying Timer_B registers TI recommends stopping the timer before modifying its operation (with exception of the interrupt enable, interrupt flag, and TBCLR) to avoid errant operating conditions.

When the timer clock is asynchronous to the CPU clock, any read from TBxR should occur while the timer is not operating or the results may be unpredictable. Alternatively, the timer may be read multiple times while operating, and a majority vote taken in software to determine the correct reading. Any write to TBxR takes effect immediately.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Eddy_Em

ну, вон жи, на борде твоей гребенка, написано - jtag.

бери любой, например из http://openocd.org/doc/html/Debug-Adapter-Hardware.html

конпелятор есть бесплатный http://www.ti.com/tool/MSP430-GCC-OPENSOURCE, можно без code composer studio обойтись

aol ★★★★★
()
Ответ на: комментарий от tyakos

в бесплатном CCS ограничения по размеру компилируемого кода, если что.

хотя, я не исключаю, что слегка отстал от жизни.

aol ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.