Я пытаюсь создать правильный интерфейс ведомого 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, и я не знаю слишком много более быстрых процессоров, которые запустить либо очень маленькую надежную ОСРВ, либо запрограммировать ее на «голое железо» ...