Jump to content

    

Алексей ВМ

Участник
  • Content Count

    125
  • Joined

  • Last visited

Everything posted by Алексей ВМ


  1. Добрый день, Необходимо запускать все функции из SRAM, так как надо перезаписать флешь с кодом. Проблема в том, что функция, вызываемая из SRAM, обращается к служебным функциям, сидящим во флеше. Как перенести все функции в SRAM?
  2. CC2541 (8051MCU) перенести библиотечные функции в ОЗУ

    Это макросы. Насколько я понял, служебные функции вызываются при использовании параметров в вызове функции. Если тело функции HalFlashWriteRAM() использовать в функции UpdateFirmware(), то все работает отлично.
  3. CC2541 (8051MCU) перенести библиотечные функции в ОЗУ

    Это и есть отдельная программа. Она копируется из ROM в SRAM и оттуда запускается, но при этом происходит обращение к служебным функциям, например LCALL ?BANKED_ENTER_XDATA, которые находятся во флеше. #pragma default_function_attributes = @ "RAMCODE" void UpdateFirmware(void) { buf[0] = 0xBE; buf[1] = 0xEF; buf[2] = 0xDE; buf[3] = 0xAD; HalFlashWriteRAM(TEST_ADDR, buf, 1); LED_ON for(;;); } void HalFlashWriteRAM(uint16 addr, uint8 *buf, uint16 cnt) { halDMADesc_t *ch = HAL_NV_DMA_GET_DESC(); HAL_DMA_SET_SOURCE(ch, buf); HAL_DMA_SET_DEST(ch, &FWDATA); HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_USE_LEN); HAL_DMA_SET_LEN(ch, (cnt * HAL_FLASH_WORD_SIZE)); HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE); HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE); HAL_DMA_SET_TRIG_SRC(ch, HAL_DMA_TRIG_FLASH); HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1); HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0); // The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_DISABLE); HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS); HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH); HAL_DMA_CLEAR_IRQ(HAL_NV_DMA_CH); HAL_DMA_ARM_CH(HAL_NV_DMA_CH); FADDRL = (uint8)addr; FADDRH = (uint8)(addr >> 8); FCTL |= 0x02; // Trigger the DMA writes. while (FCTL & 0x80); // Wait until writing is done. //LED_ON //for(;;); } #pragma default_function_attributes = Например, вызов функции HalFlashWriteRAM(TEST_ADDR, buf, 1); порождает вызов LCALL ?BANKED_ENTER_XDATA
  4. CC2541 (8051 MCU) - перепрошить 0-й банк

    Добрый день! Имеется СС2541, в нем живут три проги - BIM, ImageA и ImageB. BIM находится в 0-м банке. Там же располагаются части ImageA и ImageB, которые должны находиться в root bank - INTVEC, NEAR_CODE, BANK_RELAYS и тп. ImageA грузит по BLE и шьет ImageB. Задача - перепрошить с помощью ImageB все три проги. Решение - ImageA грузит по BLE и шьет ImageBL, ImageBL все перепрошивает. Все бы ничего, но непонятно, как перепрошивать 0-й банк, в котором находятся INTVEC, NEAR_CODE, а особенно BANK_RELAYS, загрузчиком из другого банка?
  5. CC2541 (8051 MCU) - перепрошить 0-й банк

    Программатор не поможет)). Доступ к СС2541 только по BLE. Внутри СС2541 прошиты BIM, ImageA и ImageB. Перепрошивать может только ImageA. Задача - заменить и BIM, и ImageA, и ImageB.
  6. CC2541 (8051 MCU) - перепрошить 0-й банк

    Да, надо переписать в том числе и BIM. Вообще весь банк 0 обновить с помощью кода, который располагается в 3-м банке.
  7. Добрый день. STM32F4, DMA непрерывно (двойной буфер) по таймеру выдает данные на пины. Периодически надо менять период таймера (минимум - 50 нс, максимум - 500), это делается в обработчике прерывания DMA. Прерывание настроено на окончание передачи буфера. Проблема в том, что когда прога доходит до изменения периода таймера, идет новый цикл выдачи данных, то есть от момента выставления флага ТС до работы обработчика прерывания проходит достаточно большое время - сотни нс. Как уменьшить время от момента выставления флага ТС до входа в обработчик?
  8. TCIF сбрасываю. Если не сбрасывать, будет заходить в обработчик снова и снова по первой записи. Другие флаги не выставляются, то есть ошибок записи тоже нет.
  9. Вообще один раз, больше не возникает, запись в регистры ARR и RCR (через DMAR) перед этим прерыванием производится правильно. СС1 шлепают нормально, данные выводятся, UIF выставляется, но записи в регистры ARR и RCR не производится, прерывания от выполнения этой записи не возникает.
  10. Реализовал выдачу данных по событию capture/compare event. Прерывание ТС записи DMA по update event возникает только один раз, прерывание ТС записи DMA по capture/compare event генерируются нормально. Регистры CCR1 = 0, ARR и RCR содержат правильные значения. Как я понимаю update event возникает только один раз. В чем может быть причина?
  11. Немного модифицированное предложение ув. SSerge Пины дергать не по update event, а по capture/compare event. Соответственно, update event возникает при окончании передачи всего пакета (68 импульсов), по нему производится DMA запись регистра ARR новым значение периода. Два обработчика прерываний - один старый для формирования буфера передачи, новый для изменения периода таймера.
  12. В проекте присутствует обработка довольно большого объема данных, прерывание с такой обработкой будет занимать довольно значительное время... Немного не ясно с RCR: Each time the REP_CNT related downcounter reaches zero, an update event is generated Это какой-то особый update event, или он заведен на TIM1_UP? Дальше по тексту упоминается repetition update event U_RC: As REP_CNT is reloaded with REP value only at the repetition update event U_RC, any write to the TIMx_RCR register is not taken in account until the next repetition update event. но кроме этого отрывка нигде не находится поиском.
  13. Если удастся менять период таймера аппаратно, то задержки до единиц мкс до входа в обработчик прерывания ни на что не влияют. За FPU благодарю, постараюсь избавиться от него.
  14. Уже работает. Но заказчик решил изменить возможности, отсюда все эти пляски с бубном...
  15. Частота 168 МГц . XMC4700 мы с Вами уже обсуждали в другой ветке. Если девайс будет развиваться, естественно, аппаратная часть будет изменена.
  16. Перерыв в несколько десятков или даже сотен мкс не критичен, главное, чтобы он был не чаще одного раза в неск сотен мс. Потери данных, я понимаю, не произойдет? Не вариант, заказчик за каждый цент удавится
  17. Точность +- 10 нс для наименьшего периода 50 нс, меньше не нужна. По сути, это параллельная шина с 10 сигналами, один из которых клок. ШИМ, к сожалению, здесь не прокатит... Платы уже вовсю клепают...
  18. По мелочи если только. Протокол в части добавления новых команд, но объем обмена данными небольшой. Основной функционал - выдача на пины сигналов. Есть ещё редкое- раз в неск секунд - чтение данных из SPI памяти и обработка этих данных, но логика обработки относительно простая.
  19. Есть ещё обмен по уарту, и больше никаких прерываний. По сути, да, STM большую часть времени используется как ПЛИС.
  20. Это DMA с двойным буфером. Грузи данные раз в несколько мкс и все.
  21. Нет, минимальный период таймера 50 нс, период клока на пине - 100 нс - это 10 МГц. STM32F4 вполне справляется. Затык с переинициализацией таймера на ходу.
  22. Я наверно как-то коряво объясняю свою проблему. Надо выводить на пины порта сигналы пачками разной длительности. В пачке 68 импульсов одинаковой длительности - клоки и дата, всего 10 сигналов, соответственно размер буферов DMA 68 слов. Период импульса формируется таймером, по которому с помощью DMA и выдаются данные на пины. Сущестует 4 периода импульса - 50 нс, 120 нс, 250 нс и 500 нс, то есть сначала выдаем пачку импульсов с периодом 50 нс, затем 120, 250, 500, затем опять 50. Умножаем на 68 - получаем, что прерывания от DMA (TC) возникают, в зависимости от периода таймера, через 3.4 мкс, 8 мкс, 17 мкс и 34 мкс. Сейчас я меняю период таймера в обработчике прерывания DMA, в котором, помимо этого, формируется теневой буфер данных для отправки, всё это занимает порядка 2 мкс. Проблема в том, что когда я захожу в обработчик прерывания DMA, чтобы изменить период таймера, он уже выдает новую пачку данных с предыдущим периодом из-за латентности входа в обработчик. Тоже самое описано в стартовом посте, чуть лаконичнее. Что мне нужно - таймер отсчитал 68 раз с заданным периодом, и только после этого необходимо записать в него другое значение периода, лучше аппаратно. Advanced-control timers вроде как позволяют это сделать, у них есть RCR. Или можно на update event таймера повесить запись по DMA нового периода? Тогда все равно есть непонятные моменты Сейчас у меня для дерганья пинов используется DMA2 request Channel 6 Stream 5 - TIM1_UP. По есть по событию update TIM1 каждые 50, 120, 250 или 500 нс на порт выдается новая порция данных. Как сюда ещё вкрячить изменения периода?
  23. Точно, спасибо за наводку.
  24. Прошу прощения, если я неполно описал проблему. Заказчик на ходу изменил требования, приходится изворачиваться... Время между прерываниями - 68 циклов таймера, мин период таймера- 50 нс, получается 3.4 мкс. Вся обработка прерывания занимает 2 мкс. Приоритет у прерывания DMA наивысший. Спасибо! Именно это я и хотел услышать - менять параметры таймера не в обработчике прерывания DMA, а по другому событию и в другом месте. Только немного непонятно - у меня таймер используется под DMA. О каком update event идет речь? Или имеется в виду, что можно использовать прерывания от этого же таймера? Так не получится, так как мне надо не каждое событие таймера использовать, а каждое 68. Значений периода больше, к сожалению... Кроме того, если мы разбили все интервалы на 50 нс, от и менять ничего не надо. Пусть себе шлепает с постоянной частотой...