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

Captain

Участник
  • Постов

    11
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Посетители профиля

657 просмотров профиля
  1. Ан нет, все работает. Проблема была неправильной фазе SCK (бит CKSTR должен быть 1), тогда отсчеты с микрофона правильные.
  2. STM32F746 discovery МЭМС микрофоны

    Добрый день. Возможно, вопрос не совсем по ARM, я пытаюсь получить звук с мэмс микрофонов на плате stm32f746-discovery. Для быстрой проверки настроил SAI2A как output master, SAI2B - slave in и запустил два канала DMA dma_in -> память -> dma_out. После инициализации wm8994_Init(0x34, OUTPUT_DEVICE_HEADPHONE | INPUT_DEVICE_DIGITAL_MICROPHONE_2, 50, AUDIO_FREQUENCY_48K) - в наушниках скрежет и свист. Насколько я понял, драйвер настраивается так, чтобы отправлять необработанные PDM отсчеты в цифровой интерфейс. Я видимо слепой, но не могу найти - какие регистры нужно настраивать, чтобы демодулировать сигнал?
  3. Rigol DS2072

    Чет погорячился с ценой.. Отдам за 35000.
  4. Rigol DS2072

    Продаю в Мск. цифровой осциллограф Rigol DS2072 (https://www.batronix.com/shop/oscilloscopes/Rigol-DS2072.html). Разблокирован. 42000р. Торг.
  5. STM32F746 SAI

    Благодарю, рабочий пример будет полезен. А моя проблема была в неправильном назначении альтернативной функции портов (из чего делаю вывод, что fifo sai тактируется непосредственно с пина).
  6. Похоже, что так и придется сделать. А эзернет я вроде раскурил, там тоже плохо с документацией, но он по крайней мере работает. Прерывания, кстати, тоже работают, но тут может быть дело в ревизии МК. Там с прерываниями другая проблема - пока мк в обработчике прерывания - приходят новые кадры и заново прерывание само собой не срабатывает.
  7. Да, нашел эти примеры. Там ДМА работает с УАРТом, но не суть. Проблема в том, что написано РОВНО то же самое, что и у меня... прямо строка в строку. Я сейчас даже порядок инициализации такой же как там сделал.
  8. Вот дошли руки до ДМА и что-то второй день ни в какую не могу заставить это работать. Кое-как из того, что написано в документации (а написано, надо сказать коряво) родил такой код: static dmaCtrlData_t dmaCtrlData[16] __attribute__((aligned(512), section("ahb_lite"))); volatile char tmp1[] = "DMA test string."; volatile char tmp2[20]; int main(void) { ... инициализация клоков ... memset(dmaCtrlData, 0x0, sizeof(dmaCtrlData)); // Reset to the initial state. MDR_DMA->CTRL_BASE_PTR = (uint32_t) dmaCtrlData; MDR_DMA->CFG = 1U; MDR_DMA->CHNL_SW_REQUEST = 0U; MDR_DMA->CHNL_PRI_ALT_CLR = 0xFFFFFFFF; MDR_DMA->CHNL_PRIORITY_CLR = 0xFFFFFFFF; MDR_DMA->CHNL_REQ_MASK_SET = 0xFFFFFFFF; MDR_DMA->CHNL_USEBURST_CLR = 0xFFFFFFFF; MDR_DMA->CHNL_ENABLE_CLR = 0xFFFFFFFF; MDR_DMA->ERR_CLR = 1U; // Configure DMA_CH0 dmaCtrlData[0].dmaSrcEndAddr = (uint32_t) tmp1 + sizeof(tmp1) - 1; dmaCtrlData[0].dmaDstEndAddr = (uint32_t) tmp2 + sizeof(tmp1) - 1; dmaCtrlData[0].dmaControl = (0x00 << 30) | // One byte destination increment; (0x00 << 28) | // Destination transfer unit size; (0x00 << 26) | // One byte source increment; (0x00 << 24) | // Source transfer unit size; (0U << 21) | // dst_prot_ctrl (whatever this is - let it be 0); (0U << 18) | // src_prot_ctrl; (15U << 14) | // Acquire the bus and do not release until the transfer complete; ((sizeof(tmp1) - 1) << 4) | // Transfers count - 1. (0U << 3) | // next_useburst ?? (1U << 0); // Simple request mode. Auto-request mode does not work either. MDR_DMA->CHNL_REQ_MASK_CLR = 1U; MDR_DMA->CHNL_ENABLE_SET = 1U; MDR_DMA->CHNL_SW_REQUEST = 1U; ... зацикливаемся ... } Здесь пытаюсь скопировать строку из tmp1 в tmp2. Собственно для проверки, что все заполнилось правильно: 1. Значения регистров MDR_DMA и dmaCtrlData для 1 канала ДО запуска передачи (MDR_DMA->CHNL_SW_REQUEST = 1U): { STATUS = 0x101f0001, CFG = 0x0, CTRL_BASE_PTR = 0x20100000, ALT_CTRL_BASE_PTR = 0x20100200, WAITONREQ_STATUS = 0x7fffffff, CHNL_SW_REQUEST = 0x0, CHNL_USEBURST_SET = 0x0, CHNL_USEBURST_CLR = 0x0, CHNL_REQ_MASK_SET = 0xfffffffe, CHNL_REQ_MASK_CLR = 0xfffffffe, CHNL_ENABLE_SET = 0x1, CHNL_ENABLE_CLR = 0x1, CHNL_PRI_ALT_SET = 0x0, CHNL_PRI_ALT_CLR = 0x0, CHNL_PRIORITY_SET = 0x0, CHNL_PRIORITY_CLR = 0x0, RESERVED0 = {0x0, 0x0, 0x0}, ERR_CLR = 0x0 } { dmaSrcEndAddr = 0x20000614, dmaDstEndAddr = 0x20005588, dmaControl = 0x3c101, dmaUnused = 0x0 } 2. И ПОСЛЕ: { STATUS = 0x101f0001, CFG = 0x0, CTRL_BASE_PTR = 0x20100000, ALT_CTRL_BASE_PTR = 0x20100200, WAITONREQ_STATUS = 0x7fffffff, CHNL_SW_REQUEST = 0x0, CHNL_USEBURST_SET = 0x0, CHNL_USEBURST_CLR = 0x0, CHNL_REQ_MASK_SET = 0xfffffffe, CHNL_REQ_MASK_CLR = 0xfffffffe, CHNL_ENABLE_SET = 0x0, CHNL_ENABLE_CLR = 0x0, CHNL_PRI_ALT_SET = 0x0, CHNL_PRI_ALT_CLR = 0x0, CHNL_PRIORITY_SET = 0x0, CHNL_PRIORITY_CLR = 0x0, RESERVED0 = {0x0, 0x0, 0x0}, ERR_CLR = 0x0 } { dmaSrcEndAddr = 0x20000614, dmaDstEndAddr = 0x20005588, dmaControl = 0x3c000, dmaUnused = 0x0 } И казалось бы ДМА отработал (dmaControl перешел в режим "Стоп" и счетчик обнулился, а также сбросился Enable на первом канале)... но фиг там, содержимое tmp2 - как были нули так и остались. Для проверки - адреса: (volatile char (*)[17]) 0x20000604 <tmp1> (volatile char (*)[20]) 0x20005578 <tmp2> (dmaCtrlData_t (*)[16]) 0x20100000 <dmaCtrlData> Что я забыл/не учел? :bb-offtopic: Из так называемого даташита - не смог понять что за передачи с кэшированием/буферизацией и как это использовать. Аналогично - не понятно в чем разница между режимами "Основной" и "Авто-запрос".
  9. Да я по сути ни с чем еще и не работал на нем. Был приказ импортозамещать - вот и развлекаюсь :rolleyes: . Сейчас портирую драйвера для ChibiOS HAL (ибо вся прикладуха под ней), но до spi пока не добрался. Но Вы спрашивайте - хотя бы будет ясно какими граблями по лбу получать.
  10. Спасибо за ответы. Могу, конечно ошибаться, но volatile не имеет смысла при -O0. Как водится, только написал пост - и сразу нашел проблему - прерывания были просто замаскированы. Установил PRIMASK =0 и все завертелось.
  11. Всех приветствую. Работал ли кто с Миландрами? Никак не могу настроить прерывания от таймера (ни одного). Код такой: int cnt1, cnt2, cnt3; /* * Прерывание таймера 1 (14) * Смещение в таблице векторов 0x40 + 14 * 4 = 0x78 */ void Vector78(void) { cnt1 += 1; MDR_TIMER1->STATUS = (uint32_t) 0; } /* * Прерывание таймера 2 (15) * Смещение в таблице векторов 0x40 + 15 * 4 = 0x7C */ void Vector7C(void) { cnt2 += 1; MDR_TIMER2->STATUS = (uint32_t) 0; } /* * Прерывание таймера 3 (16) * Смещение в таблице векторов 0x40 + 16 * 4 = 0x80 */ void Vector80(void) { cnt3 += 1; MDR_TIMER3->STATUS = (uint32_t) 0; } int main(void) { int cnt4 = 0; cnt1 = cnt2 = cnt3 = 0; ... Код включения тактирования ядра и таймеров в другом модуле ... MDR_TIMER1->CNTRL = (uint32_t) 0; MDR_TIMER1->CNT = (uint32_t) 0; MDR_TIMER1->PSG = (uint32_t) 0; MDR_TIMER1->ARR = (uint32_t) 4095; MDR_TIMER1->IE = TIMER_IE_CNT_ARR_EVENT_IE | TIMER_IE_CNT_ZERO_EVENT_IE; MDR_TIMER1->STATUS = (uint32_t) 0; MDR_TIMER1->CNTRL = (uint32_t) 1; MDR_TIMER3->CNTRL = (uint32_t) 0; MDR_TIMER3->CNT = (uint32_t) 0; MDR_TIMER3->PSG = (uint32_t) 0; MDR_TIMER3->ARR = (uint32_t) 4095; MDR_TIMER3->IE = TIMER_IE_CNT_ARR_EVENT_IE | TIMER_IE_CNT_ZERO_EVENT_IE; MDR_TIMER3->STATUS = (uint32_t) 0; MDR_TIMER3->CNTRL = (uint32_t) 1; MDR_TIMER2->CNTRL = (uint32_t) 0; MDR_TIMER2->CNT = (uint32_t) 0; MDR_TIMER2->PSG = (uint32_t) 0; MDR_TIMER2->ARR = (uint32_t) 4095; MDR_TIMER2->IE = TIMER_IE_CNT_ARR_EVENT_IE | TIMER_IE_CNT_ZERO_EVENT_IE; MDR_TIMER2->STATUS = (uint32_t) 0; MDR_TIMER2->CNTRL = (uint32_t) 1; NVIC_EnableIRQ(TIMER1_IRQn); NVIC_EnableIRQ(TIMER2_IRQn); NVIC_EnableIRQ(TIMER3_IRQn); while (true) { cnt4 += 1; } } Смотрю по GDB - МК в прерывания не заходит, счетчики cnt1..3 не инкриментируются ни разу. Что уже проверял: 1. Все таймеры точно затактировались и считают: (gdb) p *0x40070000 // Регистр TIMER1->CNT $82 = 3285 $83 = 1406 $84 = 2573 $85 = 1891 2. Вектора в таблице правильные: (gdb) p Vector78 $86 = {void (void)} 0x300 <Vector78> (gdb) p *0x00000078 $87 = 769 // 0x300 == (769 & 1) 3. Флаги статуса прерываний подняты: (gdb) p *0x40070058 // Регистр TIMER1->IE $88 = 3 // Прерывания по 0 и по ARR разрешены (gdb) p *0x40070054 // Регистр TIMER1->STATUS $89 = 3 // Оба события 4. В NVIC прерывания разрешены: (gdb) p *0xE000E100 $90 = 114688 // Биты 14,15,16 5. Всяко пробовал таскать строку включения прерывания таймера (до включения счетчика и после). Безрезультатно. 6. Что я упускаю?
×
×
  • Создать...