Jan. 7th, 2023

eddy_em: (Default)
Портировал и USART'овский сниппет на G0. Повозился с DMAMUX: там жесть, сколько всяких регистров, но оказалось, что для обычного применения все совершенно просто. Жаль, в интернете вообще 0 примеров. Теперь хоть один будет.
Китайцы на девборде (кстати, схемы ее я так и не нашел, на али все поголовно дают схему с девборды на F407, но там совсем другое подключение — пришлось прозванивать) почему-то вывели на отдельный разъем не USART1, как это обычно делается, а USART3. Я аж три раза прозвонил и с даташитом сверился — так и есть.
Сделал через DMA не только передачу, но и прием (не знаю, почему раньше я этого не делал): о конце строки МК узнает в прерывании character match. А если вдруг возникло прерывание DMA transfer complete, то проверяю: если последний символ - не '\n' (у усартовского прерывания приоритет ниже получается), то выставляю флаг overflow и сбрасываю буфер. При чтении передается флаг, показывающий, не было ли в прошлый раз переполнения буфера (в этом случае все данные вплоть до первой встреченной '\n' выбрасываются). Трижды ловил себя на том, что, скопипастив строчку с настройкой определенного регистра DMA Tx, я не поменял номер на канал для Rx.
Кстати, вот еще на что наткнулся (на радиокоте указали ошибку): почему-то ST'шные разработчики каналы DMA нумеруют с 1, а каналы DMAMUX — с 0. И приходится писать:
// set up DMA channels: 2 - Tx, 3 - Rx
    // Tx channel: mem++, mem->periph, 8bit, compl.&err. irq
    DMA1_Channel2->CCR = DMATXCCR;
    DMA1_Channel2->CPAR = (uint32_t) &USART3->TDR; // peripherial address
    // Rx channel: mem++, periph->mem, 8bit, compl.&err. irq
    DMA1_Channel3->CCR = DMARXCCR;
    DMA1_Channel3->CPAR = (uint32_t) &USART3->RDR; // peripherial address
    DMA1_Channel3->CNDTR = UARTBUFSZ;
    DMA1_Channel3->CMAR = (uint32_t)&rbuf[rbufno];
    // set up DMAMUX channels: 55 - USART3_TX, 54 - USART3_RX
    // enumeration of DMAMUX starts from 0 (DMA - from 1)!
    DMAMUX1_Channel1->CCR = 55;
    DMAMUX1_Channel2->CCR = 54;
eddy_em: (Default)
Добавил и I2C. В простейшем случае (без DMA) все решилось элементарным переносом с F0. Дольше провозился, разгребая все по разным файлам и переделывая proto.c.
Проверял на недавно купленном датчике SHT30 (у старых я всех подтяжки поотпаивал, чтобы к "апельсинке" присоединить, а новых аж 4 разных, но у остальных трех нужно гребенки паять — лень). Правда, у SHT30 зачем-то регистры 16-битные сделали (хоть там тех регистров и на 4 бита за глаза), так что пришлось еще добавить возможность чтения регистров с 16-битными адресами. Статусные регистры показывает, грелку включает/выключает, в однократном или непрерывном режиме температуру и влажность показывает. Температура плавает в районе ±0.05℃, влажность — в районе ±2%. По-хорошему, конечно, надо будет всю эту кучу датчиков потом в эдакий термостат засунуть, да посмотреть по калиброванному термометру, насколько врут. Еще бы чем-нибудь их показания влажности измерить… Ах, да: врет он по температуре безобразно: кажет аж 26℃ в квартире (все китайские домашние термометры 24 показывают). Если менять параметр "repeatability" (точность, видать), вообще ничего не меняется. Хотя точность обещали ±0.3℃, ну, обещанного три года ждут (а уж с китайскими датчиками, похоже, все очень плохо).
Завтра в 8 утра на работу вставать, надо долго не засиживаться, но чуть-чуть хочется еще потыкать палочкой возможность запуска I2C через DMA.

April 2025

S M T W T F S
  1 23 45
67 89101112
13141516171819
20212223242526
27282930   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 22nd, 2025 07:24 am
Powered by Dreamwidth Studios