STM32F767ZI Обработка внешних прерываний - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь создать правильный интерфейс ведомого SPI для ADC AD7768-4. АЦП имеет интерфейс SPI, но не выводит преобразования через SPI. Вместо этого есть выходные данные, которые синхронизируются на отдельных выводах GPIO. Поэтому мне в основном нужно разбивать данные на биты и выводить их в SPI, чтобы получить правильный интерфейс подчиненного SPI. Пожалуйста, не спрашивайте, почему я так делаю, это было поручено мне.

У меня проблема с прерываниями. Я использую процессор STM32F767ZI - он работает на частоте 216 МГц, и мои данные АЦП ДОЛЖНЫ БЫТЬ синхронизированы на частоте 20 МГц. Я настроил свои NMI, но я не вижу, когда система вызывает или указывает на обработчик прерываний.

Я использовал программное обеспечение STMCubeMX для назначения выводов и генерации установочного кода, и в файле stm32F7xx.c он показывает функцию NMI_Handler(), но я не вижу указателя на него где-либо в системных файлах. Я также нашел функцию void HAL_GPIO_EXTI_IRQHandler() в STM32F7xx_hal_gpio.c, которая, кажется, проверяет, установлен ли вывод, и очищает все ожидающие биты, но не сбрасывает флаг прерывания и не проверяет его, и опять же, я не вижу указателя к этой функции.

Чтобы еще более усложнить ситуацию, у меня есть 10 тактов, чтобы определить, какой флаг установлен (1 из двух за раз), сбросить его, задать переменную и переместить данные из регистров GPIO. Я считаю, что это возможно, но опять же, я не уверен в том, что делает система, как только прерывание отключается.

Есть ли у кого-нибудь опыт работы с внешними прерываниями на этом процессоре, который мог бы пролить свет на то, как эта конкретная система обрабатывает вещи? Опять же - 10 тактов, чтобы сделать то, что мне нужно ... для перемещения данных у меня уйдет всего 1-2 такта, а у меня 8 для обработки прерываний ...

EDIT:

Мы изменили частоту DCLK на 5,12 МГц (20,48 МГц MCLK / 4), потому что на 2,56 МГц у нас было ровно 12,5 микросекунд для передачи данных и настройки для следующего импульса DRDY, а скорость 80 кГц дает нам ровно нулевой запас. На частоте 5,12 МГц у меня есть 41 такт для запуска процедуры прерывания, которую я могу немного уменьшить, если пропущу проверку второго флага и просто обработаю входящие данные. Но я чувствую, что должен хотя бы использовать проверку флага DRDY и использовать процедуру для включения второго прерывания, иначе я буду постоянно прерывать, потому что DCLK на АЦП всегда работает. Это позволяет мне 6,12 микросекунды читать данные и 6,25 микросекунды вытаскивать их перед следующим импульсом DRDY. Я должен быть в состоянии сделать это на частоте SPI 32 МГц (ведомый), но, скорее всего, будет делать это на частоте 50 МГц. Это мой текущий код прерывания:

void NMI_Handler(void)
{
    if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)         
     {
         count = 0;                                             
         __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);                  
         HAL_GPIO_EXTI_Callback(GPIO_PIN_0);                        
         //     __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);             

         HAL_NVIC_EnableIRQ(GPIO_PIN_1);                            
     }  
    else
  {  
        if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1) != RESET)         
          {
             data_pad[count] = GPIOF->IDR;                      
             count++;                                           
             if (count == 31)
              {
                data_send = !data_send;                     
                HAL_NVIC_DisableIRQ(GPIO_PIN_1);            
              }
        __  HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);         
        HAL_GPIO_EXTI_Callback(GPIO_PIN_1); 
//      __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0); 
          }
   }
}  

Я по-прежнему обеспокоен тактовыми циклами, и я полагаю, что смогу обойтись только проверкой флага DRDY, если буду работать, предполагая, что единственный другой флаг EXTI, который сработает, относится к такту. Хотя я спрашиваю, как это будет работать, если SYS_TICK работает в фоновом режиме ... Я должен выяснить.

Мы исследуем более быстрый процессор для обработки битов, но сейчас похоже, что PI3 не сможет справиться с этим, если он работает под управлением Linux, и я не знаю слишком много более быстрых процессоров, которые запустить либо очень маленькую надежную ОСРВ, либо запрограммировать ее на «голое железо» ...

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

10 тактов, чтобы сделать то, что мне нужно ... для перемещения данных у меня уйдет всего 1-2 такта, а у меня 8 для обработки прерываний ...

Ни за что,Ввод прерывания (проталкивание регистров, выборка вектора и заполнение конвейера) занимает 10-12 циклов даже на Cortex-M7.Затем рассмотрим очень простой обработчик прерываний, просто переместив биты входных данных в буфер и очистив флаг прерывания:

uint32_t *p;
void handler(void) {
    *p++ = GPIOA->IDR;
    EXTI->PR = 0x10;
}

он переводится в нечто вроде этого

handler:
    ldr     r0, .addr_of_idr // load &GPIOA->IDR
    ldr     r1, [r0]         // load GPIOA->IDR
    ldr     r2, .addr_ofr_p  // load &p
    ldr     r3, [r2]         // load p
    str     r1, [r3]         // store the value from IDR to *p
    adds    r3, r3, #4       // increment p
    str     r3, [r2]         // store p
    ldr     r0, .addr_of_pr  // load &EXTI->PR
    movs    r1, #0x10
    str     r1, [r0]         // store 0x10 to EXTI->PR
    bx      lr
.addr_of_p:
    .word   p
.addr_of_idr
    .word   0x40020010
.addr_of_pr
    .word   0x40013C14

Так что это11 инструкций, каждая из которых занимает хотя бы один цикл, после ввода прерывания.Это при условии, что код, векторная таблица и стек находятся в самой быстрой области ОЗУ.Я не уверен, работают ли буквальные пулы в ITCM вообще, использование непосредственных литералов добавило бы еще 3 цикла.Забудьте об этом.

Это необходимо решить с помощью аппаратного обеспечения.

Контроллер имеет 6 интерфейсов SPI, выберите 4 из них.Подключите DRDY ко всем четырем NSS контактам, DCLK ко всем SCK контактам и каждому DOUT выводу к одному MISO выводу.Теперь каждый интерфейс SPI обрабатывает один канал и может собирать до 32 бит в своем внутреннем FIFO.

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

EDIT

Оказывается, что SPM STM32 требует чрезмерного количествазадержки между NSS падением и SCK повышением, что не обеспечивает AD7768, поэтому он не будет работать.

Sigma-Delta интерфейс

STM32F767 имеет DFSDM-периферию, разработаннуюполучать данные от внешних АЦП.Он может принимать до 8 каналов последовательных данных с частотой 20 МГц и даже может выполнять некоторую предварительную обработку, которая может понадобиться вашему приложению.

Проблема в том, что DFSDM не имеет DRDY ввода, я неточно знать, как можно синхронизировать передачу данных.Это может сработать, установив сигнал START# для сброса связи.

Если это не сработает, вы можете попробовать запустить каналы DFSDM, используя таймер и DMA.Подключите DRDY к внешнему триггеру TIM1 или TIM8 (другие таймеры не будут работать, потому что они подключены к более медленной шине APB1 и другому контроллеру DMA), запустите его на переднем фронте ETRи пусть он генерирует запрос DMA через ~ 20 нс.Затем позвольте DMA записать значение, необходимое для запуска канала, в регистр конфигурации канала DFSDM.Повторите для трех других каналов.

0 голосов
/ 16 ноября 2018

Я внимательно прочитал AD7768 DS и обнаружил, что он может передавать данные четырех каналов на один вывод DOUT.Итак, я снова говорю о последовательном аудиоинтерфейсе (SAI).

Если вы можете понизить частоту DCLK до 2,5 МГц, чем вы можете снизить частоту с соотношением 1: 8 (как отношение 2,5 МГц к 20МГц) частота выборки irt при полной частоте АЦП.

Если вы направите все 4 канала на один выход DOUT0, вы уменьшите частоту дискретизации только в соотношении 1: 4.

AD7768-4DS

стр. 53

В AD7768 интерфейс может быть настроен для вывода данных преобразования на один, два или восемь выводов DOUTx.Конфигурация DOUTx для AD7768 выбирается с помощью выводов FORMATx (см. Таблицу 33).

стр. 66 таблица 34: (для AD7768-4) стр. 67 рисунок 98:

FORMAT0 = 1 Все каналы выводятся на вывод DOUT0, на выход TDM.Используется только DOUT0.

Вы можете использовать SAI с FS = DRDY и четырьмя слотами, 32 бита / слот

0 голосов
/ 14 ноября 2018

Есть файл запуска, сгенерированный перед компиляцией: startup_stm32f767xx.s - который содержит все указатели на функции.

Под маркером g_pfnVectors: указано .word NMI_Handler, указывающее на функцию для обработки немаскированных прерываний и два других указателя, .word EXTI0_IRQHandler и .word EXTI1_IRQHandler в качестве векторов для внешних обработчиков прерываний.Далее в том же файле находятся следующие директивы компилятора:

.weak      NMI_Handler  
.thumb_set NMI_Handler,Default_Handler

.weak      EXTI0_IRQHandler         
.thumb_set EXTI0_IRQHandler,Default_Handler

.weak      EXTI1_IRQHandler         
.thumb_set EXTI1_IRQHandler,Default_Handler  

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

...