Заголовок сообщения: RTC: установка даты и времени через HAL
Добавлено: Вт июл 19, 2022 05:31:48
Опытный кот
Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42 Сообщений: 744 Откуда: Караганда, Казахстан
Рейтинг сообщения:0
Коллеги, подскажите, плз... Никак не въеду в установку даты-времени через HAL. Ситуация элементарная: оставил я плату со своим STM32F407VET6 на полгода в покое, RTC работает от батарейки. Включаю, а часы отстали или убежали на несколько часов.
Через регистры, вроде-бы, все понятно, а вот через HAL что-то никак не въеду. Подкиньте, плз, последовательность вызовов HAL для установки даты и времени?
_________________ Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Заголовок сообщения: Re: RTC: установка даты и времени через HAL
Добавлено: Вт июл 19, 2022 11:12:31
Опытный кот
Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42 Сообщений: 744 Откуда: Караганда, Казахстан
Рейтинг сообщения:0
Да я уже тоже склоняюсь к тому, чтобы забить на эту гадость и сделать всё через регистры. Просто у меня большой проект собран из кубиков, там задействована FATFS от Чана, основное взаимодействие с периферией у меня и так через регистры, через кубики идёт только FATFS. А RTC так, между делом, есть оборудование на МК, почему бы его и не использовать. Только посмотрел я на эти кубические драйвера HAL и решил, что эту дрянь я себе в голову загружать не буду. В слабой надежде спросил, может кто это делал, а сам сегодня поразглядывал работу с RTC через регистры. В общем-то, ничего военного, просто я надеялся, что у кого-нибудь найдется готовое решение, которое можно будет скопипастить, и мне можно будет не вникать в подробности этого самого RTC. Получается, нет! Ладно, вникну...
_________________ Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
afz, так вроде FATFS требует от железа только процедуру чтения/отправки байта через SPI... И ее вполне на регистрах можно... А, в какой то версии еще FATFS хотел тик от таймера 100 раз в сек. Но там сервисные функции - их можно дергать и не строго 100 раз в сек.
Есть же компактные ФС для МК - специально, чтобы не было всякого излишества (скажем, зачем там права пользователя как в ext2?). Можно и вообще свое что-нибудь примитивное реализовать. Допустим, если файлы не нужно удалять, можно сделать последовательную запись, чем-то напоминающую структуру архива tar. Потом его просто при помощи dd к себе забрать и распаковать стандартными средствами.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Заголовок сообщения: Re: RTC: установка даты и времени через HAL
Добавлено: Ср июл 20, 2022 21:51:22
Опытный кот
Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42 Сообщений: 744 Откуда: Караганда, Казахстан
Рейтинг сообщения:0
Нет, коллеги, мне была нужна настоящая FAT32, чтобы можно было выдернуть uSD-шку из моего контроллера, сунуть ее в кардридер и работать с ней на PC, потом выдернуть из кардридера, сунуть в мой контроллер и продолжить работу на нем. Если нужны подробности, приведу ссылки, но думаю, что вас это не заинтересует.
А на тему моего вопроса, так я уже, практически, вник в работу с RTC через регистры, да и нашел, где подкрутить, чтобы кубики под ногами не путались, когда мне это не нужно. Не хотелось вникать, надеялся скопипастить, но, увы, пришлось таки вникнуть... Тогда еще один вопрос. Хочу задействовать USART1, пусть кубики его проинитят, но потом хочу перехватить у них управление и отработать опять же, через регистры. Напомните, плз, где там подключить свою программу прерываний - вроде-бы там было что-то, объявленное, как weak и туда можно подсунуть свою программулю. Кажется, у них это называется коллбэком...
Добавлено after 2 hours 42 minutes 19 seconds: Что-то я ничего не нашел внятного про кубические коллбэки. То есть, конечно, никто мне не мешает вписать в программу STM32F4xx_it.c между /* USER CODE BEGIN USART1_IRQn 0 */ и /* USER CODE END USART1_IRQn 0 */ вызов своей программы обработки прерываний, только вот это еще одно место правки сгенерированного кубического кода, что мне активно не нравится. То есть, конечно, именно этот исходник должен сохранить мои изменения при повторной генерации из кубиков, но перегенеришь что-то по-другому, так не забыть и здесь подправить...
_________________ Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Писать программу между USER CODE BEGIN USART1_IRQn 0 USER CODE END USART1_IRQn 0 должен мешать здравый смысл, т.к. в этот момент ядро контроллера будет находиться в обработчике прерывания, а он должен быть максимально коротким и минимально взаимодействовать с общей памятью (ну, кроме чтения - читать можно, но можно получить случайные данные).
Может вам дать код на регистрах? Для себя писал на кольцевом буфере (на чтение и запись), работа с DMA для приёма и передачи. Дополнительных сложностей не добавлял, типа snprintf(что-нибудь) - просто console_put(нуль-терминированная-строка) и дополнительные сущности типа _hex_word, _hex_byte, _int...
void DMA2_Stream7_IRQHandler(void) { // tty0 (отладочная консоль) if (DMA2->HISR & DMA_HISR_TCIF7) { DMA2->HIFCR = DMA_HIFCR_CTCIF7; // сброс флага события TCIF DMA_STATE &= ~DMA_tty0_TX_ACTIVE; tty0_ActivateDMA(); } else if (DMA2->HISR & DMA_HISR_HTIF7) { DMA2->HIFCR = DMA_HIFCR_CHTIF7; // сброс флага события HTIF } else if (DMA2->HISR & DMA_HISR_FEIF7) { DMA2->HIFCR = DMA_HIFCR_CFEIF7; // сброс флага события FEIF } else if (DMA2->HISR & DMA_HISR_DMEIF7) { DMA2->HIFCR = DMA_HIFCR_CDMEIF7; // сброс флага события DMEIF } else if (DMA2->HISR & DMA_HISR_TEIF7) { DMA2->HIFCR = DMA_HIFCR_CTEIF7; // сброс флага события TEIF }; }; void USART1_IRQHandler(void) { uint8_t tmp; while (USART1->SR & USART_SR_RXNE) { tmp = USART1->DR; if (DMA_STATE & DMA_tty0_thread_ready) { #ifdef USE_FREERTOS xQueueSendFromISR(Q_tty0, &tmp, 0); #endif } else { microrl_insert_char(prl, tmp); }; }; };
void tty0_ActivateDMA(void) { uint16_t CurrWrPos = tty0_WR_POS; uint16_t DataToSend; DataToSend = 0; if(!(DMA_STATE & DMA_tty0_TX_ACTIVE)) { DMA2_Stream7->CR &= ~DMA_SxCR_EN; // Отключаем поток DMA if (tty0_TX_POS != CurrWrPos) { // Если не совпадает - значит, данные есть. Или малый шанс на переполнение буфера. DMA2_Stream7->M0AR = (uint32_t)&(tty0_TX_BUF[tty0_TX_POS]); if (tty0_TX_POS < CurrWrPos) { // Нет перехода через конец буфера DataToSend = (CurrWrPos - tty0_TX_POS); tty0_TX_POS = CurrWrPos; } else { // Нужно сделать кольцо. DataToSend = (sizeof(tty0_TX_BUF) - tty0_TX_POS); tty0_TX_POS = 0; }; DMA2_Stream7->NDTR = DataToSend; DMA2_Stream7->FCR = 0; USART1->SR = ~(USART_SR_TC); // И только ПОСЛЕ этого включаем его. Да, странность. Но иначе он уходит в ошибку. DMA2_Stream7->CR |= DMA_SxCR_EN; DMA_STATE |= DMA_tty0_TX_ACTIVE; }; }; // Если активен - сработает при вызове события завершения обмена. };
Собственно, любой вывод текста отправляется в console_put(), который занимается рутиной, копируя строку из входа в кольцевой буфер. После этого пинается DMA контроллер, который перебрасывает данные в USART1. Если данные закончились - производится новая попытка запустить DMA, перепроверив указатели на буфер. Если совпадают - все данные были отправлены (или буфер был переполнен идеально полностью) и запускать не нужно. Если нужно - указатели соответствующим образом обновляются (указатель, который принадлежит DMA, а не функции!).
Получение байтов - посимвольное. Где-то в другом проекте принимал по DMA, но переписывать, чтобы заработало, немного лень.
Заголовок сообщения: Re: RTC: установка даты и времени через HAL
Добавлено: Пт июл 22, 2022 19:25:04
Опытный кот
Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42 Сообщений: 744 Откуда: Караганда, Казахстан
Рейтинг сообщения:0
AlanDrakes, вообще-то, не так всё плохо. Точнее, многое зависит от кучи всяких факторов, но, если нет каких-то параллельных скоростных процессов, то, грамотно используя прерывания, все проблемы легко обходятся. Что действительно нельзя делать - это ждать чего-то в этом обработчике, а так - времени от одного до другого прерывания по TXE - 14.5 тыс тактов при работе на168 мГц и скорости USART'а 115200. И я с трудом представляю, чего туда такого можно насочинять, что бы потребовало больше 1000 тактов.
Естественно, все программы, работающие в прерываниях, должны быть быстрыми. То есть взяли что-то из регистров, поместили что-то в регистры, где-то отметились, и на выход. А ожидания будут в основном цикле, который while(1).
А без DMA не обойтись только тогда, когда нужно что-то скоростное и/или с минимально возможным джиттером.
_________________ Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 26
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения